baza 0.0.19 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +157 -0
  3. data/Gemfile +11 -9
  4. data/Gemfile.lock +41 -9
  5. data/README.md +1 -1
  6. data/Rakefile +19 -16
  7. data/VERSION +1 -1
  8. data/baza.gemspec +31 -7
  9. data/config/best_project_practice_rubocop.yml +2 -0
  10. data/config/best_project_practice_rubocop_todo.yml +157 -0
  11. data/lib/baza/base_sql_driver.rb +79 -20
  12. data/lib/baza/cloner.rb +2 -2
  13. data/lib/baza/column.rb +6 -0
  14. data/lib/baza/database.rb +33 -0
  15. data/lib/baza/database_model.rb +26 -0
  16. data/lib/baza/database_model_functionality.rb +10 -0
  17. data/lib/baza/database_model_name.rb +16 -0
  18. data/lib/baza/db.rb +210 -413
  19. data/lib/baza/dbtime.rb +20 -20
  20. data/lib/baza/driver.rb +3 -3
  21. data/lib/baza/drivers/active_record/columns.rb +1 -1
  22. data/lib/baza/drivers/active_record/indexes.rb +1 -1
  23. data/lib/baza/drivers/active_record/result.rb +3 -5
  24. data/lib/baza/drivers/active_record/tables.rb +2 -2
  25. data/lib/baza/drivers/active_record.rb +30 -16
  26. data/lib/baza/drivers/mysql/column.rb +51 -48
  27. data/lib/baza/drivers/mysql/columns.rb +8 -8
  28. data/lib/baza/drivers/mysql/database.rb +28 -0
  29. data/lib/baza/drivers/mysql/databases.rb +35 -0
  30. data/lib/baza/drivers/mysql/index.rb +32 -22
  31. data/lib/baza/drivers/mysql/result.rb +24 -24
  32. data/lib/baza/drivers/mysql/sqlspecs.rb +1 -1
  33. data/lib/baza/drivers/mysql/table.rb +80 -91
  34. data/lib/baza/drivers/mysql/tables.rb +30 -32
  35. data/lib/baza/drivers/mysql/unbuffered_result.rb +5 -5
  36. data/lib/baza/drivers/mysql.rb +127 -220
  37. data/lib/baza/drivers/mysql2/database.rb +2 -0
  38. data/lib/baza/drivers/mysql2/databases.rb +2 -0
  39. data/lib/baza/drivers/mysql2/result.rb +3 -5
  40. data/lib/baza/drivers/mysql2.rb +21 -106
  41. data/lib/baza/drivers/mysql_java/database.rb +2 -0
  42. data/lib/baza/drivers/mysql_java/databases.rb +2 -0
  43. data/lib/baza/drivers/mysql_java.rb +16 -12
  44. data/lib/baza/drivers/sqlite3/column.rb +33 -33
  45. data/lib/baza/drivers/sqlite3/columns.rb +6 -6
  46. data/lib/baza/drivers/sqlite3/database.rb +2 -0
  47. data/lib/baza/drivers/sqlite3/databases.rb +25 -0
  48. data/lib/baza/drivers/sqlite3/index.rb +20 -6
  49. data/lib/baza/drivers/sqlite3/result.rb +16 -17
  50. data/lib/baza/drivers/sqlite3/sqlspecs.rb +1 -1
  51. data/lib/baza/drivers/sqlite3/table.rb +99 -100
  52. data/lib/baza/drivers/sqlite3/tables.rb +30 -23
  53. data/lib/baza/drivers/sqlite3/unbuffered_result.rb +2 -2
  54. data/lib/baza/drivers/sqlite3.rb +27 -14
  55. data/lib/baza/drivers/sqlite3_java/database.rb +2 -0
  56. data/lib/baza/drivers/sqlite3_java/unbuffered_result.rb +2 -2
  57. data/lib/baza/drivers/sqlite3_java.rb +12 -10
  58. data/lib/baza/drivers/sqlite3_rhodes.rb +9 -7
  59. data/lib/baza/dump.rb +55 -55
  60. data/lib/baza/errors.rb +5 -0
  61. data/lib/baza/idquery.rb +25 -25
  62. data/lib/baza/index.rb +6 -0
  63. data/lib/baza/jdbc_driver.rb +6 -8
  64. data/lib/baza/jdbc_result.rb +1 -1
  65. data/lib/baza/model.rb +299 -309
  66. data/lib/baza/model_custom.rb +74 -72
  67. data/lib/baza/model_handler.rb +244 -255
  68. data/lib/baza/model_handler_sqlhelper.rb +122 -132
  69. data/lib/baza/mysql_base_driver.rb +112 -0
  70. data/lib/baza/query_buffer.rb +23 -23
  71. data/lib/baza/result_base.rb +2 -2
  72. data/lib/baza/revision.rb +67 -67
  73. data/lib/baza/row.rb +82 -84
  74. data/lib/baza/sqlspecs.rb +1 -1
  75. data/lib/baza/table.rb +31 -0
  76. data/lib/baza.rb +43 -10
  77. data/shippable.yml +1 -0
  78. data/spec/cloner_spec.rb +4 -4
  79. data/spec/drivers/active_record_mysql2_spec.rb +3 -3
  80. data/spec/drivers/active_record_mysql_spec.rb +2 -2
  81. data/spec/drivers/active_record_sqlite3_spec.rb +2 -2
  82. data/spec/drivers/mysql2_spec.rb +1 -0
  83. data/spec/drivers/mysql_spec.rb +1 -0
  84. data/spec/drivers/sqlite3_spec.rb +4 -5
  85. data/spec/info_active_record_example.rb +4 -6
  86. data/spec/info_active_record_mysql.rb +6 -7
  87. data/spec/info_active_record_mysql2.rb +2 -4
  88. data/spec/info_active_record_mysql2_shippable.rb +2 -4
  89. data/spec/info_active_record_mysql_shippable.rb +2 -4
  90. data/spec/info_active_record_sqlite3.rb +5 -6
  91. data/spec/info_mysql2_example.rb +1 -1
  92. data/spec/info_mysql2_shippable.rb +1 -1
  93. data/spec/info_mysql_example.rb +1 -1
  94. data/spec/info_mysql_shippable.rb +1 -1
  95. data/spec/info_sqlite3.rb +4 -3
  96. data/spec/model_handler_spec.rb +102 -115
  97. data/spec/spec_helper.rb +5 -5
  98. data/spec/support/driver_collection.rb +98 -95
  99. data/spec/support/driver_columns_collection.rb +18 -22
  100. data/spec/support/driver_databases_collection.rb +29 -0
  101. data/spec/support/driver_indexes_collection.rb +7 -6
  102. data/spec/support/driver_tables_collection.rb +38 -26
  103. metadata +49 -3
