baza 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/include/revision.rb CHANGED
@@ -28,53 +28,71 @@ class Baza::Revision
28
28
  @args = args
29
29
  end
30
30
 
31
+ INIT_DB_ALLOWED_ARGS = [:db, :schema, :tables_cache, :debug]
32
+ INIT_DB_SCHEMA_ALLOWED_ARGS = [:tables]
33
+ INIT_DB_TABLE_ALLOWED_ARGS = [:columns, :indexes, :rows, :renames]
31
34
  #This initializes a database-structure and content based on a schema-hash.
32
35
  #===Examples
33
36
  # dbrev = Baza::Revision.new
34
37
  # dbrev.init_db("db" => db_obj, "schema" => schema_hash)
35
38
  def init_db(args)
36
- schema = args["schema"]
37
- db = args["db"]
39
+ args.each do |key, val|
40
+ raise "Invalid key: '#{key}' (#{key.class.name})." unless INIT_DB_ALLOWED_ARGS.include?(key)
41
+ end
42
+
43
+ schema = args[:schema]
44
+ db = args[:db]
45
+
46
+ schema.each do |key, val|
47
+ raise "Invalid key for schema: '#{key}' (#{key.class.name})." unless INIT_DB_SCHEMA_ALLOWED_ARGS.include?(key)
48
+ end
38
49
 
39
50
  #Check for normal bugs and raise apropiate error.
40
51
  raise "'schema' argument was not a Hash: '#{schema.class.name}'." if !schema.is_a?(Hash)
41
- raise "':return_keys' is not 'symbols' - Knjdbrevision will not work without it." if db.opts[:return_keys] != "symbols"
42
- raise "No tables given." if !schema.has_key?("tables")
52
+ raise "No tables given." if !schema.has_key?(:tables)
43
53
 
44
54
  #Cache tables to avoid constant reloading.
45
- if !args.key?("tables_cache") or args["tables_cache"]
46
- print "Caching tables-list.\n" if args["debug"]
55
+ if !args.key?(:tables_cache) or args[:tables_cache]
56
+ puts "Caching tables-list." if args[:debug]
47
57
  tables = db.tables.list
48
58
  else
49
- print "Skipping tables-cache.\n" if args["debug"]
59
+ puts "Skipping tables-cache." if args[:debug]
50
60
  end
51
61
 
52
- schema["tables"].each do |table_name, table_data|
62
+ schema[:tables].each do |table_name, table_data|
63
+ table_data.each do |key, val|
64
+ raise "Invalid key: '#{key}' (#{key.class.name})." unless INIT_DB_TABLE_ALLOWED_ARGS.include?(key)
65
+ end
66
+
53
67
  begin
54
68
  begin
69
+ table_name = table_name.to_sym
70
+
71
+ puts "Getting table-object for table: '#{table_name}'." if args[:debug]
55
72
  table_obj = db.tables[table_name]
56
73
 
57
74
  #Cache indexes- and column-objects to avoid constant reloading.
58
75
  cols = table_obj.columns
59
76
  indexes = table_obj.indexes
60
77
 
61
- if table_data["columns"]
78
+ if table_data[:columns]
62
79
  first_col = true
63
- table_data["columns"].each do |col_data|
80
+ table_data[:columns].each do |col_data|
64
81
  begin
65
- col_obj = table_obj.column(col_data["name"])
82
+ col_name = col_data[:name].to_sym
83
+ col_obj = table_obj.column(col_name)
66
84
  col_str = "#{table_name}.#{col_obj.name}"
67
- type = col_data["type"].to_s
85
+ type = col_data[:type].to_sym
68
86
  dochange = false
69
87
 
70
- if !first_col and !col_data["after"]
88
+ if !first_col and !col_data[:after]
71
89
  #Try to find out the previous column - if so we can set "after" which makes the column being created in the right order as defined.
72
- if !col_data.has_key?("after")
73
- prev_no = table_data["columns"].index(col_data)
90
+ if !col_data.has_key?(:after)
91
+ prev_no = table_data[:columns].index(col_data)
74
92
  if prev_no != nil and prev_no != 0
75
93
  prev_no = prev_no - 1
76
- prev_col_data = table_data["columns"][prev_no]
77
- col_data["after"] = prev_col_data["name"]
94
+ prev_col_data = table_data[:columns][prev_no]
95
+ col_data[:after] = prev_col_data[:name]
78
96
  end
79
97
  end
80
98
 
