baza 0.0.0

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