data/lib/baza/db.rb CHANGED
@@ -1,4 +1,4 @@
1
- #A wrapper of several possible database-types.
1
+ # A wrapper of several possible database-types.
2
2
  #
3
3
  #===Examples
4
4
  # db = Baza::Db.new(type: :mysql2, db: "mysql", user: "user", pass: "password")
@@ -12,9 +12,9 @@
12
12
  # print data[:name]
13
13
  # end
14
14
  class Baza::Db
15
- attr_reader :sep_col, :sep_table, :sep_val, :opts, :conn, :conns, :int_types
15
+ attr_reader :sep_col, :sep_table, :sep_val, :opts, :driver, :int_types
16
16
 
17
- #Returns an array containing hashes of information about each registered driver.
17
+ # Returns an array containing hashes of information about each registered driver.
18
18
  def self.drivers
19
19
  path = "#{File.dirname(__FILE__)}/drivers"
20
20
  drivers = []
@@ -34,10 +34,10 @@ class Baza::Db
34
34
  }
35
35
  end
36
36
 
37
- return drivers
37
+ drivers
38
38
  end
39
39
 
40
- #Tries to create a database-object based on the given object which could be a SQLite3 object or a MySQL 2 object (or other supported).
40
+ # Tries to create a database-object based on the given object which could be a SQLite3 object or a MySQL 2 object (or other supported).
41
41
  def self.from_object(args)
42
42
  args = {object: args} unless args.is_a?(Hash)
43
43
  raise "No :object was given." unless args[:object]
@@ -47,14 +47,13 @@ class Baza::Db
47
47
  next unless const.respond_to?(:from_object)
48
48
 
49
49
  obj = const.from_object(args)
50
- if obj.is_a?(Hash) && obj[:type] == :success
51
- if obj[:args]
52
- new_args = obj[:args]
53
- new_args = new_args.merge(args[:new_args]) if args[:new_args]
54
- return Baza::Db.new(new_args)
55
- else
56
- raise "Didnt know what to do."
57
- end
50
+ next unless obj.is_a?(Hash) && obj[:type] == :success
51
+ if obj[:args]
52
+ new_args = obj[:args]
53
+ new_args = new_args.merge(args[:new_args]) if args[:new_args]
54
+ return Baza::Db.new(new_args)
55
+ else
56
+ raise "Didnt know what to do."
58
57
  end
59
58
  end
60
59
 
@@ -62,35 +61,28 @@ class Baza::Db
62
61
  end
63
62
 
64
63
  def initialize(opts)
65
- @conn = opts.delete(:driver) if opts[:driver]
66
- self.opts = opts if opts != nil
64
+ @driver = opts.delete(:driver) if opts[:driver]
65
+ Baza.load_driver(opts.fetch(:type))
66
+ self.opts = opts unless opts.nil?
67
67
  @int_types = [:int, :bigint, :tinyint, :smallint, :mediumint]
68
68
 
69
- unless @opts[:threadsafe]
70
- require 'monitor'
71
- @mutex = Monitor.new
72
- end
73
-
74
69
  @debug = @opts[:debug]
70
+ @driver = spawn
71
+ @sep_table = @driver.sep_table
72
+ @sep_col = @driver.sep_col
73
+ @sep_val = @driver.sep_val
75
74
 
76
- conn_exec do |driver|
77
- @sep_table = driver.sep_table
78
- @sep_col = driver.sep_col
79
- @sep_val = driver.sep_val
80
- @esc_driver = driver
81
- end
75
+ return unless block_given?
82
76
 
83
- if block_given?
84
- begin
85
- yield self
86
- ensure
87
- close
88
- end
77
+ begin
78
+ yield self
79
+ ensure
80
+ close
89
81
  end
90
82
  end
91
83
 
92
84
  def args
93
- return @opts
85
+ @opts
94
86
  end
95
87
 
96
88
  def opts=(arr_opts)
@@ -99,111 +91,63 @@ class Baza::Db
99
91
  @opts[key.to_sym] = val
100
92
  end
101
93
 
102
- if RUBY_PLATFORM == 'java'
94
+ if RUBY_PLATFORM == "java"
103
95
  @opts[:type] = :sqlite3_java if @opts[:type] == :sqlite3
104
96
  @opts[:type] = :mysql_java if @opts[:type] == :mysql || @opts[:type] == :mysql2
105
97
  end
106
98
 
107
99
  @type_cc = StringCases.snake_to_camel(@opts[:type])