@@ -88,63 +106,66 @@ class Baza::Revision
88
106
  end
89
107
  end
90
108
 
91
- if actual_after != col_data["after"]
92
- print "Changing '#{col_str}' after from '#{actual_after}' to '#{col_data["after"]}'.\n" if args["debug"]
109
+ if actual_after != col_data[:after]
110
+ print "Changing '#{col_str}' after from '#{actual_after}' to '#{col_data[:after]}'.\n" if args[:debug]
93
111
  dochange = true
94
112
  end
95
113
  end
96
114
 
97
115
  #BUGFIX: When using SQLite3 the primary-column or a autoincr-column may never change type from int... This will break it!
98
- if db.opts[:type] == "sqlite3" and col_obj.type.to_s == "int" and (col_data["primarykey"] or col_data["autoincr"]) and db.int_types.index(col_data["type"].to_s)
99
- type = "int"
116
+ if db.opts[:type] == "sqlite3" and col_obj.type.to_s == "int" and (col_data[:primarykey] or col_data[:autoincr]) and db.int_types.index(col_data[:type].to_s)
117
+ type = :int
100
118
  end
101
119
 
102
120
  if type and col_obj.type.to_s != type
103
- print "Type mismatch on #{col_str}: #{col_data["type"]}, #{col_obj.type}\n" if args["debug"]
121
+ print "Type mismatch on #{col_str}: #{col_data[:type]}, #{col_obj.type}\n" if args[:debug]
104
122
  dochange = true
105
123
  end
106
124
 
107
- if col_data.has_key?("primarykey") and col_obj.primarykey? != col_data["primarykey"]
108
- print "Primary-key mismatch for #{col_str}: #{col_data["primarykey"]}, #{col_obj.primarykey?}\n" if args["debug"]
125
+ if col_data.has_key?(:primarykey) and col_obj.primarykey? != col_data[:primarykey]
126
+ print "Primary-key mismatch for #{col_str}: #{col_data[:primarykey]}, #{col_obj.primarykey?}\n" if args[:debug]
109
127
  dochange = true
110
128
  end
111
129
 
112
- if col_data.has_key?("autoincr") and col_obj.autoincr? != col_data["autoincr"]
113
- print "Auto-increment mismatch for #{col_str}: #{col_data["autoincr"]}, #{col_obj.autoincr?}\n" if args["debug"]
130
+ if col_data.has_key?(:autoincr) and col_obj.autoincr? != col_data[:autoincr]
131
+ print "Auto-increment mismatch for #{col_str}: #{col_data[:autoincr]}, #{col_obj.autoincr?}\n" if args[:debug]
114
132
  dochange = true
115
133
  end
116
134
 
117
- if col_data.has_key?("maxlength") and col_obj.maxlength.to_s != col_data["maxlength"].to_s
118
- print "Maxlength mismatch on #{col_str}: #{col_data["maxlength"]}, #{col_obj.maxlength}\n" if args["debug"]
135
+ if col_data.has_key?(:maxlength) and col_obj.maxlength.to_s != col_data[:maxlength].to_s
136
+ print "Maxlength mismatch on #{col_str}: #{col_data[:maxlength]}, #{col_obj.maxlength}\n" if args[:debug]
119
137
  dochange = true
120
138
  end
121
139
 
122
- if col_data.has_key?("null") and col_obj.null?.to_s != col_data["null"].to_s
123
- print "Null mismatch on #{col_str}: #{col_data["null"]}, #{col_obj.null?}\n" if args["debug"]
140
+ if col_data.has_key?(:null) and col_obj.null?.to_s != col_data[:null].to_s
141
+ print "Null mismatch on #{col_str}: #{col_data[:null]}, #{col_obj.null?}\n" if args[:debug]
124
142
  dochange = true
125
143
  end
126
144
 
127
- if col_data.has_key?("default") and col_obj.default.to_s != col_data["default"].to_s
128
- print "Default mismatch on #{col_str}: #{col_data["default"]}, #{col_obj.default}\n" if args["debug"]
145
+ if col_data.has_key?(:default) and col_obj.default.to_s != col_data[:default].to_s
146
+ print "Default mismatch on #{col_str}: #{col_data[:default]}, #{col_obj.default}\n" if args[:debug]
129
147
  dochange = true
130
148
  end
131
149
 
