baza 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -13
  3. data/VERSION +1 -1
  4. data/baza.gemspec +15 -3
  5. data/include/db.rb +871 -865
  6. data/include/drivers/mysql/mysql.rb +104 -297
  7. data/include/drivers/mysql/mysql_column.rb +133 -0
  8. data/include/drivers/mysql/mysql_columns.rb +4 -127
  9. data/include/drivers/mysql/mysql_index.rb +76 -0
  10. data/include/drivers/mysql/mysql_indexes.rb +0 -73
  11. data/include/drivers/mysql/mysql_result.rb +42 -0
  12. data/include/drivers/mysql/mysql_result_java.rb +61 -0
  13. data/include/drivers/mysql/mysql_result_mysql2.rb +26 -0
  14. data/include/drivers/mysql/mysql_result_unbuffered.rb +72 -0
  15. data/include/drivers/mysql/mysql_sqlspecs.rb +1 -1
  16. data/include/drivers/mysql/mysql_table.rb +361 -0
  17. data/include/drivers/mysql/mysql_tables.rb +23 -381
  18. data/include/drivers/sqlite3/libknjdb_java_sqlite3.rb +17 -22
  19. data/include/drivers/sqlite3/libknjdb_sqlite3_ironruby.rb +13 -13
  20. data/include/drivers/sqlite3/sqlite3.rb +39 -105
  21. data/include/drivers/sqlite3/sqlite3_column.rb +146 -0
  22. data/include/drivers/sqlite3/sqlite3_columns.rb +17 -149
  23. data/include/drivers/sqlite3/sqlite3_index.rb +55 -0
  24. data/include/drivers/sqlite3/sqlite3_indexes.rb +0 -52
  25. data/include/drivers/sqlite3/sqlite3_result.rb +35 -0
  26. data/include/drivers/sqlite3/sqlite3_result_java.rb +39 -0
  27. data/include/drivers/sqlite3/sqlite3_table.rb +399 -0
  28. data/include/drivers/sqlite3/sqlite3_tables.rb +7 -403
  29. data/include/idquery.rb +19 -19
  30. data/include/model.rb +139 -139
  31. data/include/model_handler_sqlhelper.rb +74 -74
  32. data/spec/support/driver_columns_collection.rb +17 -0
  33. 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