108
- self.connect
109
- end
110
-
111
- #Actually connects to the database. This is useually done automatically.
112
- def connect
113
- if @opts[:threadsafe]
114
- require "#{$knjpath}threadhandler"
115
- @conns = Knj::Threadhandler.new
116
-
117
- @conns.on_spawn_new do
118
- self.spawn
119
- end
120
-
121
- @conns.on_inactive do |data|
122
- data[:obj].close
123
- end
124
-
125
- @conns.on_activate do |data|
126
- data[:obj].reconnect
127
- end
128
- else
129
- @conn = self.spawn
130
- end
131
100
  end
132
101
 
133
- #Spawns a new driver (useally done automatically).
102
+ # Spawns a new driver (useally done automatically).
134
103
  #===Examples
135
104
  # driver_instance = db.spawn
136
105
  def spawn
137
106
  raise "No type given (#{@opts.keys.join(",")})." unless @opts[:type]
138
107
  rpath = "#{File.dirname(__FILE__)}/drivers/#{@opts[:type]}.rb"
139
- require rpath if File.exists?(rpath)
140
- return Baza::Driver.const_get(@type_cc).new(self)
108
+ require rpath if File.exist?(rpath)
109
+ Baza::Driver.const_get(@type_cc).new(self)
141
110
  end
142
111
 
143
- #Registers a driver to the current thread.
112
+ # Registers a driver to the current thread.
144
113
  def get_and_register_thread
145
114
  raise "Baza-object is not in threadding mode" unless @conns
146
115
 
147
116
  thread_cur = Thread.current
148
- tid = self.__id__
149
- thread_cur[:baza] = {} if !thread_cur[:baza]
117
+ tid = __id__
118
+ thread_cur[:baza] = {} unless thread_cur[:baza]
150
119
 
151
120
  if thread_cur[:baza][tid]
152
- #An object has already been spawned - free that first to avoid endless "used" objects.
153
- self.free_thread
121
+ # An object has already been spawned - free that first to avoid endless "used" objects.
122
+ free_thread
154
123
  end
155
124
 
156
125
  thread_cur[:baza][tid] = @conns.get_and_lock unless thread_cur[:baza][tid]
157
126
 
158
- #If block given then be ensure to free thread after yielding.
159
- if block_given?
160
- begin
161
- yield
162
- ensure
163
- self.free_thread
164
- end
165
- end
166
- end
167
-
168
- #Frees the current driver from the current thread.
169
- def free_thread
170
- thread_cur = Thread.current
171
- tid = self.__id__
127
+ # If block given then be ensure to free thread after yielding.
128
+ return unless block_given?
172
129
 
173
- if thread_cur[:baza] && thread_cur[:baza].key?(tid)
174
- db = thread_cur[:baza][tid]
175
- thread_cur[:baza].delete(tid)
176
- @conns.free(db) if @conns
177
- end
178
- end
179
-
180
- #Clean up various memory-stuff if possible.
181
- def clean
182
- if @conns
183
- @conns.objects.each do |data|
184
- data[:object].clean if data[:object].respond_to?("clean")
185
- end
186
- elsif @conn
187
- @conn.clean if @conn.respond_to?("clean")
130
+ begin
131
+ yield
132
+ ensure
133
+ free_thread
188
134
  end
189
135
  end
190
136
 
191
- #The all driver-database-connections.
137
+ # The all driver-database-connections.
192
138
  def close
193
- @conn.close if @conn
194
- @conns.destroy if @conns
195
-
196
- @conn = nil
197
- @conns = nil
198
-
139
+ @driver.close if @driver
140
+ @driver = nil
199
141
  @closed = true
200
142
  end
201
143
 
144
+ # rubocop:disable Style/TrivialAccessors
202
145
  def closed?
146
+ # rubocop:enable Style/TrivialAccessors
203
147
  @closed
204
148
  end
205
149
 
206
- #Clones the current database-connection with possible extra arguments.
150
+ # Clones the current database-connection with possible extra arguments.
207
151
  def clone_conn(args = {})
208
152
  conn = Baza::Db.new(opts = @opts.clone.merge(args))
209
153
 
@@ -221,14 +165,14 @@ class Baza::Db
221
165
  end
222
166
 
223
167
  COPY_TO_ALLOWED_ARGS = [:tables, :debug]
224
- #Copies the content of the current database to another instance of Baza::Db.
168
+ # Copies the content of the current database to another instance of Baza::Db.
225
169
  def copy_to(db, args = {})
226
170
  debug = args[:debug]
227
- raise "No tables given." if !data[:tables]
171
+ raise "No tables given." unless data[:tables]
228
172
 
229
173
  data[:tables].each do |table|
230
174
  table_args = nil
231
- table_args = args[:tables][table[:name.to_sym]] if args && args[:tables] && args[:tables][table[:name].to_sym]
175
+ table_args = args[:tables][table[:name]] if args && args[:tables] && args[:tables][table[:name].to_sym]
232
176
  next if table_args && table_args[:skip]
233
177
  table.delete(:indexes) if table.key?(:indexes) && args[:skip_indexes]
234
178
 
@@ -242,12 +186,12 @@ class Baza::Db
242
186
  loop do
243
187
  puts "Copying rows (#{limit_from}, #{limit_incr})." if debug
244
188
  ins_arr = []
245
- q_rows = self.select(table_name, {}, {limit_from: limit_from, limit_to: limit_incr}) do |d_rows|
189
+ select(table_name, {}, limit_from: limit_from, limit_to: limit_incr) do |d_rows|
246
190
  col_args = nil
247
191
 
248
192
  if table_args && table_args[:columns]
249
- d_rows.each do |col_name, col_data|
250
- col_args = table_args[:columns][col_name.to_sym] if table_args && table_args[:columns]
193
+ d_rows.each do |col_name, _col_data|
194
+ col_args = table_args[:columns][col_name] if table_args && table_args[:columns]
251
195
  d_rows[col_name] = "" if col_args && col_args[:empty]