132
- if col_data.has_key?("comment") and col_obj.respond_to?(:comment) and col_obj.comment.to_s != col_data["comment"].to_s
133
- print "Comment mismatch on #{col_str}: #{col_data["comment"]}, #{col_obj.comment}\n" if args["debug"]
150
+ if col_data.has_key?(:comment) and col_obj.respond_to?(:comment) and col_obj.comment.to_s != col_data[:comment].to_s
151
+ print "Comment mismatch on #{col_str}: #{col_data[:comment]}, #{col_obj.comment}\n" if args[:debug]
134
152
  dochange = true
135
153
  end
136
154
 
137
- if col_data.is_a?(Hash) and col_data["on_before_alter"]
138
- callback_data = col_data["on_before_alter"].call("db" => db, "table" => table_obj, "col" => col_obj, "col_data" => col_data)
139
- if callback_data and callback_data["action"]
140
- if callback_data["action"] == "retry"
155
+ if col_data.is_a?(Hash) and col_data[:on_before_alter]
156
+ callback_data = col_data[:on_before_alter].call(:db => db, :table => table_obj, :col => col_obj, :col_data => col_data)
157
+ if callback_data and callback_data[:action]
158
+ if callback_data[:action] == :retry
141
159
  raise Knj::Errors::Retry
142
160
  end
143
161
  end
144
162
  end
145
163
 
146
164
  if dochange
147
- col_obj.change(col_data)
165
+ col_data_change = col_data.clone
166
+ col_data_change.delete(:renames)
167
+
168
+ col_obj.change(col_data_change)
148
169
 
149
170
  #Change has been made - update cache.
150
171
  cols = table_obj.columns
@@ -152,31 +173,34 @@ class Baza::Revision
152
173
 
153
174
  first_col = false
154
175
  rescue Errno::ENOENT => e
155
- print "Column not found: #{table_obj.name}.#{col_data["name"]}.\n" if args["debug"]
176
+ print "Column not found: #{table_obj.name}.#{col_data[:name]}.\n" if args[:debug]
156
177
 
157
- if col_data.has_key?("renames")
158
- raise "'renames' was not an array for column '#{table_obj.name}.#{col_data["name"]}'." if !col_data["renames"].is_a?(Array)
178
+ if col_data.has_key?(:renames)
179
+ raise "'renames' was not an array for column '#{table_obj.name}.#{col_data[:name]}'." if !col_data[:renames].is_a?(Array)
159
180
 
160
181
  rename_found = false
161
- col_data["renames"].each do |col_name|
182
+ col_data[:renames].each do |col_name|
162
183
  begin
163
184
  col_rename = table_obj.column(col_name)
164
185
  rescue Errno::ENOENT => e
165
186
  next
166
187
  end
167
188
 
168
- print "Rename #{table_obj.name}.#{col_name} to #{table_obj.name}.#{col_data["name"]}\n" if args["debug"]
169
- if col_data.is_a?(Hash) and col_data["on_before_rename"]
170
- col_data["on_before_rename"].call("db" => db, "table" => table_obj, "col" => col_rename, "col_data" => col_data)
189
+ print "Rename #{table_obj.name}.#{col_name} to #{table_obj.name}.#{col_data[:name]}\n" if args[:debug]
190
+ if col_data.is_a?(Hash) and col_data[:on_before_rename]
191
+ col_data[:on_before_rename].call(:db => db, :table => table_obj, :col => col_rename, :col_data => col_data)
171
192
  end
172
193
 
173
- col_rename.change(col_data)
194
+ col_data_change = col_data.clone
195
+ col_data_change.delete(:renames)
196
+
197
+ col_rename.change(col_data_change)
174
198
 
175
199
  #Change has been made - update cache.
176
200
  cols = table_obj.columns
177
201
 
178
- if col_data.is_a?(Hash) and col_data["on_after_rename"]
179
- col_data["on_after_rename"].call("db" => db, "table" => table_obj, "col" => col_rename, "col_data" => col_data)
202
+ if col_data.is_a?(Hash) and col_data[:on_after_rename]
203
+ col_data[:on_after_rename].call(:db => db, :table => table_obj, :col => col_rename, :col_data => col_data)
180
204
  end
181
205
 
182
206
  rename_found = true
@@ -186,42 +210,46 @@ class Baza::Revision
186
210
  retry if rename_found
187
211
  end
188
212
 
