Class: Gratan::Driver

Inherits:
Object
  • Object
show all
Includes:
Logger::Helper
Defined in:
lib/gratan/driver.rb

Constant Summary collapse

ER_NO_SUCH_TABLE =
1146

Instance Method Summary collapse

Methods included from Logger::Helper

#log

Constructor Details

#initialize(client, options = {}) ⇒ Driver

Returns a new instance of Driver.



6
7
8
9
# File 'lib/gratan/driver.rb', line 6

def initialize(client, options = {})
  @client = client
  @options = options
end

Instance Method Details

#create_user(user, host, options = {}) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/gratan/driver.rb', line 64

def create_user(user, host, options = {})
  objects = options[:objects]
  grant_options = options[:options]
  granted = false

  objects.each do |object_or_regexp, object_options|
    expand_object(object_or_regexp).each do |object|
      grant(user, host, object, grant_options.merge(object_options))
      granted = true
    end
  end

  unless granted
    log(:warn, "there was no privileges to grant to #{quote_user(user, host)}", :color => :yellow)
  end
end

#disable_log_bin_localObject



206
207
208
209
210
# File 'lib/gratan/driver.rb', line 206

def disable_log_bin_local
  unless @options[:skip_disable_log_bin]
    query('SET SQL_LOG_BIN = 0')
  end
end

#drop_user(user, host) ⇒ Object



81
82
83
84
# File 'lib/gratan/driver.rb', line 81

def drop_user(user, host)
  sql = "DROP USER #{quote_user(user, host)}"
  delete(sql)
end

#each_userObject



11
12
13
14
15
# File 'lib/gratan/driver.rb', line 11

def each_user
  query('SELECT user, host FROM mysql.user').each do |row|
    yield(row['user'], row['host'])
  end
end

#expand_object(object_or_regexp) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gratan/driver.rb', line 48

def expand_object(object_or_regexp)
  if object_or_regexp.kind_of?(Regexp)
    objects = show_all_tables.select {|i| i =~ object_or_regexp }
  else
    objects = [object_or_regexp]
  end

  objects.select do |object|
    object !~ @options[:ignore_object]
  end
end

#flush_privilegesObject



60
61
62
# File 'lib/gratan/driver.rb', line 60

def flush_privileges
  update("FLUSH PRIVILEGES")
end

#grant(user, host, object, options) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/gratan/driver.rb', line 86

def grant(user, host, object, options)
  privs = options.fetch(:privs)
  identified = options[:identified]
  required = options[:required]
  with_option = options[:with]

  sql = 'GRANT %s ON %s TO %s' % [
    privs.join(', '),
    quote_object(object),
    quote_user(user, host),
  ]

  sql << " IDENTIFIED BY #{quote_identifier(identified)}" if identified
  sql << " REQUIRE #{required}" if required
  sql << " WITH #{with_option}" if with_option

  begin
    update(sql)
  rescue Mysql2::Error => e
    if @options[:ignore_not_exist] and e.error_number == ER_NO_SUCH_TABLE
      log(:warn, e.message, :color => :yellow)
    else
      raise e
    end
  end
end

#identify(user, host, identifier) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/gratan/driver.rb', line 113

def identify(user, host, identifier)
  sql = 'GRANT USAGE ON *.* TO %s IDENTIFIED BY %s' % [
    quote_user(user, host),
    quote_identifier(identifier),
  ]

  update(sql)

  if (identifier || '').empty?
    set_password(user, host, identifier)
  end
end

#override_sql_modeObject



212
213
214
215
216
# File 'lib/gratan/driver.rb', line 212

def override_sql_mode
  if @options[:override_sql_mode]
    query('SET SQL_MODE = ""')
  end
end

#revoke(user, host, object, options = {}) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/gratan/driver.rb', line 152

def revoke(user, host, object, options = {})
  privs = options.fetch(:privs)
  with_option = options[:with]

  if with_option =~ /\bGRANT\s+OPTION\b/i
    revoke0(user, host, object, ['GRANT OPTION'])

    if privs.length == 1 and privs[0] =~ /\AUSAGE\z/i
      return
    end
  end

  revoke0(user, host, object, privs)
end

#revoke0(user, host, object, privs) ⇒ Object



167
168
169
170
171
172
173
174
175
# File 'lib/gratan/driver.rb', line 167

def revoke0(user, host, object, privs)
  sql = 'REVOKE %s ON %s FROM %s' % [
    privs.join(', '),
    quote_object(object),
    quote_user(user, host),
  ]

  delete(sql)
end

#set_password(user, host, password, options = {}) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/gratan/driver.rb', line 126

def set_password(user, host, password, options = {})
  password ||= ''

  unless options[:hash]
    password = "PASSWORD('#{escape(password)}')"
  end

  sql = 'SET PASSWORD FOR %s = %s' % [
    quote_user(user, host),
    password,
  ]

  update(sql)
end

#set_require(user, host, required) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# File 'lib/gratan/driver.rb', line 141

def set_require(user, host, required)
  required ||= 'NONE'

  sql = 'GRANT USAGE ON *.* TO %s REQUIRE %s' % [
    quote_user(user, host),
    required
  ]

  update(sql)
end

#show_all_tablesObject



40
41
42
43
44
45
46
# File 'lib/gratan/driver.rb', line 40

def show_all_tables
  @all_tables ||= show_databases.map {|database|
    show_tables(database).map do |table|
      "#{database}.#{table}"
    end
  }.flatten
end

#show_create_user(user, host) ⇒ Object



23
24
25
# File 'lib/gratan/driver.rb', line 23

def show_create_user(user, host)
  query("SHOW CREATE USER #{quote_user(user, host)}").first.values.first
end

#show_databasesObject



27
28
29
# File 'lib/gratan/driver.rb', line 27

def show_databases
  query("SHOW DATABASES").map {|i| i.values.first }
end

#show_grants(user, host) ⇒ Object



17
18
19
20
21
# File 'lib/gratan/driver.rb', line 17

def show_grants(user, host)
  query("SHOW GRANTS FOR #{quote_user(user, host)}").each do |row|
    yield(row.values.first)
  end
end

#show_tables(database) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/gratan/driver.rb', line 31

def show_tables(database)
  query("SHOW TABLES FROM `#{database}`").map {|i| i.values.first }
rescue Mysql2::Error => e
  raise e if e.error_number != 1102

  log(:debug, e.message)
  []
end

#update_with_option(user, host, object, with_option) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/gratan/driver.rb', line 177

def update_with_option(user, host, object, with_option)
  options = []

  if with_option =~ /\bGRANT\s+OPTION\b/i
    options << 'GRANT OPTION'
  else
    revoke(user, host, object, :privs => ['GRANT OPTION'])
  end

  %w(
    MAX_QUERIES_PER_HOUR
    MAX_UPDATES_PER_HOUR
    MAX_CONNECTIONS_PER_HOUR
    MAX_USER_CONNECTIONS
  ).each do |name|
    count = 0

    if with_option =~ /\b#{name}\s+(\d+)\b/i
      count = $1
    end

    options << [name, count].join(' ')
  end

  unless options.empty?
    grant(user, host, object, :privs => ['USAGE'], :with => options.join(' '))
  end
end