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