189
- oncreated = col_data["on_created"]
190
- col_data.delete("on_created") if col_data["oncreated"]
213
+ oncreated = col_data[:on_created]
214
+ col_data.delete(:on_created) if col_data[:oncreated]
215
+
216
+ col_data_create = col_data
217
+ col_data_create.delete(:renames)
218
+
191
219
  col_obj = table_obj.create_columns([col_data])
192
220
 
193
221
  #Change has been made - update cache.
194
222
  cols = table_obj.columns
195
223
 
196
- oncreated.call("db" => db, "table" => table_obj) if oncreated
224
+ oncreated.call(:db => db, :table => table_obj) if oncreated
197
225
  end
198
226
  end
199
227
  end
200
228
 
201
- if table_data["columns_remove"]
202
- table_data["columns_remove"].each do |column_name, column_data|
229
+ if table_data[:columns_remove]
230
+ table_data[:columns_remove].each do |column_name, column_data|
203
231
  begin
204
232
  col_obj = table_obj.column(column_name)
205
233
  rescue Errno::ENOENT => e
206
234
  next
207
235
  end
208
236
 
209
- column_data["callback"].call if column_data.is_a?(Hash) and column_data["callback"]
237
+ column_data[:callback].call if column_data.is_a?(Hash) and column_data[:callback]
210
238
  col_obj.drop
211
239
  end
212
240
  end
213
241
 
214
- if table_data["indexes"]
215
- table_data["indexes"].each do |index_data|
242
+ if table_data[:indexes]
243
+ table_data[:indexes].each do |index_data|
216
244
  if index_data.is_a?(String)
217
- index_data = {"name" => index_data, "columns" => [index_data]}
245
+ index_data = {:name => index_data, :columns => [index_data]}
218
246
  end
219
247
 
220
248
  begin
221
- index_obj = table_obj.index(index_data["name"])
249
+ index_obj = table_obj.index(index_data[:name])
222
250
 
223
251
  rewrite_index = false
224
- rewrite_index = true if index_data.key?("unique") and index_data["unique"] != index_obj.unique?
252
+ rewrite_index = true if index_data.key?(:unique) and index_data[:unique] != index_obj.unique?
225
253
 
226
254
  if rewrite_index
227
255
  index_obj.drop
@@ -233,27 +261,30 @@ class Baza::Revision
233
261
  end
234
262
  end
235
263
 
236
- if table_data["indexes_remove"]
237
- table_data["indexes_remove"].each do |index_name, index_data|
264
+ if table_data[:indexes_remove]
265
+ table_data[:indexes_remove].each do |index_name, index_data|
238
266
  begin
239
267
  index_obj = table_obj.index(index_name)
240
268
  rescue Errno::ENOENT => e
241
269
  next
242
270
  end
243
271
 
244
- if index_data.is_a?(Hash) and index_data["callback"]
245
- index_data["callback"].call if index_data["callback"]
272
+ if index_data.is_a?(Hash) and index_data[:callback]
273
+ index_data[:callback].call if index_data[:callback]
246
274
  end
247
275
 
248
276
  index_obj.drop
249
277
  end
250
278
  end
251
279
 
252
- rows_init("db" => db, "table" => table_obj, "rows" => table_data["rows"]) if table_data and table_data["rows"]
280
+ rows_init(:db => db, :table => table_obj, :rows => table_data[:rows]) if table_data and table_data[:rows]
253
281
  rescue Errno::ENOENT => e
254
- if table_data.key?("renames")
255
- table_data["renames"].each do |table_name_rename|
282
+ puts "Table did not exist: '#{table_name}'." if args[:debug]
283
+
284
+ if table_data.key?(:renames)
285
+ table_data[:renames].each do |table_name_rename|
256
286
  begin
287
+ puts "Renaming table: '#{table_name_rename}' to '#{table_name}'." if args[:debug]
257
288
  table_rename = db.tables[table_name_rename.to_sym]
258
289
  table_rename.rename(table_name)
259
290
  raise Knj::Errors::Retry
@@ -263,34 +294,38 @@ class Baza::Revision
263
294
  end
264
295
  end
265
296
 
266
- if !table_data.key?("columns")
297
+ if !table_data.key?(:columns)
267
298
  print "Notice: Skipping creation of '#{table_name}' because no columns were given in hash.\n"
268
299
  next
269
300
  end
270
301
 
271
- if table_data["on_create"]
272
- table_data["on_create"].call("db" => db, "table_name" => table_name, "table_data" => table_data)
302
+ if table_data[:on_create]
303
+ table_data[:on_create].call(:db => db, :table_name => table_name, :table_data => table_data)
273
304
  end