252
196
  end
253
197
  end
@@ -264,89 +208,28 @@ class Baza::Db
264
208
  end
265
209
  end
266
210
 
267
- #Returns the data of this database in a hash.
211
+ # Returns the data of this database in a hash.
268
212
  #===Examples
269
213
  # data = db.data
270
214
  # tables_hash = data['tables']
271
215
  def data
272
216
  tables_ret = []
273
- tables.list.each do |name, table|
217
+ tables.list do |table|
274
218
  tables_ret << table.data
275
219
  end
276
220
 
277
- return {
278
- tables: tables_ret
279
- }
221
+ {tables: tables_ret}
280
222
  end
281
223
 
282
- #Simply inserts data into a table.
283
- #
284
- #===Examples
285
- # db.insert(:users, name: "John", lastname: "Doe")
286
- # id = db.insert(:users, {name: "John", lastname: "Doe"}, return_id: true)
287
- # sql = db.insert(:users, {name: "John", lastname: "Doe"}, return_sql: true) #=> "INSERT INTO `users` (`name`, `lastname`) VALUES ('John', 'Doe')"
288
- def insert(tablename, arr_insert, args = nil)
289
- sql = "INSERT INTO #{@sep_table}#{self.esc_table(tablename)}#{@sep_table}"
290
-
291
- if !arr_insert || arr_insert.empty?
292
- # This is the correct syntax for inserting a blank row in MySQL.
293
- if @opts[:type].to_s.include?("mysql")
294
- sql << " VALUES ()"
295
- elsif @opts[:type].to_s.include?("sqlite3")
296
- sql << " DEFAULT VALUES"
297
- else
298
- raise "Unknown database-type: '#{@opts[:type]}'."
299
- end
300
- else
301
- sql << " ("
302
-
303
- first = true
304
- arr_insert.each do |key, value|
305
- if first
306
- first = false
307
- else
308
- sql << ", "
309
- end
310
-
311
- sql << "#{@sep_col}#{self.esc_col(key)}#{@sep_col}"
312
- end
313
-
314
- sql << ") VALUES ("
315
-
316
- first = true
317
- arr_insert.each do |key, value|
318
- if first
319
- first = false
320
- else
321
- sql << ", "
322
- end
323
-
324
- sql << self.sqlval(value)
325
- end
326
-
327
- sql << ")"
328
- end
329
-
330
- return sql if args && args[:return_sql]
331
-
332
- conn_exec do |driver|
333
- begin
334
- driver.query(sql)
335
- rescue => e
336
- self.add_sql_to_error(e, sql) if @opts[:sql_to_error]
337
- raise e
338
- end
339
-
340
- return driver.last_id if args && args[:return_id]
341
- return nil
342
- end
224
+ def insert(table_name, data, args = nil)
225
+ @driver.insert(table_name, data, args)
343
226
  end
344
227
 
345
228
  def add_sql_to_error(error, sql)
346
229
  error.message << " (SQL: #{sql})"
347
230
  end
348
231
 
349
- #Returns the correct SQL-value for the given value. If it is a number, then just the raw number as a string will be returned. nil's will be NULL and strings will have quotes and will be escaped.
232
+ # Returns the correct SQL-value for the given value. If it is a number, then just the raw number as a string will be returned. nil's will be NULL and strings will have quotes and will be escaped.
350
233
  def sqlval(val)
351
234
  return @conn.sqlval(val) if @conn.respond_to?(:sqlval)
352
235
 
@@ -359,11 +242,11 @@ class Baza::Db
359
242
  elsif val.is_a?(Time) || val.is_a?(DateTime)
360
243
  return "#{@sep_val}#{Datet.in(val).dbstr}#{@sep_val}"
361
244
  else
362
- return "#{@sep_val}#{self.escape(val)}#{@sep_val}"
245
+ return "#{@sep_val}#{escape(val)}#{@sep_val}"
363
246
  end
364
247
  end
365
248
 
366
- #Simply and optimal insert multiple rows into a table in a single query. Uses the drivers functionality if supported or inserts each row manually.
249
+ # Simply and optimal insert multiple rows into a table in a single query. Uses the drivers functionality if supported or inserts each row manually.
367
250
  #
368
251
  #===Examples
369
252
  # db.insert_multi(:users, [
@@ -373,9 +256,9 @@ class Baza::Db
373
256
  def insert_multi(tablename, arr_hashes, args = nil)
374
257
  return false if arr_hashes.empty?
375
258
 
376
- if @esc_driver.respond_to?(:insert_multi)
259
+ if @driver.respond_to?(:insert_multi)
377
260
  if args && args[:return_sql]
378
- res = @esc_driver.insert_multi(tablename, arr_hashes, args)
261
+ res = @driver.insert_multi(tablename, arr_hashes, args)
379
262
  if res.is_a?(String)
380
263
  return [res]
381
264
  elsif res.is_a?(Array)
@@ -385,13 +268,11 @@ class Baza::Db
385
268
  end
386
269
  end
387
270
 
388
- conn_exec do |driver|
389
- return driver.insert_multi(tablename, arr_hashes, args)
390
- end
271
+ @driver.insert_multi(tablename, arr_hashes, args)
391
272
  else
392
273
  transaction do
393
274
  arr_hashes.each do |hash|
394
- self.insert(tablename, hash, args)
275
+ insert(tablename, hash, args)
395
276
  end
396
277
  end
397
278
 
@@ -399,12 +280,12 @@ class Baza::Db
399
280
  end
400
281
  end
401
282
 
402
- #Simple updates rows.
283
+ # Simple updates rows.
403
284
  #
