baza 0.0.14 → 0.0.15
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 +4 -4
- data/README.md +58 -13
- data/VERSION +1 -1
- data/baza.gemspec +15 -3
- data/include/db.rb +871 -865
- data/include/drivers/mysql/mysql.rb +104 -297
- data/include/drivers/mysql/mysql_column.rb +133 -0
- data/include/drivers/mysql/mysql_columns.rb +4 -127
- data/include/drivers/mysql/mysql_index.rb +76 -0
- data/include/drivers/mysql/mysql_indexes.rb +0 -73
- data/include/drivers/mysql/mysql_result.rb +42 -0
- data/include/drivers/mysql/mysql_result_java.rb +61 -0
- data/include/drivers/mysql/mysql_result_mysql2.rb +26 -0
- data/include/drivers/mysql/mysql_result_unbuffered.rb +72 -0
- data/include/drivers/mysql/mysql_sqlspecs.rb +1 -1
- data/include/drivers/mysql/mysql_table.rb +361 -0
- data/include/drivers/mysql/mysql_tables.rb +23 -381
- data/include/drivers/sqlite3/libknjdb_java_sqlite3.rb +17 -22
- data/include/drivers/sqlite3/libknjdb_sqlite3_ironruby.rb +13 -13
- data/include/drivers/sqlite3/sqlite3.rb +39 -105
- data/include/drivers/sqlite3/sqlite3_column.rb +146 -0
- data/include/drivers/sqlite3/sqlite3_columns.rb +17 -149
- data/include/drivers/sqlite3/sqlite3_index.rb +55 -0
- data/include/drivers/sqlite3/sqlite3_indexes.rb +0 -52
- data/include/drivers/sqlite3/sqlite3_result.rb +35 -0
- data/include/drivers/sqlite3/sqlite3_result_java.rb +39 -0
- data/include/drivers/sqlite3/sqlite3_table.rb +399 -0
- data/include/drivers/sqlite3/sqlite3_tables.rb +7 -403
- data/include/idquery.rb +19 -19
- data/include/model.rb +139 -139
- data/include/model_handler_sqlhelper.rb +74 -74
- data/spec/support/driver_columns_collection.rb +17 -0
- metadata +14 -2
@@ -1,70 +1,82 @@
|
|
1
1
|
class Baza::Driver::Mysql
|
2
|
+
autoload :Table, "#{File.dirname(__FILE__)}/mysql_table"
|
3
|
+
autoload :Tables, "#{File.dirname(__FILE__)}/mysql_tables"
|
4
|
+
autoload :Column, "#{File.dirname(__FILE__)}/mysql_column"
|
5
|
+
autoload :Columns, "#{File.dirname(__FILE__)}/mysql_columns"
|
6
|
+
autoload :Index, "#{File.dirname(__FILE__)}/mysql_index"
|
7
|
+
autoload :Indexes, "#{File.dirname(__FILE__)}/mysql_indexes"
|
8
|
+
autoload :Result, "#{File.dirname(__FILE__)}/mysql_result"
|
9
|
+
autoload :ResultJava, "#{File.dirname(__FILE__)}/mysql_result_java"
|
10
|
+
autoload :ResultMysql2, "#{File.dirname(__FILE__)}/mysql_result_mysql2"
|
11
|
+
autoload :ResultUnbuffered, "#{File.dirname(__FILE__)}/mysql_result_unbuffered"
|
12
|
+
autoload :Sqlspecs, "#{File.dirname(__FILE__)}/mysql_sqlspecs"
|
13
|
+
|
2
14
|
attr_reader :baza, :conn, :conns, :sep_table, :sep_col, :sep_val
|
3
15
|
attr_accessor :tables, :cols, :indexes
|
4
|
-
|
16
|
+
|
5
17
|
#Helper to enable automatic registering of database using Baza::Db.from_object
|
6
18
|
def self.from_object(args)
|
7
19
|
if args[:object].class.name == "Mysql2::Client"
|
8
20
|
return {
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
21
|
+
type: :success,
|
22
|
+
args: {
|
23
|
+
type: :mysql,
|
24
|
+
subtype: :mysql2,
|
25
|
+
conn: args[:object],
|
26
|
+
query_args: {
|
27
|
+
as: :hash,
|
28
|
+
symbolize_keys: true
|
17
29
|
}
|
18
30
|
}
|
19
31
|
}
|
20
32
|
end
|
21
|
-
|
33
|
+
|
22
34
|
return nil
|
23
35
|
end
|
24
|
-
|
36
|
+
|
25
37
|
def initialize(baza_db_obj)
|
26
38
|
@baza_db = baza_db_obj
|
27
39
|
@opts = @baza_db.opts
|
28
40
|
@sep_table = "`"
|
29
41
|
@sep_col = "`"
|
30
42
|
@sep_val = "'"
|
31
|
-
|
43
|
+
|
32
44
|
require "monitor"
|
33
45
|
@mutex = Monitor.new
|
34
|
-
|
46
|
+
|
35
47
|
if @opts[:encoding]
|
36
48
|
@encoding = @opts[:encoding]
|
37
49
|
else
|
38
50
|
@encoding = "utf8"
|
39
51
|
end
|
40
|
-
|
52
|
+
|
41
53
|
if @baza_db.opts.key?(:port)
|
42
54
|
@port = @baza_db.opts[:port].to_i
|
43
55
|
else
|
44
56
|
@port = 3306
|
45
57
|
end
|
46
|
-
|
58
|
+
|
47
59
|
@java_rs_data = {}
|
48
60
|
@subtype = @baza_db.opts[:subtype]
|
49
61
|
@subtype = :mysql if @subtype.to_s.empty?
|
50
62
|
self.reconnect
|
51
63
|
end
|
52
|
-
|
64
|
+
|
53
65
|
#This method handels the closing of statements and results for the Java MySQL-mode.
|
54
66
|
def java_mysql_resultset_killer(id)
|
55
67
|
data = @java_rs_data[id]
|
56
68
|
return nil if !data
|
57
|
-
|
69
|
+
|
58
70
|
data[:res].close
|
59
71
|
data[:stmt].close
|
60
72
|
@java_rs_data.delete(id)
|
61
73
|
end
|
62
|
-
|
74
|
+
|
63
75
|
#Cleans the wref-map holding the tables.
|
64
76
|
def clean
|
65
77
|
self.tables.clean if self.tables
|
66
78
|
end
|
67
|
-
|
79
|
+
|
68
80
|
#Respawns the connection to the MySQL-database.
|
69
81
|
def reconnect
|
70
82
|
@mutex.synchronize do
|
@@ -74,28 +86,28 @@ class Baza::Driver::Mysql
|
|
74
86
|
when :mysql2
|
75
87
|
require "rubygems"
|
76
88
|
require "mysql2"
|
77
|
-
|
89
|
+
|
78
90
|
args = {
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
91
|
+
host: @baza_db.opts[:host],
|
92
|
+
username: @baza_db.opts[:user],
|
93
|
+
password: @baza_db.opts[:pass],
|
94
|
+
database: @baza_db.opts[:db],
|
95
|
+
port: @port,
|
96
|
+
symbolize_keys: true,
|
97
|
+
cache_rows: false
|
86
98
|
}
|
87
|
-
|
99
|
+
|
88
100
|
#Symbolize keys should also be given here, else table-data wont be symbolized for some reason - knj.
|
89
|
-
@query_args = {:
|
101
|
+
@query_args = {symbolize_keys: true}
|
90
102
|
@query_args.merge!(@baza_db.opts[:query_args]) if @baza_db.opts[:query_args]
|
91
|
-
|
103
|
+
|
92
104
|
pos_args = [:as, :async, :cast_booleans, :database_timezone, :application_timezone, :cache_rows, :connect_flags, :cast]
|
93
105
|
pos_args.each do |key|
|
94
106
|
args[key] = @baza_db.opts[key] if @baza_db.opts.key?(key)
|
95
107
|
end
|
96
|
-
|
108
|
+
|
97
109
|
args[:as] = :array if @opts[:result] == "array"
|
98
|
-
|
110
|
+
|
99
111
|
tries = 0
|
100
112
|
begin
|
101
113
|
tries += 1
|
@@ -112,33 +124,33 @@ class Baza::Driver::Mysql
|
|
112
124
|
retry
|
113
125
|
end
|
114
126
|
end
|
115
|
-
|
127
|
+
|
116
128
|
raise e
|
117
129
|
end
|
118
130
|
when :java
|
119
|
-
|
131
|
+
unless @jdbc_loaded
|
120
132
|
require "java"
|
121
133
|
require "/usr/share/java/mysql-connector-java.jar" if File.exists?("/usr/share/java/mysql-connector-java.jar")
|
122
134
|
import "com.mysql.jdbc.Driver"
|
123
135
|
@jdbc_loaded = true
|
124
136
|
end
|
125
|
-
|
137
|
+
|
126
138
|
@conn = java.sql::DriverManager.getConnection("jdbc:mysql://#{@baza_db.opts[:host]}:#{@port}/#{@baza_db.opts[:db]}?user=#{@baza_db.opts[:user]}&password=#{@baza_db.opts[:pass]}&populateInsertRowWithDefaultValues=true&zeroDateTimeBehavior=round&characterEncoding=#{@encoding}&holdResultsOpenOverStatementClose=true")
|
127
|
-
|
139
|
+
query("SET SQL_MODE = ''")
|
128
140
|
else
|
129
141
|
raise "Unknown subtype: #{@subtype} (#{@subtype.class.name})"
|
130
142
|
end
|
131
|
-
|
132
|
-
|
143
|
+
|
144
|
+
query("SET NAMES '#{self.esc(@encoding)}'") if @encoding
|
133
145
|
end
|
134
146
|
end
|
135
|
-
|
147
|
+
|
136
148
|
#Executes a query and returns the result.
|
137
149
|
def query(str)
|
138
150
|
str = str.to_s
|
139
151
|
str = str.force_encoding("UTF-8") if @encoding == "utf8" and str.respond_to?(:force_encoding)
|
140
152
|
tries = 0
|
141
|
-
|
153
|
+
|
142
154
|
begin
|
143
155
|
tries += 1
|
144
156
|
@mutex.synchronize do
|
@@ -146,33 +158,33 @@ class Baza::Driver::Mysql
|
|
146
158
|
when :mysql
|
147
159
|
return Baza::Driver::Mysql::Result.new(self, @conn.query(str))
|
148
160
|
when :mysql2
|
149
|
-
return Baza::Driver::Mysql::
|
161
|
+
return Baza::Driver::Mysql::ResultMysql2.new(@conn.query(str, @query_args))
|
150
162
|
when :java
|
151
163
|
stmt = conn.create_statement
|
152
|
-
|
164
|
+
|
153
165
|
if str.match(/^\s*(delete|update|create|drop|insert\s+into|alter)\s+/i)
|
154
166
|
begin
|
155
167
|
stmt.execute(str)
|
156
168
|
ensure
|
157
169
|
stmt.close
|
158
170
|
end
|
159
|
-
|
171
|
+
|
160
172
|
return nil
|
161
173
|
else
|
162
174
|
id = nil
|
163
|
-
|
175
|
+
|
164
176
|
begin
|
165
177
|
res = stmt.execute_query(str)
|
166
178
|
ret = Baza::Driver::Mysql::ResultJava.new(@baza_db, @opts, res)
|
167
179
|
id = ret.__id__
|
168
|
-
|
180
|
+
|
169
181
|
#If ID is being reused we have to free the result.
|
170
182
|
self.java_mysql_resultset_killer(id) if @java_rs_data.key?(id)
|
171
|
-
|
183
|
+
|
172
184
|
#Save reference to result and statement, so we can close them when they are garbage collected.
|
173
|
-
@java_rs_data[id] = {:
|
174
|
-
ObjectSpace.define_finalizer(ret,
|
175
|
-
|
185
|
+
@java_rs_data[id] = {res: res, stmt: stmt}
|
186
|
+
ObjectSpace.define_finalizer(ret, method(:java_mysql_resultset_killer))
|
187
|
+
|
176
188
|
return ret
|
177
189
|
rescue => e
|
178
190
|
res.close if res
|
@@ -187,20 +199,20 @@ class Baza::Driver::Mysql
|
|
187
199
|
end
|
188
200
|
rescue => e
|
189
201
|
if tries <= 3
|
190
|
-
if e.message == "MySQL server has gone away"
|
202
|
+
if e.message == "MySQL server has gone away" || e.message == "closed MySQL connection" or e.message == "Can't connect to local MySQL server through socket"
|
191
203
|
sleep 0.5
|
192
|
-
|
204
|
+
reconnect
|
193
205
|
retry
|
194
206
|
elsif e.message.include?("No operations allowed after connection closed") or e.message == "This connection is still waiting for a result, try again once you have the result" or e.message == "Lock wait timeout exceeded; try restarting transaction"
|
195
|
-
|
207
|
+
reconnect
|
196
208
|
retry
|
197
209
|
end
|
198
210
|
end
|
199
|
-
|
211
|
+
|
200
212
|
raise e
|
201
213
|
end
|
202
214
|
end
|
203
|
-
|
215
|
+
|
204
216
|
#Executes an unbuffered query and returns the result that can be used to access the data.
|
205
217
|
def query_ubuf(str)
|
206
218
|
@mutex.synchronize do
|
@@ -213,26 +225,26 @@ class Baza::Driver::Mysql
|
|
213
225
|
when :java
|
214
226
|
if str.match(/^\s*(delete|update|create|drop|insert\s+into)\s+/i)
|
215
227
|
stmt = @conn.createStatement
|
216
|
-
|
228
|
+
|
217
229
|
begin
|
218
230
|
stmt.execute(str)
|
219
231
|
ensure
|
220
232
|
stmt.close
|
221
233
|
end
|
222
|
-
|
234
|
+
|
223
235
|
return nil
|
224
236
|
else
|
225
237
|
stmt = @conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY)
|
226
238
|
stmt.setFetchSize(java.lang.Integer::MIN_VALUE)
|
227
|
-
|
239
|
+
|
228
240
|
begin
|
229
241
|
res = stmt.executeQuery(str)
|
230
242
|
ret = Baza::Driver::Mysql::ResultJava.new(@baza_db, @opts, res)
|
231
|
-
|
243
|
+
|
232
244
|
#Save reference to result and statement, so we can close them when they are garbage collected.
|
233
|
-
@java_rs_data[ret.__id__] = {:
|
234
|
-
ObjectSpace.define_finalizer(ret,
|
235
|
-
|
245
|
+
@java_rs_data[ret.__id__] = {res: res, stmt: stmt}
|
246
|
+
ObjectSpace.define_finalizer(ret, method("java_mysql_resultset_killer"))
|
247
|
+
|
236
248
|
return ret
|
237
249
|
rescue => e
|
238
250
|
res.close if res
|
@@ -245,7 +257,7 @@ class Baza::Driver::Mysql
|
|
245
257
|
end
|
246
258
|
end
|
247
259
|
end
|
248
|
-
|
260
|
+
|
249
261
|
#Escapes a string to be safe to use in a query.
|
250
262
|
def escape_alternative(string)
|
251
263
|
case @subtype
|
@@ -254,12 +266,12 @@ class Baza::Driver::Mysql
|
|
254
266
|
when :mysql2
|
255
267
|
return @conn.escape(string.to_s)
|
256
268
|
when :java
|
257
|
-
return
|
269
|
+
return escape(string)
|
258
270
|
else
|
259
271
|
raise "Unknown subtype: '#{@subtype}'."
|
260
272
|
end
|
261
273
|
end
|
262
|
-
|
274
|
+
|
263
275
|
#An alternative to the MySQL framework's escape. This is copied from the Ruby/MySQL framework at: http://www.tmtm.org/en/ruby/mysql/
|
264
276
|
def escape(string)
|
265
277
|
return string.to_s.gsub(/([\0\n\r\032\'\"\\])/) do
|
@@ -272,19 +284,19 @@ class Baza::Driver::Mysql
|
|
272
284
|
end
|
273
285
|
end
|
274
286
|
end
|
275
|
-
|
287
|
+
|
276
288
|
#Escapes a string to be safe to use as a column in a query.
|
277
289
|
def esc_col(string)
|
278
290
|
string = string.to_s
|
279
291
|
raise "Invalid column-string: #{string}" if string.include?(@sep_col)
|
280
292
|
return string
|
281
293
|
end
|
282
|
-
|
294
|
+
|
283
295
|
alias :esc_table :esc_col
|
284
296
|
alias :esc :escape
|
285
|
-
|
297
|
+
|
286
298
|
#Returns the last inserted ID for the connection.
|
287
|
-
def
|
299
|
+
def last_id
|
288
300
|
case @subtype
|
289
301
|
when :mysql
|
290
302
|
@mutex.synchronize do
|
@@ -300,14 +312,14 @@ class Baza::Driver::Mysql
|
|
300
312
|
raise "Could not figure out last inserted ID."
|
301
313
|
end
|
302
314
|
end
|
303
|
-
|
315
|
+
|
304
316
|
#Closes the connection threadsafe.
|
305
317
|
def close
|
306
318
|
@mutex.synchronize do
|
307
319
|
@conn.close
|
308
320
|
end
|
309
321
|
end
|
310
|
-
|
322
|
+
|
311
323
|
#Destroyes the connection.
|
312
324
|
def destroy
|
313
325
|
@conn = nil
|
@@ -318,28 +330,28 @@ class Baza::Driver::Mysql
|
|
318
330
|
@query_args = nil
|
319
331
|
@port = nil
|
320
332
|
end
|
321
|
-
|
333
|
+
|
322
334
|
#Inserts multiple rows in a table. Can return the inserted IDs if asked to in arguments.
|
323
335
|
def insert_multi(tablename, arr_hashes, args = nil)
|
324
336
|
sql = "INSERT INTO `#{tablename}` ("
|
325
|
-
|
337
|
+
|
326
338
|
first = true
|
327
|
-
if args
|
339
|
+
if args && args[:keys]
|
328
340
|
keys = args[:keys]
|
329
341
|
elsif arr_hashes.first.is_a?(Hash)
|
330
342
|
keys = arr_hashes.first.keys
|
331
343
|
else
|
332
344
|
raise "Could not figure out keys."
|
333
345
|
end
|
334
|
-
|
346
|
+
|
335
347
|
keys.each do |col_name|
|
336
|
-
sql << ","
|
348
|
+
sql << "," unless first
|
337
349
|
first = false if first
|
338
350
|
sql << "`#{self.esc_col(col_name)}`"
|
339
351
|
end
|
340
|
-
|
352
|
+
|
341
353
|
sql << ") VALUES ("
|
342
|
-
|
354
|
+
|
343
355
|
first = true
|
344
356
|
arr_hashes.each do |hash|
|
345
357
|
if first
|
@@ -347,7 +359,7 @@ class Baza::Driver::Mysql
|
|
347
359
|
else
|
348
360
|
sql << "),("
|
349
361
|
end
|
350
|
-
|
362
|
+
|
351
363
|
first_key = true
|
352
364
|
if hash.is_a?(Array)
|
353
365
|
hash.each do |val|
|
@@ -356,7 +368,7 @@ class Baza::Driver::Mysql
|
|
356
368
|
else
|
357
369
|
sql << ","
|
358
370
|
end
|
359
|
-
|
371
|
+
|
360
372
|
sql << @baza_db.sqlval(val)
|
361
373
|
end
|
362
374
|
else
|
@@ -366,42 +378,42 @@ class Baza::Driver::Mysql
|
|
366
378
|
else
|
367
379
|
sql << ","
|
368
380
|
end
|
369
|
-
|
381
|
+
|
370
382
|
sql << @baza_db.sqlval(val)
|
371
383
|
end
|
372
384
|
end
|
373
385
|
end
|
374
|
-
|
386
|
+
|
375
387
|
sql << ")"
|
376
|
-
|
377
|
-
return sql if args
|
378
|
-
|
388
|
+
|
389
|
+
return sql if args && args[:return_sql]
|
390
|
+
|
379
391
|
self.query(sql)
|
380
|
-
|
381
|
-
if args
|
382
|
-
first_id = self.
|
392
|
+
|
393
|
+
if args && args[:return_id]
|
394
|
+
first_id = self.last_id
|
383
395
|
raise "Invalid ID: #{first_id}" if first_id.to_i <= 0
|
384
396
|
ids = [first_id]
|
385
397
|
1.upto(arr_hashes.length - 1) do |count|
|
386
398
|
ids << first_id + count
|
387
399
|
end
|
388
|
-
|
400
|
+
|
389
401
|
ids_length = ids.length
|
390
402
|
arr_hashes_length = arr_hashes.length
|
391
403
|
raise "Invalid length (#{ids_length}, #{arr_hashes_length})." if ids_length != arr_hashes_length
|
392
|
-
|
404
|
+
|
393
405
|
return ids
|
394
406
|
else
|
395
407
|
return nil
|
396
408
|
end
|
397
409
|
end
|
398
|
-
|
410
|
+
|
399
411
|
#Starts a transaction, yields the database and commits at the end.
|
400
412
|
def transaction
|
401
413
|
@baza_db.q("START TRANSACTION")
|
402
|
-
|
414
|
+
|
403
415
|
begin
|
404
|
-
yield
|
416
|
+
yield @baza_db
|
405
417
|
@baza_db.q("COMMIT")
|
406
418
|
rescue
|
407
419
|
@baza_db.q("ROLLBACK")
|
@@ -409,208 +421,3 @@ class Baza::Driver::Mysql
|
|
409
421
|
end
|
410
422
|
end
|
411
423
|
end
|
412
|
-
|
413
|
-
#This class controls the results for the normal MySQL-driver.
|
414
|
-
class Baza::Driver::Mysql::Result
|
415
|
-
#Constructor. This should not be called manually.
|
416
|
-
def initialize(driver, result)
|
417
|
-
@driver = driver
|
418
|
-
@result = result
|
419
|
-
@mutex = Mutex.new
|
420
|
-
|
421
|
-
if @result
|
422
|
-
@keys = []
|
423
|
-
@result.fetch_fields.each do |key|
|
424
|
-
@keys << key.name.to_sym
|
425
|
-
end
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
#Returns a single result as a hash with symbols as keys.
|
430
|
-
def fetch
|
431
|
-
fetched = nil
|
432
|
-
@mutex.synchronize do
|
433
|
-
fetched = @result.fetch_row
|
434
|
-
end
|
435
|
-
|
436
|
-
return false if !fetched
|
437
|
-
|
438
|
-
ret = {}
|
439
|
-
count = 0
|
440
|
-
@keys.each do |key|
|
441
|
-
ret[key] = fetched[count]
|
442
|
-
count += 1
|
443
|
-
end
|
444
|
-
|
445
|
-
return ret
|
446
|
-
end
|
447
|
-
|
448
|
-
#Loops over every result yielding it.
|
449
|
-
def each
|
450
|
-
while data = self.fetch
|
451
|
-
yield(data)
|
452
|
-
end
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
|
-
#This class controls the unbuffered result for the normal MySQL-driver.
|
457
|
-
class Baza::Driver::Mysql::ResultUnbuffered
|
458
|
-
#Constructor. This should not be called manually.
|
459
|
-
def initialize(conn, opts, result)
|
460
|
-
@conn = conn
|
461
|
-
@result = result
|
462
|
-
|
463
|
-
if !opts.key?(:result) or opts[:result] == "hash"
|
464
|
-
@as_hash = true
|
465
|
-
elsif opts[:result] == "array"
|
466
|
-
@as_hash = false
|
467
|
-
else
|
468
|
-
raise "Unknown type of result: '#{opts[:result]}'."
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
|
-
#Lods the keys for the object.
|
473
|
-
def load_keys
|
474
|
-
@keys = []
|
475
|
-
keys = @res.fetch_fields
|
476
|
-
keys.each do |key|
|
477
|
-
@keys << key.name.to_sym
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
#Returns a single result.
|
482
|
-
def fetch
|
483
|
-
if @enum
|
484
|
-
begin
|
485
|
-
ret = @enum.next
|
486
|
-
rescue StopIteration
|
487
|
-
@enum = nil
|
488
|
-
@res = nil
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
if !ret and !@res and !@enum
|
493
|
-
begin
|
494
|
-
@res = @conn.use_result
|
495
|
-
@enum = @res.to_enum
|
496
|
-
ret = @enum.next
|
497
|
-
rescue Mysql::Error
|
498
|
-
#Reset it to run non-unbuffered again and then return false.
|
499
|
-
@conn.query_with_result = true
|
500
|
-
return false
|
501
|
-
rescue StopIteration
|
502
|
-
sleep 0.1
|
503
|
-
retry
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
if !@as_hash
|
508
|
-
return ret
|
509
|
-
else
|
510
|
-
self.load_keys if !@keys
|
511
|
-
|
512
|
-
ret_h = {}
|
513
|
-
@keys.each_index do |key_no|
|
514
|
-
ret_h[@keys[key_no]] = ret[key_no]
|
515
|
-
end
|
516
|
-
|
517
|
-
return ret_h
|
518
|
-
end
|
519
|
-
end
|
520
|
-
|
521
|
-
#Loops over every single result yielding it.
|
522
|
-
def each
|
523
|
-
while data = self.fetch
|
524
|
-
yield(data)
|
525
|
-
end
|
526
|
-
end
|
527
|
-
end
|
528
|
-
|
529
|
-
#This class controls the result for the MySQL2 driver.
|
530
|
-
class Baza::Driver::Mysql::ResultMySQL2
|
531
|
-
#Constructor. This should not be called manually.
|
532
|
-
def initialize(result)
|
533
|
-
@result = result
|
534
|
-
end
|
535
|
-
|
536
|
-
#Returns a single result.
|
537
|
-
def fetch
|
538
|
-
@enum = @result.to_enum if !@enum
|
539
|
-
|
540
|
-
begin
|
541
|
-
return @enum.next
|
542
|
-
rescue StopIteration
|
543
|
-
return false
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
#Loops over every single result yielding it.
|
548
|
-
def each
|
549
|
-
@result.each do |res|
|
550
|
-
next if !res #This sometimes happens when streaming results...
|
551
|
-
yield(res)
|
552
|
-
end
|
553
|
-
end
|
554
|
-
end
|
555
|
-
|
556
|
-
#This class controls the result for the Java-MySQL-driver.
|
557
|
-
class Baza::Driver::Mysql::ResultJava
|
558
|
-
#Constructor. This should not be called manually.
|
559
|
-
def initialize(knjdb, opts, result)
|
560
|
-
@baza_db = knjdb
|
561
|
-
@result = result
|
562
|
-
|
563
|
-
if !opts.key?(:result) or opts[:result] == "hash"
|
564
|
-
@as_hash = true
|
565
|
-
elsif opts[:result] == "array"
|
566
|
-
@as_hash = false
|
567
|
-
else
|
568
|
-
raise "Unknown type of result: '#{opts[:result]}'."
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
#Reads meta-data about the query like keys and count.
|
573
|
-
def read_meta
|
574
|
-
@result.before_first
|
575
|
-
meta = @result.meta_data
|
576
|
-
@count = meta.column_count
|
577
|
-
|
578
|
-
@keys = []
|
579
|
-
1.upto(@count) do |count|
|
580
|
-
@keys << meta.column_label(count).to_sym
|
581
|
-
end
|
582
|
-
end
|
583
|
-
|
584
|
-
def fetch
|
585
|
-
return false if !@result
|
586
|
-
self.read_meta if !@keys
|
587
|
-
status = @result.next
|
588
|
-
|
589
|
-
if !status
|
590
|
-
@result = nil
|
591
|
-
@keys = nil
|
592
|
-
@count = nil
|
593
|
-
return false
|
594
|
-
end
|
595
|
-
|
596
|
-
if @as_hash
|
597
|
-
ret = {}
|
598
|
-
1.upto(@count) do |count|
|
599
|
-
ret[@keys[count - 1]] = @result.object(count)
|
600
|
-
end
|
601
|
-
else
|
602
|
-
ret = []
|
603
|
-
1.upto(@count) do |count|
|
604
|
-
ret << @result.object(count)
|
605
|
-
end
|
606
|
-
end
|
607
|
-
|
608
|
-
return ret
|
609
|
-
end
|
610
|
-
|
611
|
-
def each
|
612
|
-
while data = self.fetch
|
613
|
-
yield(data)
|
614
|
-
end
|
615
|
-
end
|
616
|
-
end
|