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
@@ -0,0 +1,35 @@
|
|
1
|
+
#This class handels the result when running MRI (or others).
|
2
|
+
class Baza::Driver::Sqlite3::Result
|
3
|
+
#Constructor. This should not be called manually.
|
4
|
+
def initialize(driver, result_array)
|
5
|
+
@result_array = result_array
|
6
|
+
@index = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
#Returns a single result.
|
10
|
+
def fetch
|
11
|
+
result_hash = @result_array[@index]
|
12
|
+
return false unless result_hash
|
13
|
+
@index += 1
|
14
|
+
|
15
|
+
ret = {}
|
16
|
+
result_hash.each do |key, val|
|
17
|
+
if (Float(key) rescue false)
|
18
|
+
#do nothing.
|
19
|
+
elsif !key.is_a?(Symbol)
|
20
|
+
ret[key.to_sym] = val
|
21
|
+
else
|
22
|
+
ret[key] = val
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return ret
|
27
|
+
end
|
28
|
+
|
29
|
+
#Loops over every result yielding them.
|
30
|
+
def each
|
31
|
+
while data = self.fetch
|
32
|
+
yield(data)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#This class handels results when running in JRuby.
|
2
|
+
class Baza::Driver::Sqlite3::ResultJava
|
3
|
+
def initialize(driver, rs)
|
4
|
+
@index = 0
|
5
|
+
retkeys = driver.knjdb.opts[:return_keys]
|
6
|
+
|
7
|
+
if rs
|
8
|
+
metadata = rs.getMetaData
|
9
|
+
columns_count = metadata.getColumnCount
|
10
|
+
|
11
|
+
@rows = []
|
12
|
+
while rs.next
|
13
|
+
row_data = {}
|
14
|
+
for i in (1..columns_count)
|
15
|
+
col_name = metadata.getColumnName(i).to_sym
|
16
|
+
row_data[col_name] = rs.getString(i)
|
17
|
+
end
|
18
|
+
|
19
|
+
@rows << row_data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#Returns a single result.
|
25
|
+
def fetch
|
26
|
+
return false unless @rows
|
27
|
+
ret = @rows[@index]
|
28
|
+
return false unless ret
|
29
|
+
@index += 1
|
30
|
+
return ret
|
31
|
+
end
|
32
|
+
|
33
|
+
#Loops over every result and yields them.
|
34
|
+
def each
|
35
|
+
while data = fetch
|
36
|
+
yield data
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
class Baza::Driver::Sqlite3::Table
|
2
|
+
attr_reader :name, :type
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@db = args[:db]
|
6
|
+
@data = args[:data]
|
7
|
+
@name = @data[:name].to_sym
|
8
|
+
@type = @data[:type].to_sym
|
9
|
+
@tables = args[:tables]
|
10
|
+
|
11
|
+
@list = Wref_map.new
|
12
|
+
@indexes_list = Wref_map.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def maxlength
|
16
|
+
return @data[:maxlength]
|
17
|
+
end
|
18
|
+
|
19
|
+
def reload
|
20
|
+
@data = @db.select("sqlite_master", {type: "table", name: name}, {orderby: "name"}).fetch
|
21
|
+
end
|
22
|
+
|
23
|
+
def rows_count
|
24
|
+
data = @db.q("SELECT COUNT(*) AS count FROM `#{name}`").fetch
|
25
|
+
return data[:count].to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
#Drops the table from the database.
|
29
|
+
def drop
|
30
|
+
raise "Cant drop native table: '#{name}'." if native?
|
31
|
+
@db.query("DROP TABLE `#{name}`")
|
32
|
+
@tables.remove_from_list(self) if @tables.exists_in_list?(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
#Returns true if the table is safe to drop.
|
36
|
+
def native?
|
37
|
+
return true if name.to_s == "sqlite_sequence"
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
def optimize
|
42
|
+
# Not possible in SQLite3.
|
43
|
+
end
|
44
|
+
|
45
|
+
def rename(newname)
|
46
|
+
newname = newname.to_sym
|
47
|
+
|
48
|
+
@tables.remove_from_list(self)
|
49
|
+
newtable = clone(newname)
|
50
|
+
@db.tables.remove_from_list(newtable)
|
51
|
+
drop
|
52
|
+
@data[:name] = newname
|
53
|
+
@name = newname
|
54
|
+
@tables.add_to_list(self)
|
55
|
+
|
56
|
+
#Rename table on all columns and indexes.
|
57
|
+
@list.each do |name, column|
|
58
|
+
column.args[:table_name] = newname
|
59
|
+
end
|
60
|
+
|
61
|
+
@indexes_list.each do |name, index|
|
62
|
+
index.args[:table_name] = newname
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def truncate
|
67
|
+
@db.query("DELETE FROM `#{name}` WHERE 1=1")
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def table
|
72
|
+
return @db.tables[@table_name]
|
73
|
+
end
|
74
|
+
|
75
|
+
def column(name)
|
76
|
+
list = self.columns
|
77
|
+
return list[name] if list[name]
|
78
|
+
raise Errno::ENOENT, "Column not found: #{name}."
|
79
|
+
end
|
80
|
+
|
81
|
+
def columns
|
82
|
+
@db.cols
|
83
|
+
ret = {}
|
84
|
+
|
85
|
+
@db.q("PRAGMA table_info(`#{@db.esc_table(name)}`)") do |d_cols|
|
86
|
+
column_name = d_cols[:name].to_sym
|
87
|
+
obj = @list.get!(column_name)
|
88
|
+
|
89
|
+
unless obj
|
90
|
+
obj = Baza::Driver::Sqlite3::Column.new(
|
91
|
+
table_name: name,
|
92
|
+
db: @db,
|
93
|
+
data: d_cols
|
94
|
+
)
|
95
|
+
@list[column_name] = obj
|
96
|
+
end
|
97
|
+
|
98
|
+
if block_given?
|
99
|
+
yield obj
|
100
|
+
else
|
101
|
+
ret[column_name] = obj
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if block_given?
|
106
|
+
return nil
|
107
|
+
else
|
108
|
+
return ret
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def create_columns(col_arr)
|
113
|
+
col_arr.each do |col_data|
|
114
|
+
#if col_data.key?("after")
|
115
|
+
# self.create_column_programmatic(col_data)
|
116
|
+
#else
|
117
|
+
@db.query("ALTER TABLE `#{self.name}` ADD COLUMN #{@db.cols.data_sql(col_data)};")
|
118
|
+
#end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_column_programmatic(col_data)
|
123
|
+
temp_name = "temptable_#{Time.now.to_f.to_s.hash}"
|
124
|
+
cloned_tabled = self.clone(temp_name)
|
125
|
+
cols_cur = self.columns
|
126
|
+
@db.query("DROP TABLE `#{self.name}`")
|
127
|
+
|
128
|
+
sql = "CREATE TABLE `#{self.name}` ("
|
129
|
+
first = true
|
130
|
+
cols_cur.each do |name, col|
|
131
|
+
sql << ", " if !first
|
132
|
+
first = false if first
|
133
|
+
sql << @db.cols.data_sql(col.data)
|
134
|
+
|
135
|
+
if col_data[:after] and col_data[:after] == name
|
136
|
+
sql << ", #{@db.cols.data_sql(col_data)}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
sql << ");"
|
140
|
+
@db.query(sql)
|
141
|
+
|
142
|
+
sql = "INSERT INTO `#{self.name}` SELECT "
|
143
|
+
first = true
|
144
|
+
cols_cur.each do |name, col|
|
145
|
+
sql << ", " if !first
|
146
|
+
first = false if first
|
147
|
+
|
148
|
+
sql << "`#{name}`"
|
149
|
+
|
150
|
+
if col_data[:after] and col_data[:after] == name
|
151
|
+
sql << ", ''"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
sql << " FROM `#{temp_name}`"
|
155
|
+
@db.query(sql)
|
156
|
+
@db.query("DROP TABLE `#{temp_name}`")
|
157
|
+
end
|
158
|
+
|
159
|
+
def clone(newname, args = nil)
|
160
|
+
raise "Invalid name." if newname.to_s.strip.empty?
|
161
|
+
|
162
|
+
sql = "CREATE TABLE `#{newname}` ("
|
163
|
+
first = true
|
164
|
+
columns.each do |name, col|
|
165
|
+
sql << ", " unless first
|
166
|
+
first = false if first
|
167
|
+
sql << @db.cols.data_sql(col.data)
|
168
|
+
end
|
169
|
+
|
170
|
+
sql << ");"
|
171
|
+
@db.query(sql)
|
172
|
+
@db.query("INSERT INTO `#{newname}` SELECT * FROM `#{name}`")
|
173
|
+
|
174
|
+
indexes_to_create = []
|
175
|
+
new_table = @db.tables[newname.to_sym]
|
176
|
+
indexes.each do |name, index|
|
177
|
+
index_name = name.to_s
|
178
|
+
|
179
|
+
if @db.opts[:index_append_table_name] && match = index_name.match(/\A(.+?)__(.+)\Z/)
|
180
|
+
index_name = match[2]
|
181
|
+
end
|
182
|
+
|
183
|
+
create_data = index.data
|
184
|
+
create_data[:name] = index_name
|
185
|
+
|
186
|
+
indexes_to_create << create_data
|
187
|
+
end
|
188
|
+
|
189
|
+
new_table.create_indexes(indexes_to_create)
|
190
|
+
|
191
|
+
if args && args[:return_table] == false
|
192
|
+
return nil
|
193
|
+
else
|
194
|
+
return new_table
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def copy(args = {})
|
199
|
+
temp_name = "temptable_#{Time.now.to_f.to_s.hash}"
|
200
|
+
cloned_tabled = self.clone(temp_name)
|
201
|
+
cols_cur = self.columns
|
202
|
+
@db.query("DROP TABLE `#{self.name}`")
|
203
|
+
|
204
|
+
sql = "CREATE TABLE `#{self.name}` ("
|
205
|
+
first = true
|
206
|
+
cols_cur.each do |name, col|
|
207
|
+
next if args[:drops] && args[:drops].to_s.include?(name.to_s)
|
208
|
+
|
209
|
+
sql << ", " if !first
|
210
|
+
first = false if first
|
211
|
+
|
212
|
+
if args.key?(:alter_columns) && args[:alter_columns][name.to_sym]
|
213
|
+
sql << @db.cols.data_sql(args[:alter_columns][name.to_sym])
|
214
|
+
else
|
215
|
+
sql << @db.cols.data_sql(col.data)
|
216
|
+
end
|
217
|
+
|
218
|
+
if args[:new]
|
219
|
+
args[:new].each do |col_data|
|
220
|
+
if col_data[:after] && col_data[:after] == name
|
221
|
+
sql << ", #{@db.cols.data_sql(col_data)}"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
sql << ");"
|
227
|
+
@db.query(sql)
|
228
|
+
|
229
|
+
sql = "INSERT INTO `#{self.name}` SELECT "
|
230
|
+
first = true
|
231
|
+
cols_cur.each do |name, col|
|
232
|
+
next if args[:drops] && args[:drops].to_s.include?(name.to_s)
|
233
|
+
|
234
|
+
sql << ", " if !first
|
235
|
+
first = false if first
|
236
|
+
|
237
|
+
sql << "`#{name}`"
|
238
|
+
|
239
|
+
if args[:news]
|
240
|
+
args[:news].each do |col_data|
|
241
|
+
if col_data[:after] && col_data[:after] == name.to_s
|
242
|
+
sql << ", ''"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
sql << " FROM `#{temp_name}`"
|
249
|
+
@db.query(sql)
|
250
|
+
@db.query("DROP TABLE `#{temp_name}`")
|
251
|
+
end
|
252
|
+
|
253
|
+
def index index_name
|
254
|
+
index_name = index_name.to_sym
|
255
|
+
|
256
|
+
begin
|
257
|
+
return @indexes_list[index_name]
|
258
|
+
rescue Wref::Recycled
|
259
|
+
if @db.opts[:index_append_table_name]
|
260
|
+
tryname = "#{name}__#{index_name}"
|
261
|
+
|
262
|
+
begin
|
263
|
+
return @indexes_list[tryname]
|
264
|
+
rescue Wref::Recycled
|
265
|
+
#ignore.
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
indexes do |index|
|
271
|
+
if index.name.to_s == "#{name}__#{index_name}"
|
272
|
+
return index
|
273
|
+
end
|
274
|
+
|
275
|
+
return index if index.name.to_s == index_name.to_s
|
276
|
+
end
|
277
|
+
|
278
|
+
raise Errno::ENOENT, "Index not found: #{index_name}."
|
279
|
+
end
|
280
|
+
|
281
|
+
def indexes
|
282
|
+
@db.indexes
|
283
|
+
ret = {} unless block_given?
|
284
|
+
|
285
|
+
@db.q("PRAGMA index_list(`#{@db.esc_table(name)}`)") do |d_indexes|
|
286
|
+
next if d_indexes[:Key_name] == "PRIMARY"
|
287
|
+
obj = @indexes_list.get!(d_indexes[:name])
|
288
|
+
|
289
|
+
unless obj
|
290
|
+
obj = Baza::Driver::Sqlite3::Index.new(
|
291
|
+
table_name: name,
|
292
|
+
db: @db,
|
293
|
+
data: d_indexes
|
294
|
+
)
|
295
|
+
|
296
|
+
@indexes_list[d_indexes[:name].to_sym] = obj
|
297
|
+
|
298
|
+
# Get columns from index.
|
299
|
+
index_master_data = @db.single(:sqlite_master, type: "index", name: d_indexes[:name])
|
300
|
+
parse_columns_from_sql(index_master_data[:sql]).each do |column|
|
301
|
+
obj.columns << column
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
if block_given?
|
306
|
+
yield(obj)
|
307
|
+
else
|
308
|
+
ret[d_indexes[:name].to_sym] = obj
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
if block_given?
|
313
|
+
return nil
|
314
|
+
else
|
315
|
+
return ret
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def create_indexes(index_arr, args = nil)
|
320
|
+
if args && args[:return_sql]
|
321
|
+
ret = []
|
322
|
+
end
|
323
|
+
|
324
|
+
index_arr.each do |index_data|
|
325
|
+
if index_data.is_a?(String) or index_data.is_a?(Symbol)
|
326
|
+
index_data = {name: index_data, columns: [index_data]}
|
327
|
+
end
|
328
|
+
|
329
|
+
raise "No name was given in data: '#{index_data}'." if !index_data.key?(:name) or index_data[:name].to_s.strip.empty?
|
330
|
+
raise "No columns was given on index #{index_data[:name]}." if index_data[:columns].empty?
|
331
|
+
|
332
|
+
name = index_data[:name]
|
333
|
+
name = "#{self.name}__#{name}" if @db.opts[:index_append_table_name]
|
334
|
+
|
335
|
+
sql = "CREATE"
|
336
|
+
sql << " UNIQUE" if index_data[:unique]
|
337
|
+
sql << " INDEX '#{@db.esc_col(name)}' ON `#{@db.esc_table(self.name)}` ("
|
338
|
+
|
339
|
+
first = true
|
340
|
+
index_data[:columns].each do |col_name|
|
341
|
+
sql << ", " if !first
|
342
|
+
first = false if first
|
343
|
+
|
344
|
+
sql << "`#{@db.esc_col(col_name)}`"
|
345
|
+
end
|
346
|
+
|
347
|
+
sql << ")"
|
348
|
+
|
349
|
+
if args && args[:return_sql]
|
350
|
+
ret << sql
|
351
|
+
else
|
352
|
+
@db.query(sql)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
if args && args[:return_sql]
|
357
|
+
return ret
|
358
|
+
else
|
359
|
+
return nil
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def data
|
364
|
+
ret = {
|
365
|
+
name: name,
|
366
|
+
columns: [],
|
367
|
+
indexes: []
|
368
|
+
}
|
369
|
+
|
370
|
+
columns.each do |name, column|
|
371
|
+
ret[:columns] << column.data
|
372
|
+
end
|
373
|
+
|
374
|
+
indexes.each do |name, index|
|
375
|
+
ret[:indexes] << index.data if name != "PRIMARY"
|
376
|
+
end
|
377
|
+
|
378
|
+
return ret
|
379
|
+
end
|
380
|
+
|
381
|
+
def insert(data)
|
382
|
+
@db.insert(name, data)
|
383
|
+
end
|
384
|
+
|
385
|
+
def to_s
|
386
|
+
"#<Baza::Driver::Sqlite3::Table name: \"#{name}\">"
|
387
|
+
end
|
388
|
+
|
389
|
+
def inspect
|
390
|
+
to_s
|
391
|
+
end
|
392
|
+
|
393
|
+
private
|
394
|
+
|
395
|
+
def parse_columns_from_sql sql
|
396
|
+
columns_sql = sql.match(/\((.+?)\)\Z/)[1]
|
397
|
+
return columns_sql.split(",").map{ |column| column[1, column.length - 2] }
|
398
|
+
end
|
399
|
+
end
|