404
285
  #===Examples
405
286
  # db.update(:users, {name: "John"}, {lastname: "Doe"})
406
287
  def update(tablename, hash_update, arr_terms = {}, args = nil)
407
- raise "'hash_update' was not a hash: '#{hash_update.class.name}'." if !hash_update.is_a?(Hash)
288
+ raise "'hash_update' was not a hash: '#{hash_update.class.name}'." unless hash_update.is_a?(Hash)
408
289
  return false if hash_update.empty?
409
290
 
410
291
  sql = ""
@@ -418,27 +299,23 @@ class Baza::Db
418
299
  sql << ", "
419
300
  end
420
301
 
421
- #Convert dates to valid dbstr.
422
- value = self.date_out(value) if value.is_a?(Datet) || value.is_a?(Time)
302
+ # Convert dates to valid dbstr.
303
+ value = date_out(value) if value.is_a?(Datet) || value.is_a?(Time)
423
304
 
424
- sql << "#{@sep_col}#{self.esc_col(key)}#{@sep_col} = "
425
- sql << self.sqlval(value)
305
+ sql << "#{@sep_col}#{escape_column(key)}#{@sep_col} = "
306
+ sql << sqlval(value)
426
307
  end
427
308
 
428
- if arr_terms && arr_terms.length > 0
429
- sql << " WHERE #{self.makeWhere(arr_terms)}"
430
- end
309
+ sql << " WHERE #{makeWhere(arr_terms)}" if arr_terms && arr_terms.length > 0
431
310
 
432
311
  return sql if args && args[:return_sql]
433
312
 
434
- conn_exec do |driver|
435
- driver.query(sql)
436
- end
313
+ query(sql)
437
314
  end
438
315
 
439
- #Checks if a given terms exists. If it does, updates it to match data. If not inserts the row.
316
+ # Checks if a given terms exists. If it does, updates it to match data. If not inserts the row.
440
317
  def upsert(table, data, terms, args = nil)
441
- row = self.single(table, terms)
318
+ row = single(table, terms)
442
319
 
443
320
  if args && args[:buffer]
444
321
  obj = args[:buffer]
@@ -454,59 +331,68 @@ class Baza::Db
454
331
  end
455
332
 
456
333
  SELECT_ARGS_ALLOWED_KEYS = [:limit, :limit_from, :limit_to]
457
- #Makes a select from the given arguments: table-name, where-terms and other arguments as limits and orders. Also takes a block to avoid raping of memory.
334
+ # Makes a select from the given arguments: table-name, where-terms and other arguments as limits and orders. Also takes a block to avoid raping of memory.
458
335
  def select(tablename, arr_terms = nil, args = nil, &block)
459
- #Set up vars.
336
+ # Set up vars.
460
337
  sql = ""
461
338
  args_q = nil
462
339
  select_sql = "*"
463
340
 
464
- #Give 'cloned_ubuf' argument to 'q'-method.
465
- if args && args[:cloned_ubuf]
466
- args_q = {cloned_ubuf: true}
467
- end
341
+ # Give 'cloned_ubuf' argument to 'q'-method.
342
+ args_q = {cloned_ubuf: true} if args && args[:cloned_ubuf]
468
343
 
469
- #Set up IDQuery-stuff if that is given in arguments.
344
+ # Set up IDQuery-stuff if that is given in arguments.
470
345
  if args && args[:idquery]
471
346
  if args[:idquery] == true
472
347
  select_sql = "`id`"
473
348
  col = :id
474
349
  else
475
- select_sql = "`#{self.esc_col(args[:idquery])}`"
350
+ select_sql = "`#{escape_column(args[:idquery])}`"
476
351
  col = args[:idquery]
477
352
  end
478
353
  end
479
354
 
480
- sql = "SELECT #{select_sql} FROM #{@sep_table}#{tablename}#{@sep_table}"
355
+ sql = "SELECT #{select_sql} FROM"
481
356
 
482
- if arr_terms != nil && !arr_terms.empty?
483
- sql << " WHERE #{self.makeWhere(arr_terms)}"
357
+ if tablename.is_a?(Array)
358
+ sql << " #{@sep_table}#{tablename.first}#{@sep_table}.#{@sep_table}#{tablename.last}#{@sep_table}"
359
+ else
360
+ sql << " #{@sep_table}#{tablename}#{@sep_table}"
484
361
  end
485
362
 
486
- if args != nil
487
- if args[:orderby]
488
- sql << " ORDER BY #{args[:orderby]}"
489
- end
363
+ if !arr_terms.nil? && !arr_terms.empty?
364
+ sql << " WHERE #{makeWhere(arr_terms)}"
365
+ end
490
366
 
491
- if args[:limit]
492
- sql << " LIMIT #{args[:limit]}"
493
- end
367
+ unless args.nil?
368
+ sql << " ORDER BY #{args[:orderby]}" if args[:orderby]
369
+ sql << " LIMIT #{args[:limit]}" if args[:limit]
494
370
 
495
371
  if args[:limit_from] && args[:limit_to]
496
- raise "'limit_from' was not numeric: '#{args[:limit_from]}'." if !(Float(args[:limit_from]) rescue false)
497
- raise "'limit_to' was not numeric: '#{args[:limit_to]}'." if !(Float(args[:limit_to]) rescue false)
372
+ begin
373
+ Float(args[:limit_from])
374
+ rescue
375
+ raise "'limit_from' was not numeric: '#{args[:limit_from]}'."
376
+ end
377
+
378
+ begin
379
+ Float(args[:limit_to])
380
+ rescue
381
+ raise "'limit_to' was not numeric: '#{args[:limit_to]}'."
382
+ end
383
+
498
384
  sql << " LIMIT #{args[:limit_from]}, #{args[:limit_to]}"
