baza 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,133 @@
|
|
1
|
+
#This class handels every MySQL-column, that can be returned from a table-object.
|
2
|
+
class Baza::Driver::Mysql::Column
|
3
|
+
attr_reader :args, :name
|
4
|
+
|
5
|
+
#Constructor. Should not be called manually.
|
6
|
+
def initialize(args)
|
7
|
+
@args = args
|
8
|
+
@name = @args[:data][:Field].to_sym
|
9
|
+
@db = @args[:db]
|
10
|
+
end
|
11
|
+
|
12
|
+
#Used to validate in Knj::Wrap_map.
|
13
|
+
def __object_unique_id__
|
14
|
+
return @name
|
15
|
+
end
|
16
|
+
|
17
|
+
def table_name
|
18
|
+
@args[:table_name]
|
19
|
+
end
|
20
|
+
|
21
|
+
#Returns the table-object that this column belongs to.
|
22
|
+
def table
|
23
|
+
return @db.tables[table_name]
|
24
|
+
end
|
25
|
+
|
26
|
+
#Returns all data of the column in the knjdb-format.
|
27
|
+
def data
|
28
|
+
return {
|
29
|
+
type: type,
|
30
|
+
name: name,
|
31
|
+
null: null?,
|
32
|
+
maxlength: maxlength,
|
33
|
+
default: default,
|
34
|
+
primarykey: primarykey?,
|
35
|
+
autoincr: autoincr?
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def reload
|
40
|
+
@args[:data] = @db.query("SHOW FULL COLUMNS FROM `#{@db.esc_table(table_name)}` WHERE `Field` = '#{@db.esc(name)}'").fetch
|
41
|
+
@type = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
#Returns the type of the column (integer, varchar etc.).
|
45
|
+
def type
|
46
|
+
if !@type
|
47
|
+
if match = @args[:data][:Type].match(/^([A-z]+)$/)
|
48
|
+
@maxlength = false
|
49
|
+
@type = match[0].to_sym
|
50
|
+
elsif match = @args[:data][:Type].match(/^decimal\((\d+),(\d+)\)$/)
|
51
|
+
@maxlength = "#{match[1]},#{match[2]}"
|
52
|
+
@type = :decimal
|
53
|
+
elsif match = @args[:data][:Type].match(/^enum\((.+)\)$/)
|
54
|
+
@maxlength = match[1]
|
55
|
+
@type = :enum
|
56
|
+
elsif match = @args[:data][:Type].match(/^(.+)\((\d+)\)/)
|
57
|
+
@maxlength = match[2].to_i
|
58
|
+
@type = match[1].to_sym
|
59
|
+
end
|
60
|
+
|
61
|
+
raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.empty?
|
62
|
+
end
|
63
|
+
|
64
|
+
return @type
|
65
|
+
end
|
66
|
+
|
67
|
+
#Return true if the columns allows null. Otherwise false.
|
68
|
+
def null?
|
69
|
+
return false if @args[:data][:Null] == "NO"
|
70
|
+
return true
|
71
|
+
end
|
72
|
+
|
73
|
+
#Returns the maxlength.
|
74
|
+
def maxlength
|
75
|
+
self.type unless @maxlength
|
76
|
+
return @maxlength if @maxlength
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
#Returns the default value for the column.
|
81
|
+
def default
|
82
|
+
return false if (self.type == :datetime || self.type == :date) && @args[:data][:Default].to_s.strip.empty?
|
83
|
+
return false if (self.type == :int || self.type == :bigint) && @args[:data][:Default].to_s.strip.empty?
|
84
|
+
return false if !@args[:data][:Default]
|
85
|
+
return @args[:data][:Default]
|
86
|
+
end
|
87
|
+
|
88
|
+
#Returns true if the column is the primary key. Otherwise false.
|
89
|
+
def primarykey?
|
90
|
+
return true if @args[:data][:Key] == "PRI"
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
|
94
|
+
#Returns true if the column is auto-increasing. Otherwise false.
|
95
|
+
def autoincr?
|
96
|
+
return true if @args[:data][:Extra].include?("auto_increment")
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
|
100
|
+
#Returns the comment for the column.
|
101
|
+
def comment
|
102
|
+
return @args[:data][:Comment]
|
103
|
+
end
|
104
|
+
|
105
|
+
#Drops the column from the table.
|
106
|
+
def drop
|
107
|
+
@args[:db].query("ALTER TABLE `#{@db.esc_table(@args[:table_name])}` DROP COLUMN `#{@db.esc_col(self.name)}`")
|
108
|
+
table.__send__(:remove_column_from_list, self)
|
109
|
+
return nil
|
110
|
+
end
|
111
|
+
|
112
|
+
#Changes the column properties by the given hash.
|
113
|
+
def change(data)
|
114
|
+
col_escaped = "`#{@db.esc_col(name)}`"
|
115
|
+
table_escape = "`#{@db.esc_table(table_name)}`"
|
116
|
+
newdata = data.clone
|
117
|
+
|
118
|
+
newdata[:name] = name unless newdata.key?(:name)
|
119
|
+
newdata[:type] = type unless newdata.key?(:type)
|
120
|
+
newdata[:maxlength] = maxlength if !newdata.key?(:maxlength) && maxlength
|
121
|
+
newdata[:null] = null? unless newdata.key?(:null)
|
122
|
+
newdata[:default] = self.default if !newdata.key?(:default) && default
|
123
|
+
newdata.delete(:primarykey) if newdata.key?(:primarykey)
|
124
|
+
|
125
|
+
drop_add = true if name.to_s != newdata[:name].to_s
|
126
|
+
|
127
|
+
table.__send__(:remove_column_from_list, self) if drop_add
|
128
|
+
@db.query("ALTER TABLE #{table_escape} CHANGE #{col_escaped} #{@args[:db].cols.data_sql(newdata)}")
|
129
|
+
@name = newdata[:name].to_sym
|
130
|
+
reload
|
131
|
+
table.__send__(:add_column_to_list, self) if drop_add
|
132
|
+
end
|
133
|
+
end
|
@@ -12,10 +12,10 @@ class Baza::Driver::Mysql::Columns
|
|
12
12
|
raise "Invalid key: '#{key}' (#{key.class.name})." if !DATA_SQL_ALLOWED_KEYS.include?(key)
|
13
13
|
end
|
14
14
|
|
15
|
-
raise "No type given."
|
15
|
+
raise "No type given." unless data[:type]
|
16
16
|
type = data[:type].to_sym
|
17
17
|
|
18
|
-
data[:maxlength] = 255 if type == :varchar
|
18
|
+
data[:maxlength] = 255 if type == :varchar && !data.key?(:maxlength)
|
19
19
|
|
20
20
|
sql = "`#{data[:name]}` #{type}"
|
21
21
|
sql << "(#{data[:maxlength]})" if data[:maxlength]
|
@@ -25,138 +25,15 @@ class Baza::Driver::Mysql::Columns
|
|
25
25
|
|
26
26
|
if data.key?(:default_func)
|
27
27
|
sql << " DEFAULT #{data[:default_func]}"
|
28
|
-
elsif data.key?(:default)
|
28
|
+
elsif data.key?(:default) && data[:default] != false
|
29
29
|
sql << " DEFAULT '#{@args[:db].escape(data[:default])}'"
|
30
30
|
end
|
31
31
|
|
32
32
|
sql << " COMMENT '#{@args[:db].escape(data[:comment])}'" if data.key?(:comment)
|
33
|
-
sql << " AFTER `#{@args[:db].esc_col(data[:after])}`" if data[:after]
|
33
|
+
sql << " AFTER `#{@args[:db].esc_col(data[:after])}`" if data[:after] && !data[:first]
|
34
34
|
sql << " FIRST" if data[:first]
|
35
35
|
sql << " STORAGE #{data[:storage].to_s.upcase}" if data[:storage]
|
36
36
|
|
37
37
|
return sql
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
41
|
-
#This class handels every MySQL-column, that can be returned from a table-object.
|
42
|
-
class Baza::Driver::Mysql::Columns::Column
|
43
|
-
attr_reader :args, :name
|
44
|
-
|
45
|
-
#Constructor. Should not be called manually.
|
46
|
-
def initialize(args)
|
47
|
-
@args = args
|
48
|
-
@name = @args[:data][:Field].to_sym
|
49
|
-
@db = @args[:db]
|
50
|
-
end
|
51
|
-
|
52
|
-
#Used to validate in Knj::Wrap_map.
|
53
|
-
def __object_unique_id__
|
54
|
-
return @name
|
55
|
-
end
|
56
|
-
|
57
|
-
#Returns the table-object that this column belongs to.
|
58
|
-
def table
|
59
|
-
return @args[:db].tables[@args[:table_name]]
|
60
|
-
end
|
61
|
-
|
62
|
-
#Returns all data of the column in the knjdb-format.
|
63
|
-
def data
|
64
|
-
return {
|
65
|
-
type: type,
|
66
|
-
name: name,
|
67
|
-
null: null?,
|
68
|
-
maxlength: maxlength,
|
69
|
-
default: default,
|
70
|
-
primarykey: primarykey?,
|
71
|
-
autoincr: autoincr?
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
|
-
#Returns the type of the column (integer, varchar etc.).
|
76
|
-
def type
|
77
|
-
if !@type
|
78
|
-
if match = @args[:data][:Type].match(/^([A-z]+)$/)
|
79
|
-
@maxlength = false
|
80
|
-
@type = match[0].to_sym
|
81
|
-
elsif match = @args[:data][:Type].match(/^decimal\((\d+),(\d+)\)$/)
|
82
|
-
@maxlength = "#{match[1]},#{match[2]}"
|
83
|
-
@type = :decimal
|
84
|
-
elsif match = @args[:data][:Type].match(/^enum\((.+)\)$/)
|
85
|
-
@maxlength = match[1]
|
86
|
-
@type = :enum
|
87
|
-
elsif match = @args[:data][:Type].match(/^(.+)\((\d+)\)/)
|
88
|
-
@maxlength = match[2].to_i
|
89
|
-
@type = match[1].to_sym
|
90
|
-
end
|
91
|
-
|
92
|
-
raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.empty?
|
93
|
-
end
|
94
|
-
|
95
|
-
return @type
|
96
|
-
end
|
97
|
-
|
98
|
-
#Return true if the columns allows null. Otherwise false.
|
99
|
-
def null?
|
100
|
-
return false if @args[:data][:Null] == "NO"
|
101
|
-
return true
|
102
|
-
end
|
103
|
-
|
104
|
-
#Returns the maxlength.
|
105
|
-
def maxlength
|
106
|
-
self.type if !@maxlength
|
107
|
-
return @maxlength if @maxlength
|
108
|
-
return false
|
109
|
-
end
|
110
|
-
|
111
|
-
#Returns the default value for the column.
|
112
|
-
def default
|
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
|
115
|
-
return false if !@args[:data][:Default]
|
116
|
-
return @args[:data][:Default]
|
117
|
-
end
|
118
|
-
|
119
|
-
#Returns true if the column is the primary key. Otherwise false.
|
120
|
-
def primarykey?
|
121
|
-
return true if @args[:data][:Key] == "PRI"
|
122
|
-
return false
|
123
|
-
end
|
124
|
-
|
125
|
-
#Returns true if the column is auto-increasing. Otherwise false.
|
126
|
-
def autoincr?
|
127
|
-
return true if @args[:data][:Extra].include?("auto_increment")
|
128
|
-
return false
|
129
|
-
end
|
130
|
-
|
131
|
-
#Returns the comment for the column.
|
132
|
-
def comment
|
133
|
-
return @args[:data][:Comment]
|
134
|
-
end
|
135
|
-
|
136
|
-
#Drops the column from the table.
|
137
|
-
def drop
|
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)
|
140
|
-
return nil
|
141
|
-
end
|
142
|
-
|
143
|
-
#Changes the column properties by the given hash.
|
144
|
-
def change(data)
|
145
|
-
col_escaped = "`#{@args[:db].esc_col(self.name)}`"
|
146
|
-
table_escape = "`#{@args[:db].esc_table(self.table.name)}`"
|
147
|
-
newdata = data.clone
|
148
|
-
|
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
|
157
|
-
|
158
|
-
self.table.__send__(:remove_column_from_list, self) if drop_add
|
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
|
161
|
-
end
|
162
|
-
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Baza::Driver::Mysql::Index
|
2
|
+
attr_reader :args, :columns
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@args = args
|
6
|
+
@columns = []
|
7
|
+
end
|
8
|
+
|
9
|
+
#Used to validate in Knj::Wrap_map.
|
10
|
+
def __object_unique_id__
|
11
|
+
return @args[:data][:Key_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
return @args[:data][:Key_name]
|
16
|
+
end
|
17
|
+
|
18
|
+
def table
|
19
|
+
return @args[:db].tables[@args[:table_name]]
|
20
|
+
end
|
21
|
+
|
22
|
+
def drop
|
23
|
+
sql = "DROP INDEX `#{self.name}` ON `#{self.table.name}`"
|
24
|
+
|
25
|
+
begin
|
26
|
+
@args[:db].query(sql)
|
27
|
+
rescue => e
|
28
|
+
#The index has already been dropped - ignore.
|
29
|
+
if e.message.index("check that column/key exists") != nil
|
30
|
+
#ignore.
|
31
|
+
else
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def rename newname
|
38
|
+
newname = newname.to_sym
|
39
|
+
create_args = data
|
40
|
+
create_args[:name] = newname
|
41
|
+
|
42
|
+
drop
|
43
|
+
table.create_indexes([create_args])
|
44
|
+
@args[:data][:Key_name] = newname
|
45
|
+
end
|
46
|
+
|
47
|
+
def data
|
48
|
+
return {
|
49
|
+
name: name,
|
50
|
+
columns: @columns
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
#Returns true if the index is a unique-index.
|
55
|
+
def unique?
|
56
|
+
if @args[:data][:Index_type] == "UNIQUE"
|
57
|
+
return true
|
58
|
+
else
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#Returns true if the index is a primary-index.
|
64
|
+
def primary?
|
65
|
+
return true if @args[:data][:Key_name] == "PRIMARY"
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
return "#<Baza::Driver::Mysql::Index name: \"#{name}\", columns: #{@columns}, primary: #{primary?}, unique: #{unique?}>"
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
to_s
|
75
|
+
end
|
76
|
+
end
|
@@ -3,76 +3,3 @@ class Baza::Driver::Mysql::Indexes
|
|
3
3
|
@args = args
|
4
4
|
end
|
5
5
|
end
|
6
|
-
|
7
|
-
class Baza::Driver::Mysql::Indexes::Index
|
8
|
-
attr_reader :args, :columns
|
9
|
-
|
10
|
-
def initialize(args)
|
11
|
-
@args = args
|
12
|
-
@columns = []
|
13
|
-
end
|
14
|
-
|
15
|
-
#Used to validate in Knj::Wrap_map.
|
16
|
-
def __object_unique_id__
|
17
|
-
return @args[:data][:Key_name]
|
18
|
-
end
|
19
|
-
|
20
|
-
def name
|
21
|
-
return @args[:data][:Key_name]
|
22
|
-
end
|
23
|
-
|
24
|
-
def table
|
25
|
-
return @args[:db].tables[@args[:table_name]]
|
26
|
-
end
|
27
|
-
|
28
|
-
def drop
|
29
|
-
sql = "DROP INDEX `#{self.name}` ON `#{self.table.name}`"
|
30
|
-
|
31
|
-
begin
|
32
|
-
@args[:db].query(sql)
|
33
|
-
rescue => e
|
34
|
-
#The index has already been dropped - ignore.
|
35
|
-
if e.message.index("check that column/key exists") != nil
|
36
|
-
#ignore.
|
37
|
-
else
|
38
|
-
raise e
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def rename newname
|
44
|
-
newname = newname.to_sym
|
45
|
-
create_args = data
|
46
|
-
create_args[:name] = newname
|
47
|
-
|
48
|
-
drop
|
49
|
-
table.create_indexes([create_args])
|
50
|
-
@args[:data][:Key_name] = newname
|
51
|
-
end
|
52
|
-
|
53
|
-
def data
|
54
|
-
return {
|
55
|
-
name: name,
|
56
|
-
columns: @columns
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
#Returns true if the index is a unique-index.
|
61
|
-
def unique?
|
62
|
-
if @args[:data][:Index_type] == "UNIQUE"
|
63
|
-
return true
|
64
|
-
else
|
65
|
-
return false
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
#Returns true if the index is a primary-index.
|
70
|
-
def primary?
|
71
|
-
return true if @args[:data][:Key_name] == "PRIMARY"
|
72
|
-
return false
|
73
|
-
end
|
74
|
-
|
75
|
-
def to_s
|
76
|
-
return "#<Baza::Driver::Mysql::Index name: \"#{name}\", columns: #{@columns}, primary: #{primary?}, unique: #{unique?}>"
|
77
|
-
end
|
78
|
-
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#This class controls the results for the normal MySQL-driver.
|
2
|
+
class Baza::Driver::Mysql::Result
|
3
|
+
#Constructor. This should not be called manually.
|
4
|
+
def initialize(driver, result)
|
5
|
+
@driver = driver
|
6
|
+
@result = result
|
7
|
+
@mutex = Mutex.new
|
8
|
+
|
9
|
+
if @result
|
10
|
+
@keys = []
|
11
|
+
@result.fetch_fields.each do |key|
|
12
|
+
@keys << key.name.to_sym
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#Returns a single result as a hash with symbols as keys.
|
18
|
+
def fetch
|
19
|
+
fetched = nil
|
20
|
+
@mutex.synchronize do
|
21
|
+
fetched = @result.fetch_row
|
22
|
+
end
|
23
|
+
|
24
|
+
return false unless fetched
|
25
|
+
|
26
|
+
ret = {}
|
27
|
+
count = 0
|
28
|
+
@keys.each do |key|
|
29
|
+
ret[key] = fetched[count]
|
30
|
+
count += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
return ret
|
34
|
+
end
|
35
|
+
|
36
|
+
#Loops over every result yielding it.
|
37
|
+
def each
|
38
|
+
while data = self.fetch
|
39
|
+
yield(data)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#This class controls the result for the Java-MySQL-driver.
|
2
|
+
class Baza::Driver::Mysql::ResultJava
|
3
|
+
#Constructor. This should not be called manually.
|
4
|
+
def initialize(knjdb, opts, result)
|
5
|
+
@baza_db = knjdb
|
6
|
+
@result = result
|
7
|
+
|
8
|
+
if !opts.key?(:result) || opts[:result] == "hash"
|
9
|
+
@as_hash = true
|
10
|
+
elsif opts[:result] == "array"
|
11
|
+
@as_hash = false
|
12
|
+
else
|
13
|
+
raise "Unknown type of result: '#{opts[:result]}'."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#Reads meta-data about the query like keys and count.
|
18
|
+
def read_meta
|
19
|
+
@result.before_first
|
20
|
+
meta = @result.meta_data
|
21
|
+
@count = meta.column_count
|
22
|
+
|
23
|
+
@keys = []
|
24
|
+
1.upto(@count) do |count|
|
25
|
+
@keys << meta.column_label(count).to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch
|
30
|
+
return false unless @result
|
31
|
+
self.read_meta unless @keys
|
32
|
+
status = @result.next
|
33
|
+
|
34
|
+
unless status
|
35
|
+
@result = nil
|
36
|
+
@keys = nil
|
37
|
+
@count = nil
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
if @as_hash
|
42
|
+
ret = {}
|
43
|
+
1.upto(@count) do |count|
|
44
|
+
ret[@keys[count - 1]] = @result.object(count)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
ret = []
|
48
|
+
1.upto(@count) do |count|
|
49
|
+
ret << @result.object(count)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
return ret
|
54
|
+
end
|
55
|
+
|
56
|
+
def each
|
57
|
+
while data = self.fetch
|
58
|
+
yield(data)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#This class controls the result for the MySQL2 driver.
|
2
|
+
class Baza::Driver::Mysql::ResultMysql2
|
3
|
+
#Constructor. This should not be called manually.
|
4
|
+
def initialize(result)
|
5
|
+
@result = result
|
6
|
+
end
|
7
|
+
|
8
|
+
#Returns a single result.
|
9
|
+
def fetch
|
10
|
+
@enum = @result.to_enum if !@enum
|
11
|
+
|
12
|
+
begin
|
13
|
+
return @enum.next
|
14
|
+
rescue StopIteration
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#Loops over every single result yielding it.
|
20
|
+
def each
|
21
|
+
@result.each do |res|
|
22
|
+
next unless res #This sometimes happens when streaming results...
|
23
|
+
yield(res)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#This class controls the unbuffered result for the normal MySQL-driver.
|
2
|
+
class Baza::Driver::Mysql::ResultUnbuffered
|
3
|
+
#Constructor. This should not be called manually.
|
4
|
+
def initialize(conn, opts, result)
|
5
|
+
@conn = conn
|
6
|
+
@result = result
|
7
|
+
|
8
|
+
if !opts.key?(:result) || opts[:result] == "hash"
|
9
|
+
@as_hash = true
|
10
|
+
elsif opts[:result] == "array"
|
11
|
+
@as_hash = false
|
12
|
+
else
|
13
|
+
raise "Unknown type of result: '#{opts[:result]}'."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#Lods the keys for the object.
|
18
|
+
def load_keys
|
19
|
+
@keys = []
|
20
|
+
keys = @res.fetch_fields
|
21
|
+
keys.each do |key|
|
22
|
+
@keys << key.name.to_sym
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#Returns a single result.
|
27
|
+
def fetch
|
28
|
+
if @enum
|
29
|
+
begin
|
30
|
+
ret = @enum.next
|
31
|
+
rescue StopIteration
|
32
|
+
@enum = nil
|
33
|
+
@res = nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if !ret && !@res && !@enum
|
38
|
+
begin
|
39
|
+
@res = @conn.use_result
|
40
|
+
@enum = @res.to_enum
|
41
|
+
ret = @enum.next
|
42
|
+
rescue Mysql::Error
|
43
|
+
#Reset it to run non-unbuffered again and then return false.
|
44
|
+
@conn.query_with_result = true
|
45
|
+
return false
|
46
|
+
rescue StopIteration
|
47
|
+
sleep 0.1
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if !@as_hash
|
53
|
+
return ret
|
54
|
+
else
|
55
|
+
self.load_keys if !@keys
|
56
|
+
|
57
|
+
ret_h = {}
|
58
|
+
@keys.each_index do |key_no|
|
59
|
+
ret_h[@keys[key_no]] = ret[key_no]
|
60
|
+
end
|
61
|
+
|
62
|
+
return ret_h
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#Loops over every single result yielding it.
|
67
|
+
def each
|
68
|
+
while data = self.fetch
|
69
|
+
yield(data)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|