baza 0.0.0 → 0.0.1
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.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.rdoc +106 -1
- data/VERSION +1 -1
- data/baza.gemspec +103 -0
- data/include/db.rb +108 -29
- data/include/drivers/mysql/mysql.rb +52 -47
- data/include/drivers/mysql/mysql_columns.rb +48 -41
- data/include/drivers/mysql/mysql_indexes.rb +2 -2
- data/include/drivers/mysql/mysql_tables.rb +91 -59
- data/include/drivers/sqlite3/sqlite3.rb +66 -45
- data/include/drivers/sqlite3/sqlite3_columns.rb +41 -39
- data/include/drivers/sqlite3/sqlite3_indexes.rb +2 -2
- data/include/drivers/sqlite3/sqlite3_tables.rb +86 -54
- data/include/dump.rb +5 -2
- data/include/revision.rb +130 -90
- data/spec/baza_spec.rb +312 -263
- data/spec/info_mysql_example.rb +6 -0
- data/spec/info_sqlite3.rb +20 -0
- metadata +22 -3
@@ -2,6 +2,22 @@ class Baza::Driver::Mysql
|
|
2
2
|
attr_reader :knjdb, :conn, :conns, :sep_table, :sep_col, :sep_val
|
3
3
|
attr_accessor :tables, :cols, :indexes
|
4
4
|
|
5
|
+
#Helper to enable automatic registering of database using Baza::Db.from_object
|
6
|
+
def self.from_object(args)
|
7
|
+
if args[:object].class.name == "Mysql2::Client"
|
8
|
+
return {
|
9
|
+
:type => :success,
|
10
|
+
:args => {
|
11
|
+
:type => :mysql,
|
12
|
+
:subtype => :mysql2,
|
13
|
+
:conn => args[:object]
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
5
21
|
def initialize(knjdb_ob)
|
6
22
|
@knjdb = knjdb_ob
|
7
23
|
@opts = @knjdb.opts
|
@@ -26,7 +42,7 @@ class Baza::Driver::Mysql
|
|
26
42
|
|
27
43
|
@java_rs_data = {}
|
28
44
|
@subtype = @knjdb.opts[:subtype]
|
29
|
-
@subtype =
|
45
|
+
@subtype = :mysql if @subtype.to_s.empty?
|
30
46
|
self.reconnect
|
31
47
|
end
|
32
48
|
|
@@ -49,9 +65,9 @@ class Baza::Driver::Mysql
|
|
49
65
|
def reconnect
|
50
66
|
@mutex.synchronize do
|
51
67
|
case @subtype
|
52
|
-
when
|
68
|
+
when :mysql
|
53
69
|
@conn = Mysql.real_connect(@knjdb.opts[:host], @knjdb.opts[:user], @knjdb.opts[:pass], @knjdb.opts[:db], @port)
|
54
|
-
when
|
70
|
+
when :mysql2
|
55
71
|
require "rubygems"
|
56
72
|
require "mysql2"
|
57
73
|
|
@@ -79,7 +95,11 @@ class Baza::Driver::Mysql
|
|
79
95
|
tries = 0
|
80
96
|
begin
|
81
97
|
tries += 1
|
82
|
-
@conn
|
98
|
+
if @knjdb.opts[:conn]
|
99
|
+
@conn = @knjdb.opts[:conn]
|
100
|
+
else
|
101
|
+
@conn = Mysql2::Client.new(args)
|
102
|
+
end
|
83
103
|
rescue => e
|
84
104
|
if tries <= 3
|
85
105
|
if e.message == "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)"
|
@@ -90,7 +110,7 @@ class Baza::Driver::Mysql
|
|
90
110
|
|
91
111
|
raise e
|
92
112
|
end
|
93
|
-
when
|
113
|
+
when :java
|
94
114
|
if !@jdbc_loaded
|
95
115
|
require "java"
|
96
116
|
require "/usr/share/java/mysql-connector-java.jar" if File.exists?("/usr/share/java/mysql-connector-java.jar")
|
@@ -101,7 +121,7 @@ class Baza::Driver::Mysql
|
|
101
121
|
@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
122
|
self.query("SET SQL_MODE = ''")
|
103
123
|
else
|
104
|
-
raise "Unknown subtype: #{@subtype}"
|
124
|
+
raise "Unknown subtype: #{@subtype} (#{@subtype.class.name})"
|
105
125
|
end
|
106
126
|
|
107
127
|
self.query("SET NAMES '#{self.esc(@encoding)}'") if @encoding
|
@@ -118,11 +138,11 @@ class Baza::Driver::Mysql
|
|
118
138
|
tries += 1
|
119
139
|
@mutex.synchronize do
|
120
140
|
case @subtype
|
121
|
-
when
|
122
|
-
return Baza::Driver::
|
123
|
-
when
|
124
|
-
return Baza::Driver::
|
125
|
-
when
|
141
|
+
when :mysql
|
142
|
+
return Baza::Driver::Mysql::Result.new(self, @conn.query(str))
|
143
|
+
when :mysql2
|
144
|
+
return Baza::Driver::Mysql::ResultMySQL2.new(@conn.query(str, @query_args))
|
145
|
+
when :java
|
126
146
|
stmt = conn.create_statement
|
127
147
|
|
128
148
|
if str.match(/^\s*(delete|update|create|drop|insert\s+into|alter)\s+/i)
|
@@ -138,7 +158,7 @@ class Baza::Driver::Mysql
|
|
138
158
|
|
139
159
|
begin
|
140
160
|
res = stmt.execute_query(str)
|
141
|
-
ret =
|
161
|
+
ret = Baza::Driver::Mysql::ResultJava.new(@knjdb, @opts, res)
|
142
162
|
id = ret.__id__
|
143
163
|
|
144
164
|
#If ID is being reused we have to free the result.
|
@@ -180,12 +200,12 @@ class Baza::Driver::Mysql
|
|
180
200
|
def query_ubuf(str)
|
181
201
|
@mutex.synchronize do
|
182
202
|
case @subtype
|
183
|
-
when
|
203
|
+
when :mysql
|
184
204
|
@conn.query_with_result = false
|
185
|
-
return Baza::Driver::
|
186
|
-
when
|
187
|
-
return Baza::Driver::
|
188
|
-
when
|
205
|
+
return Baza::Driver::Mysql::ResultUnbuffered.new(@conn, @opts, @conn.query(str))
|
206
|
+
when :mysql2
|
207
|
+
return Baza::Driver::Mysql::ResultMySQL2.new(@conn.query(str, @query_args.merge(:stream => true)))
|
208
|
+
when :java
|
189
209
|
if str.match(/^\s*(delete|update|create|drop|insert\s+into)\s+/i)
|
190
210
|
stmt = @conn.createStatement
|
191
211
|
|
@@ -202,7 +222,7 @@ class Baza::Driver::Mysql
|
|
202
222
|
|
203
223
|
begin
|
204
224
|
res = stmt.executeQuery(str)
|
205
|
-
ret =
|
225
|
+
ret = Baza::Driver::Mysql::ResultJava.new(@knjdb, @opts, res)
|
206
226
|
|
207
227
|
#Save reference to result and statement, so we can close them when they are garbage collected.
|
208
228
|
@java_rs_data[ret.__id__] = {:res => res, :stmt => stmt}
|
@@ -224,11 +244,11 @@ class Baza::Driver::Mysql
|
|
224
244
|
#Escapes a string to be safe to use in a query.
|
225
245
|
def escape_alternative(string)
|
226
246
|
case @subtype
|
227
|
-
when
|
247
|
+
when :mysql
|
228
248
|
return @conn.escape_string(string.to_s)
|
229
|
-
when
|
249
|
+
when :mysql2
|
230
250
|
return @conn.escape(string.to_s)
|
231
|
-
when
|
251
|
+
when :java
|
232
252
|
return self.escape(string)
|
233
253
|
else
|
234
254
|
raise "Unknown subtype: '#{@subtype}'."
|
@@ -261,15 +281,15 @@ class Baza::Driver::Mysql
|
|
261
281
|
#Returns the last inserted ID for the connection.
|
262
282
|
def lastID
|
263
283
|
case @subtype
|
264
|
-
when
|
284
|
+
when :mysql
|
265
285
|
@mutex.synchronize do
|
266
286
|
return @conn.insert_id.to_i
|
267
287
|
end
|
268
|
-
when
|
288
|
+
when :mysql2
|
269
289
|
@mutex.synchronize do
|
270
290
|
return @conn.last_id.to_i
|
271
291
|
end
|
272
|
-
when
|
292
|
+
when :java
|
273
293
|
data = self.query("SELECT LAST_INSERT_ID() AS id").fetch
|
274
294
|
return data[:id].to_i if data.key?(:id)
|
275
295
|
raise "Could not figure out last inserted ID."
|
@@ -384,7 +404,7 @@ class Baza::Driver::Mysql
|
|
384
404
|
end
|
385
405
|
|
386
406
|
#This class controls the results for the normal MySQL-driver.
|
387
|
-
class Baza::Driver::
|
407
|
+
class Baza::Driver::Mysql::Result
|
388
408
|
#Constructor. This should not be called manually.
|
389
409
|
def initialize(driver, result)
|
390
410
|
@driver = driver
|
@@ -393,28 +413,14 @@ class Baza::Driver::Mysql_result
|
|
393
413
|
|
394
414
|
if @result
|
395
415
|
@keys = []
|
396
|
-
|
397
|
-
keys.each do |key|
|
416
|
+
@result.fetch_fields.each do |key|
|
398
417
|
@keys << key.name.to_sym
|
399
418
|
end
|
400
419
|
end
|
401
420
|
end
|
402
421
|
|
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
422
|
#Returns a single result as a hash with symbols as keys.
|
417
|
-
def
|
423
|
+
def fetch
|
418
424
|
fetched = nil
|
419
425
|
@mutex.synchronize do
|
420
426
|
fetched = @result.fetch_row
|
@@ -434,14 +440,14 @@ class Baza::Driver::Mysql_result
|
|
434
440
|
|
435
441
|
#Loops over every result yielding it.
|
436
442
|
def each
|
437
|
-
while data = self.
|
443
|
+
while data = self.fetch
|
438
444
|
yield(data)
|
439
445
|
end
|
440
446
|
end
|
441
447
|
end
|
442
448
|
|
443
449
|
#This class controls the unbuffered result for the normal MySQL-driver.
|
444
|
-
class Baza::Driver::
|
450
|
+
class Baza::Driver::Mysql::ResultUnbuffered
|
445
451
|
#Constructor. This should not be called manually.
|
446
452
|
def initialize(conn, opts, result)
|
447
453
|
@conn = conn
|
@@ -514,7 +520,7 @@ class Baza::Driver::Mysql_unbuffered_result
|
|
514
520
|
end
|
515
521
|
|
516
522
|
#This class controls the result for the MySQL2 driver.
|
517
|
-
class Baza::Driver::
|
523
|
+
class Baza::Driver::Mysql::ResultMySQL2
|
518
524
|
#Constructor. This should not be called manually.
|
519
525
|
def initialize(result)
|
520
526
|
@result = result
|
@@ -534,15 +540,14 @@ class Baza::Driver::Mysql2_result
|
|
534
540
|
#Loops over every single result yielding it.
|
535
541
|
def each
|
536
542
|
@result.each do |res|
|
537
|
-
#This sometimes happens when streaming results...
|
538
|
-
next if !res
|
543
|
+
next if !res #This sometimes happens when streaming results...
|
539
544
|
yield(res)
|
540
545
|
end
|
541
546
|
end
|
542
547
|
end
|
543
548
|
|
544
549
|
#This class controls the result for the Java-MySQL-driver.
|
545
|
-
class
|
550
|
+
class Baza::Driver::Mysql::ResultJava
|
546
551
|
#Constructor. This should not be called manually.
|
547
552
|
def initialize(knjdb, opts, result)
|
548
553
|
@knjdb = knjdb
|
@@ -6,27 +6,33 @@ class Baza::Driver::Mysql::Columns
|
|
6
6
|
end
|
7
7
|
|
8
8
|
#Returns the SQL for this column.
|
9
|
+
DATA_SQL_ALLOWED_KEYS = [:type, :maxlength, :name, :primarykey, :autoincr, :default, :comment, :after, :first, :storage, :null]
|
9
10
|
def data_sql(data)
|
10
|
-
|
11
|
+
data.each do |key, val|
|
12
|
+
raise "Invalid key: '#{key}' (#{key.class.name})." if !DATA_SQL_ALLOWED_KEYS.include?(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
raise "No type given." if !data[:type]
|
16
|
+
type = data[:type].to_sym
|
11
17
|
|
12
|
-
data[
|
18
|
+
data[:maxlength] = 255 if type == :varchar and !data.key?(:maxlength)
|
13
19
|
|
14
|
-
sql = "`#{data[
|
15
|
-
sql << "(#{data[
|
16
|
-
sql << " PRIMARY KEY" if data[
|
17
|
-
sql << " AUTO_INCREMENT" if data[
|
18
|
-
sql << " NOT NULL" if !data[
|
20
|
+
sql = "`#{data[:name]}` #{type}"
|
21
|
+
sql << "(#{data[:maxlength]})" if data[:maxlength]
|
22
|
+
sql << " PRIMARY KEY" if data[:primarykey]
|
23
|
+
sql << " AUTO_INCREMENT" if data[:autoincr]
|
24
|
+
sql << " NOT NULL" if !data[:null]
|
19
25
|
|
20
|
-
if data.key?(
|
21
|
-
sql << " DEFAULT #{data[
|
22
|
-
elsif data.key?(
|
23
|
-
sql << " DEFAULT '#{@args[:db].escape(data[
|
26
|
+
if data.key?(:default_func)
|
27
|
+
sql << " DEFAULT #{data[:default_func]}"
|
28
|
+
elsif data.key?(:default) and data[:default] != false
|
29
|
+
sql << " DEFAULT '#{@args[:db].escape(data[:default])}'"
|
24
30
|
end
|
25
31
|
|
26
|
-
sql << " COMMENT '#{@args[:db].escape(data[
|
27
|
-
sql << " AFTER `#{@args[:db].esc_col(data[
|
28
|
-
sql << " FIRST" if data[
|
29
|
-
sql << " STORAGE #{data[
|
32
|
+
sql << " COMMENT '#{@args[:db].escape(data[:comment])}'" if data.key?(:comment)
|
33
|
+
sql << " AFTER `#{@args[:db].esc_col(data[:after])}`" if data[:after] and !data[:first]
|
34
|
+
sql << " FIRST" if data[:first]
|
35
|
+
sql << " STORAGE #{data[:storage].to_s.upcase}" if data[:storage]
|
30
36
|
|
31
37
|
return sql
|
32
38
|
end
|
@@ -34,21 +40,18 @@ end
|
|
34
40
|
|
35
41
|
#This class handels every MySQL-column, that can be returned from a table-object.
|
36
42
|
class Baza::Driver::Mysql::Columns::Column
|
37
|
-
attr_reader :args
|
43
|
+
attr_reader :args, :name
|
38
44
|
|
39
45
|
#Constructor. Should not be called manually.
|
40
46
|
def initialize(args)
|
41
47
|
@args = args
|
48
|
+
@name = @args[:data][:Field].to_sym
|
49
|
+
@db = @args[:db]
|
42
50
|
end
|
43
51
|
|
44
52
|
#Used to validate in Knj::Wrap_map.
|
45
53
|
def __object_unique_id__
|
46
|
-
return @
|
47
|
-
end
|
48
|
-
|
49
|
-
#Returns the name of the column.
|
50
|
-
def name
|
51
|
-
return @args[:data][:Field]
|
54
|
+
return @name
|
52
55
|
end
|
53
56
|
|
54
57
|
#Returns the table-object that this column belongs to.
|
@@ -59,13 +62,13 @@ class Baza::Driver::Mysql::Columns::Column
|
|
59
62
|
#Returns all data of the column in the knjdb-format.
|
60
63
|
def data
|
61
64
|
return {
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
:type => self.type,
|
66
|
+
:name => self.name,
|
67
|
+
:null => self.null?,
|
68
|
+
:maxlength => self.maxlength,
|
69
|
+
:default => self.default,
|
70
|
+
:primarykey => self.primarykey?,
|
71
|
+
:autoincr => self.autoincr?
|
69
72
|
}
|
70
73
|
end
|
71
74
|
|
@@ -86,7 +89,7 @@ class Baza::Driver::Mysql::Columns::Column
|
|
86
89
|
@type = match[1].to_sym
|
87
90
|
end
|
88
91
|
|
89
|
-
raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.
|
92
|
+
raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.empty?
|
90
93
|
end
|
91
94
|
|
92
95
|
return @type
|
@@ -107,8 +110,8 @@ class Baza::Driver::Mysql::Columns::Column
|
|
107
110
|
|
108
111
|
#Returns the default value for the column.
|
109
112
|
def default
|
110
|
-
return false if (self.type ==
|
111
|
-
return false if (self.type ==
|
113
|
+
return false if (self.type == :datetime or self.type == :date) and @args[:data][:Default].to_s.strip.length <= 0
|
114
|
+
return false if (self.type == :int or self.type == :bigint) and @args[:data][:Default].to_s.strip.length <= 0
|
112
115
|
return false if !@args[:data][:Default]
|
113
116
|
return @args[:data][:Default]
|
114
117
|
end
|
@@ -121,7 +124,7 @@ class Baza::Driver::Mysql::Columns::Column
|
|
121
124
|
|
122
125
|
#Returns true if the column is auto-increasing. Otherwise false.
|
123
126
|
def autoincr?
|
124
|
-
return true if @args[:data][:Extra].
|
127
|
+
return true if @args[:data][:Extra].include?("auto_increment")
|
125
128
|
return false
|
126
129
|
end
|
127
130
|
|
@@ -132,7 +135,8 @@ class Baza::Driver::Mysql::Columns::Column
|
|
132
135
|
|
133
136
|
#Drops the column from the table.
|
134
137
|
def drop
|
135
|
-
@args[:db].query("ALTER TABLE `#{@args[:table_name]}` DROP COLUMN `#{self.name}`")
|
138
|
+
@args[:db].query("ALTER TABLE `#{@db.esc_table(@args[:table_name])}` DROP COLUMN `#{@db.esc_col(self.name)}`")
|
139
|
+
table = self.table.remove_column_from_list(self)
|
136
140
|
return nil
|
137
141
|
end
|
138
142
|
|
@@ -142,14 +146,17 @@ class Baza::Driver::Mysql::Columns::Column
|
|
142
146
|
table_escape = "`#{@args[:db].esc_table(self.table.name)}`"
|
143
147
|
newdata = data.clone
|
144
148
|
|
145
|
-
newdata[
|
146
|
-
newdata[
|
147
|
-
newdata[
|
148
|
-
newdata[
|
149
|
-
newdata[
|
150
|
-
newdata.delete(
|
149
|
+
newdata[:name] = self.name if !newdata.key?(:name)
|
150
|
+
newdata[:type] = self.type if !newdata.key?(:type)
|
151
|
+
newdata[:maxlength] = self.maxlength if !newdata.key?(:maxlength) and self.maxlength
|
152
|
+
newdata[:null] = self.null? if !newdata.key?(:null)
|
153
|
+
newdata[:default] = self.default if !newdata.key?(:default) and self.default
|
154
|
+
newdata.delete(:primarykey) if newdata.key?(:primarykey)
|
155
|
+
|
156
|
+
drop_add = true if self.name.to_s != newdata[:name].to_s
|
151
157
|
|
152
|
-
|
158
|
+
self.table.__send__(:remove_column_from_list, self) if drop_add
|
153
159
|
@args[:db].query("ALTER TABLE #{table_escape} CHANGE #{col_escaped} #{@args[:db].cols.data_sql(newdata)}")
|
160
|
+
self.table.__send__(:add_column_to_list, self) if drop_add
|
154
161
|
end
|
155
162
|
end
|