499
385
  end
500
386
  end
501
387
 
502
- #Do IDQuery if given in arguments.
388
+ # Do IDQuery if given in arguments.
503
389
  if args && args[:idquery]
504
390
  res = Baza::Idquery.new(db: self, table: tablename, query: sql, col: col, &block)
505
391
  else
506
392
  res = q(sql, args_q, &block)
507
393
  end
508
394
 
509
- #Return result if a block wasnt given.
395
+ # Return result if a block wasnt given.
510
396
  if block
511
397
  return nil
512
398
  else
@@ -515,55 +401,52 @@ class Baza::Db
515
401
  end
516
402
 
517
403
  def count(tablename, arr_terms = nil)
518
- #Set up vars.
404
+ # Set up vars.
519
405
  sql = ""
520
406
  args_q = nil
521
407
 
522
408
  sql = "SELECT COUNT(*) AS count FROM #{@sep_table}#{tablename}#{@sep_table}"
523
409
 
524
- if arr_terms != nil && !arr_terms.empty?
525
- sql << " WHERE #{self.makeWhere(arr_terms)}"
410
+ if !arr_terms.nil? && !arr_terms.empty?
411
+ sql << " WHERE #{makeWhere(arr_terms)}"
526
412
  end
527
413
 
528
- return q(sql).fetch.fetch(:count).to_i
414
+ q(sql).fetch.fetch(:count).to_i
529
415
  end
530
416
 
531
- #Returns a single row from a database.
417
+ # Returns a single row from a database.
532
418
  #
533
419
  #===Examples
534
420
  # row = db.single(:users, lastname: "Doe")
535
421
  def single(tablename, terms = nil, args = {})
536
- select(tablename, terms, args.merge(limit: 1)) { |data| return data } #Experienced very weird memory leak if this was not done by block. Maybe bug in Ruby 1.9.2? - knj
537
- return false
422
+ # Experienced very weird memory leak if this was not done by block. Maybe bug in Ruby 1.9.2? - knj
423
+ select(tablename, terms, args.merge(limit: 1)).fetch
538
424
  end
539
425
 
540
- alias :selectsingle :single
426
+ alias_method :selectsingle, :single
541
427
 
542
- #Deletes rows from the database.
428
+ # Deletes rows from the database.
543
429
  #
544
430
  #===Examples
545
431
  # db.delete(:users, {lastname: "Doe"})
546
432
  def delete(tablename, arr_terms, args = nil)
547
433
  sql = "DELETE FROM #{@sep_table}#{tablename}#{@sep_table}"
548
434
 
549
- if arr_terms != nil && !arr_terms.empty?
550
- sql << " WHERE #{self.makeWhere(arr_terms)}"
435
+ if !arr_terms.nil? && !arr_terms.empty?
436
+ sql << " WHERE #{makeWhere(arr_terms)}"
551
437
  end
552
438
 
553
439
  return sql if args && args[:return_sql]
554
440
 
555
- conn_exec do |driver|
556
- driver.query(sql)
557
- end
558
-
559
- return nil
441
+ query(sql)
442
+ nil
560
443
  end
561
444
 
562
- #Internally used to generate SQL.
445
+ # Internally used to generate SQL.
563
446
  #
564
447
  #===Examples
565
448
  # sql = db.makeWhere({lastname: "Doe"}, driver_obj)
566
- def makeWhere(arr_terms, driver = nil)
449
+ def makeWhere(arr_terms, _driver = nil)
567
450
  sql = ""
568
451
 
569
452
  first = true
@@ -576,63 +459,26 @@ class Baza::Db
576
459
 
577
460
  if value.is_a?(Array)
578
461
  raise "Array for column '#{key}' was empty." if value.empty?
579
- values = value.map { |v| "'#{escape(v)}'" }.join(',')
462
+ values = value.map { |v| "'#{escape(v)}'" }.join(",")
580
463
  sql << "#{@sep_col}#{key}#{@sep_col} IN (#{values})"
581
464
  elsif value.is_a?(Hash)
582
465
  raise "Dont know how to handle hash."
583
466
  else
584
- sql << "#{@sep_col}#{key}#{@sep_col} = #{self.sqlval(value)}"
585
- end
586
- end
587
-
588
- return sql
589
- end
590
-
591
- #Returns a driver-object based on the current thread and free driver-objects.
592
- #
593
- #===Examples
594
- # db.conn_exec do |driver|
595
- # str = driver.escape('something̈́')
596
- # end
597
- def conn_exec
598
- raise "Call to closed database" if @closed
599
-
600
- if tcur = Thread.current && Thread.current[:baza]
601
- tid = self.__id__
602
-
603
- if tcur[:baza].key?(tid)
604
- yield(tcur[:baza][tid])
605
- return nil
467
+ sql << "#{@sep_col}#{key}#{@sep_col} = #{sqlval(value)}"
606
468
  end
607
469
  end
608
470
 
609
- if @conns
610
- conn = @conns.get_and_lock
611
-
612
- begin
613
- yield(conn)
614
- return nil
615
- ensure
616
- @conns.free(conn)
617
- end
618
- elsif @conn
619
- @mutex.synchronize do
620
- yield(@conn)
621
- return nil
622
- end
623
- end
624
-
625
- raise "Could not figure out which driver to use?"
471
+ sql
626
472
  end
627
473
 
628
- #Executes a query and returns the result.
474
+ # Executes a query and returns the result.
629
475
  #
630
476
  #===Examples
631
477
  # res = db.query('SELECT * FROM users')
632
478
  # while data = res.fetch
633
479
  # print data[:name]
634
480
  # end
635
- def query(string)
481
+ def query(string, args = nil, &block)
636
482
  if @debug
