baza 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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