274
305
 
275
- db.tables.create(table_name, table_data)
306
+ table_data_create = table_data.clone
307
+ table_data_create.delete(:rows)
308
+
309
+ puts "Creating table: '#{table_name}'." if args[:debug]
310
+ db.tables.create(table_name, table_data_create)
276
311
  table_obj = db.tables[table_name.to_sym]
277
312
 
278
- if table_data["on_create_after"]
279
- table_data["on_create_after"].call("db" => db, "table_name" => table_name, "table_data" => table_data)
313
+ if table_data[:on_create_after]
314
+ table_data[:on_create_after].call(:db => db, :table_name => table_name, :table_data => table_data)
280
315
  end
281
316
 
282
- rows_init("db" => db, "table" => table_obj, "rows" => table_data["rows"]) if table_data["rows"]
317
+ rows_init(:db => db, :table => table_obj, :rows => table_data[:rows]) if table_data[:rows]
283
318
  end
284
319
  rescue Knj::Errors::Retry
285
320
  retry
286
321
  end
287
322
  end
288
323
 
289
- if schema["tables_remove"]
290
- schema["tables_remove"].each do |table_name, table_data|
324
+ if schema[:tables_remove]
325
+ schema[:tables_remove].each do |table_name, table_data|
291
326
  begin
292
327
  table_obj = db.tables[table_name.to_sym]
293
- table_data["callback"].call("db" => db, "table" => table_obj) if table_data.is_a?(Hash) and table_data["callback"]
328
+ table_data[:callback].call(:db => db, :table => table_obj) if table_data.is_a?(Hash) and table_data[:callback]
294
329
  table_obj.drop
295
330
  rescue Errno::ENOENT => e
296
331
  next
@@ -306,36 +341,41 @@ class Baza::Revision
306
341
 
307
342
  private
308
343
 
344
+ ROWS_INIT_ALLOWED_ARGS = [:db, :table, :rows]
309
345
  #This method checks if certain rows are present in a table based on a hash.
310
346
  def rows_init(args)
311
- db = args["db"]
312
- table = args["table"]
347
+ args.each do |key, val|
348
+ raise "Invalid key: '#{key}' (#{key.class.name})." unless ROWS_INIT_ALLOWED_ARGS.include?(key)
349
+ end
350
+
351
+ db = args[:db]
352
+ table = args[:table]
313
353
 
314
354
  raise "No db given." if !db
315
355
  raise "No table given." if !table
316
356
 
317
- args["rows"].each do |row_data|
318
- if row_data["find_by"]
319
- find_by = row_data["find_by"]
320
- elsif row_data["data"]
321
- find_by = row_data["data"]
357
+ args[:rows].each do |row_data|
358
+ if row_data[:find_by]
359
+ find_by = row_data[:find_by]
360
+ elsif row_data[:data]
361
+ find_by = row_data[:data]
322
362
  else
323
363
  raise "Could not figure out the find-by."
324
364
  end
325
365
 
326
366
  rows_found = 0
327
- args["db"].select(table.name, find_by) do |d_rows|
367
+ args[:db].select(table.name, find_by) do |d_rows|
328
368
  rows_found += 1
329
369
 
330
- if Knj::ArrayExt.hash_diff?(Knj::ArrayExt.hash_sym(row_data["data"]), Knj::ArrayExt.hash_sym(d_rows), {"h2_to_h1" => false})
331
- print "Data was not right - updating row: #{JSON.generate(row_data["data"])}\n" if args["debug"]
332
- args["db"].update(table.name, row_data["data"], d_rows)
370
+ if Knj::ArrayExt.hash_diff?(Knj::ArrayExt.hash_sym(row_data[:data]), Knj::ArrayExt.hash_sym(d_rows), {"h2_to_h1" => false})
371
+ print "Data was not right - updating row: #{JSON.generate(row_data[:data])}\n" if args[:debug]
372
+ args[:db].update(table.name, row_data[:data], d_rows)
333
373
  end
334
374
  end
335
375
 
336
376
  if rows_found == 0
337
- print "Inserting row: #{JSON.generate(row_data["data"])}\n" if args["debug"]
338
- table.insert(row_data["data"])
377
+ print "Inserting row: #{JSON.generate(row_data[:data])}\n" if args[:debug]
378
+ table.insert(row_data[:data])
339
379
  end
340
380
  end
341
381
  end