637
483
  print "SQL: #{string}\n"
638
484
 
@@ -642,38 +488,49 @@ class Baza::Db
642
488
  end
643
489
  end
644
490
 
645
- begin
646
- conn_exec do |driver|
647
- return driver.query(string)
491
+ # If the query should be executed in a new connection unbuffered.
492
+ if args && args[:cloned_ubuf]
493
+ raise "No block given." unless block
494
+
495
+ cloned_conn(clone_args: args[:clone_args]) do |cloned_conn|
496
+ return cloned_conn.query_ubuf(string, args, &block)
648
497
  end
649
- rescue => e
650
- e.message << " (SQL: #{string})" if @opts[:sql_to_error]
651
- raise e
498
+
499
+ return nil
652
500
  end
501
+
502
+ return query_ubuf(string, args, &block) if args && args[:type] == :unbuffered
503
+
504
+ ret = @driver.query(string)
505
+
506
+ if block && ret
507
+ ret.each(&block)
508
+ return nil
509
+ end
510
+
511
+ ret
653
512
  end
654
513
 
655
- #Execute an ubuffered query and returns the result.
514
+ alias q query
515
+
516
+ # Execute an ubuffered query and returns the result.
656
517
  #
657
518
  #===Examples
658
519
  # db.query_ubuf('SELECT * FROM users') do |data|
659
520
  # print data[:name]
660
521
  # end
661
- def query_ubuf(string, &block)
662
- ret = nil
663
-
664
- conn_exec do |driver|
665
- ret = driver.query_ubuf(string, &block)
666
- end
522
+ def query_ubuf(string, args = nil, &block)
523
+ ret = @driver.query_ubuf(string)
667
524
 
668
525
  if block
669
526
  ret.each(&block)
670
527
  return nil
671
528
  end
672
529
 
673
- return ret
530
+ ret
674
531
  end
675
532
 
676
- #Clones the connection, executes the given block and closes the connection again.
533
+ # Clones the connection, executes the given block and closes the connection again.
677
534
  #
678
535
  #===Examples
679
536
  # db.cloned_conn do |conn|
@@ -681,13 +538,9 @@ class Baza::Db
681
538
  # print data[:name]
682
539
  # end
683
540
  # end
684
- def cloned_conn(args = nil, &block)
685
- clone_conn_args = {
686
- threadsafe: false
687
- }
688
-
689
- clone_conn_args.merge!(args[:clone_args]) if args && args[:clone_args]
690
- dbconn = self.clone_conn(clone_conn_args)
541
+ def cloned_conn(args = nil, &_block)
542
+ clone_conn_args = args[:clone_args] || {}
543
+ dbconn = clone_conn(clone_conn_args)
691
544
 
692
545
  begin
693
546
  yield(dbconn)
@@ -696,142 +549,103 @@ class Baza::Db
696
549
  end
697
550
  end
698
551
 
699
- #Executes a query and returns the result. If a block is given the result is iterated over that block instead and it returns nil.
700
- #
701
- #===Examples
702
- # db.q('SELECT * FROM users') do |data|
703
- # print data[:name]
704
- # end
705
- def q(sql, args = nil, &block)
706
- #If the query should be executed in a new connection unbuffered.
707
- if args && args[:cloned_ubuf]
708
- raise "No block given." unless block
709
-
710
- self.cloned_conn(clone_args: args[:clone_args]) do |cloned_conn|
711
- ret = cloned_conn.query_ubuf(sql)
712
- ret.each(&block)
713
- end
714
-
715
- return nil
716
- end
717
-
718
- if args && args[:type] == :unbuffered
719
- ret = self.query_ubuf(sql)
720
- else
721
- ret = self.query(sql)
722
- end
723
-
724
- if block
725
- ret.each(&block)
726
- return nil
727
- end
728
-
729
- return ret
730
- end
731
-
732
- #Yields a query-buffer and flushes at the end of the block given.
552
+ # Yields a query-buffer and flushes at the end of the block given.
733
553
  def q_buffer(args = {}, &block)
734
554
  Baza::QueryBuffer.new(args.merge(db: self), &block)
735
- return nil
555
+ nil
736
556
  end
737
557
 
738
- #Returns the last inserted ID.
558
+ # Returns the last inserted ID.
739
559
  #
740
560
  #===Examples
741
561
  # id = db.last_id
742
562
  def last_id
743
- conn_exec do |driver|
744
- return driver.last_id
745
- end
563
+ @driver.last_id
746
564
  end
747
565
 
748
- #Escapes a string to be safe-to-use in a query-string.
566
+ # Escapes a string to be safe-to-use in a query-string.
749
567
  #
750
568
  #===Examples
751
569
  # db.q("INSERT INTO users (name) VALUES ('#{db.esc('John')}')")
752
570
  def escape(string)
753
- return @esc_driver.escape(string)
571
+ @driver.escape(string)
754
572
  end
755
573
 
756
- alias :esc :escape
574
+ alias_method :esc, :escape
757
575
 
758
- #Escapes the given string to be used as a column.
759
- def esc_col(str)
760
- return @esc_driver.esc_col(str)
576
+ # Escapes the given string to be used as a column.
577
+ def escape_column(str)
578
+ @driver.escape_column(str)
761
579
  end
762
580
 
763
- #Escapes the given string to be used as a table.
764
- def esc_table(str)
765
- return @esc_driver.esc_table(str)
581
+ # Escapes the given string to be used as a table.
582
+ def escape_table(str)
583
+ @driver.escape_table(str)
766
584
  end
767
585
 
768
- #Returns a string which can be used in SQL with the current driver.
586
+ def escape_database(str)
587
+ @driver.escape_database(str)
588
+ end
589
+
590
+ # Returns a string which can be used in SQL with the current driver.
769
591
  #===Examples
