knjrbfw 0.0.110 → 0.0.111

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