770
592
  # str = db.date_out(Time.now) #=> "2012-05-20 22:06:09"
771
593
  def date_out(date_obj = Datet.new, args = {})
772
- if @esc_driver.respond_to?(:date_out)
773
- return @esc_driver.date_out(date_obj, args)
774
- end
775
-
776
- return Datet.in(date_obj).dbstr(args)
594
+ return @driver.date_out(date_obj, args) if @driver.respond_to?(:date_out)
595
+ Datet.in(date_obj).dbstr(args)
777
596
  end
778
597
 
779
- #Takes a valid date-db-string and converts it into a Datet.
598
+ # Takes a valid date-db-string and converts it into a Datet.
780
599
  #===Examples
781
600
  # db.date_in('2012-05-20 22:06:09') #=> 2012-05-20 22:06:09 +0200
782
601
  def date_in(date_obj)
783
- if @esc_driver.respond_to?(:date_in)
784
- return @esc_driver.date_in(date_obj)
785
- end
602
+ return @driver.date_in(date_obj) if @driver.respond_to?(:date_in)
786
603
 
787
- return Datet.in(date_obj)
604
+ Datet.in(date_obj)
788
605
  end
789
606
 
790
- #Returns the table-module and spawns it if it isnt already spawned.
791
- def tables
792
- unless @tables
793
- @tables = Baza::Driver.const_get(@type_cc).const_get(:Tables).new(
794
- db: self
795
- )
796
- end
607
+ def databases
608
+ require_relative "drivers/#{@opts.fetch(:type)}/databases"
609
+ @databases ||= Baza::Driver.const_get(@type_cc).const_get(:Databases).new(db: self)
610
+ end
797
611
 
798
- return @tables
612
+ # Returns the table-module and spawns it if it isnt already spawned.
613
+ def tables
614
+ @tables ||= Baza::Driver.const_get(@type_cc).const_get(:Tables).new(db: self)
799
615
  end
800
616
 
801
- #Returns the columns-module and spawns it if it isnt already spawned.
617
+ # Returns the columns-module and spawns it if it isnt already spawned.
802
618
  def cols
803
- unless @cols
804
- @cols = Baza::Driver.const_get(@type_cc).const_get(:Columns).new(
805
- db: self
806
- )
807
- end
808
-
809
- return @cols
619
+ @cols || Baza::Driver.const_get(@type_cc).const_get(:Columns).new(db: self)
810
620
  end
811
621
 
812
- #Returns the index-module and spawns it if it isnt already spawned.
622
+ # Returns the index-module and spawns it if it isnt already spawned.
813
623
  def indexes
814
- unless @indexes
815
- @indexes = Baza::Driver.const_get(@type_cc).const_get(:Indexes).new(
816
- db: self
817
- )
818
- end
819
-
820
- return @indexes
624
+ @indexes ||= Baza::Driver.const_get(@type_cc).const_get(:Indexes).new(db: self)
821
625
  end
822
626
 
823
- #Returns the SQLSpec-module and spawns it if it isnt already spawned.
627
+ # Returns the SQLSpec-module and spawns it if it isnt already spawned.
824
628
  def sqlspecs
825
- unless @sqlspecs
826
- @sqlspecs = Baza::Driver.const_get(@type_cc).const_get(:Sqlspecs).new(
827
- db: self
828
- )
629
+ @sqlspecs ||= Baza::Driver.const_get(@type_cc).const_get(:Sqlspecs).new(db: self)
630
+ end
631
+
632
+ def supports_multiple_databases?
633
+ if @driver.respond_to?(:supports_multiple_databases?)
634
+ @driver.supports_multiple_databases?
635
+ else
636
+ false
829
637
  end
638
+ end
830
639
 
831
- return @sqlspecs
640
+ def supports_type_translation?
641
+ if @driver.respond_to?(:supports_type_translation?)
642
+ @driver.supports_multiple_databases?
643
+ else
644
+ false
645
+ end
832
646
  end
833
647
 
834
- #Beings a transaction and commits when the block ends.
648
+ # Beings a transaction and commits when the block ends.
835
649
  #
836
650
  #===Examples
837
651
  # db.transaction do |db|
@@ -839,14 +653,11 @@ class Baza::Db
839
653
  # db.insert(:users, name: "Kasper")
840
654
  # end
841
655
  def transaction(&block)
842
- conn_exec do |driver|
843
- driver.transaction(&block)
844
- end
845
-
846
- return nil
656
+ @driver.transaction(&block)
657
+ nil
847
658
  end
848
659
 
849
- #Optimizes all tables in the database.
660
+ # Optimizes all tables in the database.
850
661
  def optimize(args = nil)
851
662
  STDOUT.puts "Beginning optimization of database." if @debug || (args && args[:debug])
852
663
  tables.list do |table|
@@ -854,25 +665,11 @@ class Baza::Db
854
665
  table.optimize
855
666
  end
856
667
 
857
- return nil
858
- end
859
-
860
- #Proxies the method to the driver.
861
- #
862
- #===Examples
863
- # db.method_on_driver
864
- def method_missing(method_name, *args)
865
- conn_exec do |driver|
866
- if driver.respond_to?(method_name.to_sym)
867
- return driver.send(method_name, *args)
868
- end
869
- end
870
-
871
- raise "Method not found: '#{method_name}'."
668
+ nil
872
669
  end
873
670
 
874
671
  def to_s
875
- "#<Baza::Db driver \"#{@opts[:type]}\">"
672
+ "#<Baza::Db driver=\"#{@opts[:type]}\">"
876
673
  end
877
674
 
878
675
  def inspect