baza 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  #This class buffers a lot of queries and flushes them out via transactions.
2
2
  class Baza::QueryBuffer
3
3
  attr_reader :thread_async
4
-
4
+
5
5
  INITIALIZE_ARGS_ALLOWED = [:db, :debug, :flush_async]
6
6
  #Constructor. Takes arguments to be used and a block.
7
7
  def initialize(args)
@@ -11,14 +11,14 @@ class Baza::QueryBuffer
11
11
  @queries_count = 0
12
12
  @debug = @args[:debug]
13
13
  @lock = Mutex.new
14
-
14
+
15
15
  STDOUT.puts "Query buffer started." if @debug
16
-
16
+
17
17
  if block_given?
18
18
  if @args[:flush_async]
19
19
  @args[:db].clone_conn do |db_flush_async|
20
20
  @db_flush_async = db_flush_async
21
-
21
+
22
22
  begin
23
23
  yield(self)
24
24
  ensure
@@ -28,15 +28,15 @@ class Baza::QueryBuffer
28
28
  end
29
29
  else
30
30
  begin
31
- yield(self)
31
+ yield(self)
32
32
  ensure
33
33
  flush
34
34
  thread_async_join
35
35
  end
36
36
  end
37
- end
37
+ end
38
38
  end
39
-
39
+
40
40
  #Adds a query to the buffer.
41
41
  def query(str)
42
42
  @lock.synchronize do
@@ -44,11 +44,11 @@ class Baza::QueryBuffer
44
44
  @queries << str
45
45
  @queries_count += 1
46
46
  end
47
-
47
+
48
48
  flush if @queries_count >= 1000
49
49
  return nil
50
50
  end
51
-
51
+
52
52
  #Delete as on a normal Baza::Db.
53
53
  #===Example
54
54
  # buffer.delete(:users, {:id => 5})
@@ -57,7 +57,7 @@ class Baza::QueryBuffer
57
57
  query(@args[:db].delete(table, where, :return_sql => true))
58
58
  return nil
59
59
  end
60
-
60
+
61
61
  #Update as on a normal Baza::Db.
62
62
  #===Example
63
63
  # buffer.update(:users, {:name => "Kasper"}, {:id => 5})
@@ -66,7 +66,7 @@ class Baza::QueryBuffer
66
66
  query(@args[:db].update(table, update, terms, :return_sql => true))
67
67
  return nil
68
68
  end
69
-
69
+
70
70
  #Shortcut to doing upsert through the buffer instead of through the db-object with the buffer as an argument.
71
71
  #===Example
72
72
  # buffer.upsert(:users, {:id => 5}, {:name => "Kasper"})
@@ -74,7 +74,7 @@ class Baza::QueryBuffer
74
74
  @args[:db].upsert(table, data, terms, :buffer => self)
75
75
  return nil
76
76
  end
77
-
77
+
78
78
  #Plans to inset a hash into a table. It will only be inserted when flush is called.
79
79
  #===Examples
80
80
  # buffer.insert(:users, {:name => "John Doe"})
@@ -82,7 +82,7 @@ class Baza::QueryBuffer
82
82
  query(@args[:db].insert(table, data, :return_sql => true))
83
83
  return nil
84
84
  end
85
-
85
+
86
86
  #Flushes all queries out in a transaction. This will automatically be called for every 1000 queries.
87
87
  def flush
88
88
  if @args[:flush_async]
@@ -91,13 +91,13 @@ class Baza::QueryBuffer
91
91
  flush_real
92
92
  end
93
93
  end
94
-
94
+
95
95
  private
96
-
96
+
97
97
  #Runs the flush in a thread in the background.
98
98
  def flush_async
99
99
  thread_async_join
100
-
100
+
101
101
  @thread_async = Thread.new do
102
102
  begin
103
103
  flush_real(@db_flush_async)
@@ -107,18 +107,18 @@ class Baza::QueryBuffer
107
107
  end
108
108
  end
109
109
  end
110
-
110
+
111
111
  def thread_async_join
112
112
  if thread = @thread_async
113
113
  thread.join
114
114
  end
115
115
  end
116
-
116
+
117
117
  #Flushes the queries for real.
118
118
  def flush_real(db = nil)
119
119
  return nil if @queries_count <= 0
120
120
  db = @args[:db] if db == nil
121
-
121
+
122
122
  @lock.synchronize do
123
123
  if !@queries.empty?
124
124
  while !@queries.empty?
@@ -130,18 +130,18 @@ class Baza::QueryBuffer
130
130
  end
131
131
  end
132
132
  end
133
-
133
+
134
134
  @inserts.each do |table, datas_arr|
135
135
  while !datas_arr.empty?
136
136
  datas_chunk_arr = datas_arr.shift(1000)
137
137
  @db.insert_multi(table, datas_chunk_arr)
138
138
  end
139
139
  end
140
-
140
+
141
141
  @inserts.clear
142
142
  @queries_count = 0
143
143
  end
144
-
144
+
145
145
  return nil
146
146
  end
147
147
  end
data/include/revision.rb CHANGED
@@ -20,14 +20,14 @@
20
20
  # }
21
21
  # }
22
22
  # }
23
- #
23
+ #
24
24
  # rev = Baza::Revision.new
25
25
  # rev.init_db("db" => db, "schema" => schema)
26
26
  class Baza::Revision
27
27
  def initialize(args = {})
28
28
  @args = args
29
29
  end
30
-
30
+
31
31
  INIT_DB_ALLOWED_ARGS = [:db, :schema, :tables_cache, :debug]
32
32
  INIT_DB_SCHEMA_ALLOWED_ARGS = [:tables]
33
33
  INIT_DB_TABLE_ALLOWED_ARGS = [:columns, :indexes, :rows, :renames]
@@ -39,19 +39,19 @@ class Baza::Revision
39
39
  args.each do |key, val|
40
40
  raise "Invalid key: '#{key}' (#{key.class.name})." unless INIT_DB_ALLOWED_ARGS.include?(key)
41
41
  end
42
-
42
+
43
43
  schema = args[:schema]
44
44
  db = args[:db]
45
45
  raise "No 'db' was given." if !db
46
-
46
+
47
47
  schema.each do |key, val|
48
48
  raise "Invalid key for schema: '#{key}' (#{key.class.name})." unless INIT_DB_SCHEMA_ALLOWED_ARGS.include?(key)
49
49
  end
50
-
50
+
51
51
  #Check for normal bugs and raise apropiate error.
52
52
  raise "'schema' argument was not a Hash: '#{schema.class.name}'." if !schema.is_a?(Hash)
53
53
  raise "No tables given." if !schema.has_key?(:tables)
54
-
54
+
55
55
  #Cache tables to avoid constant reloading.
56
56
  if !args.key?(:tables_cache) or args[:tables_cache]
57
57
  puts "Caching tables-list." if args[:debug]
@@ -59,23 +59,23 @@ class Baza::Revision
59
59
  else
60
60
  puts "Skipping tables-cache." if args[:debug]
61
61
  end
62
-
62
+
63
63
  schema[:tables].each do |table_name, table_data|
64
64
  table_data.each do |key, val|
65
65
  raise "Invalid key: '#{key}' (#{key.class.name})." unless INIT_DB_TABLE_ALLOWED_ARGS.include?(key)
66
66
  end
67
-
67
+
68
68
  begin
69
69
  begin
70
70
  table_name = table_name.to_sym
71
-
71
+
72
72
  puts "Getting table-object for table: '#{table_name}'." if args[:debug]
73
73
  table_obj = db.tables[table_name]
74
-
74
+
75
75
  #Cache indexes- and column-objects to avoid constant reloading.
76
76
  cols = table_obj.columns
77
77
  indexes = table_obj.indexes
78
-
78
+
79
79
  if table_data[:columns]
80
80
  first_col = true
81
81
  table_data[:columns].each do |col_data|
@@ -85,7 +85,7 @@ class Baza::Revision
85
85
  col_str = "#{table_name}.#{col_obj.name}"
86
86
  type = col_data[:type].to_sym
87
87
  dochange = false
88
-
88
+
89
89
  if !first_col and !col_data[:after]
90
90
  #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.
91
91
  if !col_data.has_key?(:after)
@@ -96,7 +96,7 @@ class Baza::Revision
96
96
  col_data[:after] = prev_col_data[:name]
97
97
  end
98
98
  end
99
-
99
+
100
100
  actual_after = nil
101
101
  set_next = false
102
102
  cols.each do |col_name, col_iter|
@@ -106,53 +106,53 @@ class Baza::Revision
106
106
  actual_after = col_iter.name
107
107
  end
108
108
  end
109
-
109
+
110
110
  if actual_after != col_data[:after]
111
111
  print "Changing '#{col_str}' after from '#{actual_after}' to '#{col_data[:after]}'.\n" if args[:debug]
112
112
  dochange = true
113
113
  end
114
114
  end
115
-
115
+
116
116
  #BUGFIX: When using SQLite3 the primary-column or a autoincr-column may never change type from int... This will break it!
117
117
  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)
118
118
  type = :int
119
119
  end
120
-
120
+
121
121
  if type and col_obj.type.to_s != type
122
122
  print "Type mismatch on #{col_str}: #{col_data[:type]}, #{col_obj.type}\n" if args[:debug]
123
123
  dochange = true
124
124
  end
125
-
125
+
126
126
  if col_data.has_key?(:primarykey) and col_obj.primarykey? != col_data[:primarykey]
127
127
  print "Primary-key mismatch for #{col_str}: #{col_data[:primarykey]}, #{col_obj.primarykey?}\n" if args[:debug]
128
128
  dochange = true
129
129
  end
130
-
130
+
131
131
  if col_data.has_key?(:autoincr) and col_obj.autoincr? != col_data[:autoincr]
132
132
  print "Auto-increment mismatch for #{col_str}: #{col_data[:autoincr]}, #{col_obj.autoincr?}\n" if args[:debug]
133
133
  dochange = true
134
134
  end
135
-
135
+
136
136
  if col_data.has_key?(:maxlength) and col_obj.maxlength.to_s != col_data[:maxlength].to_s
137
137
  print "Maxlength mismatch on #{col_str}: #{col_data[:maxlength]}, #{col_obj.maxlength}\n" if args[:debug]
138
138
  dochange = true
139
139
  end
140
-
140
+
141
141
  if col_data.has_key?(:null) and col_obj.null?.to_s != col_data[:null].to_s
142
142
  print "Null mismatch on #{col_str}: #{col_data[:null]}, #{col_obj.null?}\n" if args[:debug]
143
143
  dochange = true
144
144
  end
145
-
145
+
146
146
  if col_data.has_key?(:default) and col_obj.default.to_s != col_data[:default].to_s
147
147
  print "Default mismatch on #{col_str}: #{col_data[:default]}, #{col_obj.default}\n" if args[:debug]
148
148
  dochange = true
149
149
  end
150
-
150
+
151
151
  if col_data.has_key?(:comment) and col_obj.respond_to?(:comment) and col_obj.comment.to_s != col_data[:comment].to_s
152
152
  print "Comment mismatch on #{col_str}: #{col_data[:comment]}, #{col_obj.comment}\n" if args[:debug]
153
153
  dochange = true
154
154
  end
155
-
155
+
156
156
  if col_data.is_a?(Hash) and col_data[:on_before_alter]
157
157
  callback_data = col_data[:on_before_alter].call(:db => db, :table => table_obj, :col => col_obj, :col_data => col_data)
158
158
  if callback_data and callback_data[:action]
@@ -161,24 +161,24 @@ class Baza::Revision
161
161
  end
162
162
  end
163
163
  end
164
-
164
+
165
165
  if dochange
166
166
  col_data_change = col_data.clone
167
167
  col_data_change.delete(:renames)
168
-
168
+
169
169
  col_obj.change(col_data_change)
170
-
170
+
171
171
  #Change has been made - update cache.
172
172
  cols = table_obj.columns
173
173
  end
174
-
174
+
175
175
  first_col = false
176
176
  rescue Errno::ENOENT => e
177
177
  print "Column not found: #{table_obj.name}.#{col_data[:name]}.\n" if args[:debug]
178
-
178
+
179
179
  if col_data.has_key?(:renames)
180
180
  raise "'renames' was not an array for column '#{table_obj.name}.#{col_data[:name]}'." if !col_data[:renames].is_a?(Array)
181
-
181
+
182
182
  rename_found = false
183
183
  col_data[:renames].each do |col_name|
184
184
  begin
@@ -186,47 +186,47 @@ class Baza::Revision
186
186
  rescue Errno::ENOENT => e
187
187
  next
188
188
  end
189
-
189
+
190
190
  print "Rename #{table_obj.name}.#{col_name} to #{table_obj.name}.#{col_data[:name]}\n" if args[:debug]
191
191
  if col_data.is_a?(Hash) and col_data[:on_before_rename]
192
192
  col_data[:on_before_rename].call(:db => db, :table => table_obj, :col => col_rename, :col_data => col_data)
193
193
  end
194
-
194
+
195
195
  col_data_change = col_data.clone
196
196
  col_data_change.delete(:renames)
197
-
197
+
198
198
  col_rename.change(col_data_change)
199
-
199
+
200
200
  #Change has been made - update cache.
201
201
  cols = table_obj.columns
202
-
202
+
203
203
  if col_data.is_a?(Hash) and col_data[:on_after_rename]
204
204
  col_data[:on_after_rename].call(:db => db, :table => table_obj, :col => col_rename, :col_data => col_data)
205
205
  end
206
-
206
+
207
207
  rename_found = true
208
208
  break
209
209
  end
210
-
210
+
211
211
  retry if rename_found
212
212
  end
213
-
213
+
214
214
  oncreated = col_data[:on_created]
215
215
  col_data.delete(:on_created) if col_data[:oncreated]
216
-
216
+
217
217
  col_data_create = col_data
218
218
  col_data_create.delete(:renames)
219
-
219
+
220
220
  col_obj = table_obj.create_columns([col_data])
221
-
221
+
222
222
  #Change has been made - update cache.
223
223
  cols = table_obj.columns
224
-
224
+
225
225
  oncreated.call(:db => db, :table => table_obj) if oncreated
226
226
  end
227
227
  end
228
228
  end
229
-
229
+
230
230
  if table_data[:columns_remove]
231
231
  table_data[:columns_remove].each do |column_name, column_data|
232
232
  begin
@@ -234,24 +234,24 @@ class Baza::Revision
234
234
  rescue Errno::ENOENT => e
235
235
  next
236
236
  end
237
-
237
+
238
238
  column_data[:callback].call if column_data.is_a?(Hash) and column_data[:callback]
239
239
  col_obj.drop
240
240
  end
241
241
  end
242
-
242
+
243
243
  if table_data[:indexes]
244
244
  table_data[:indexes].each do |index_data|
245
245
  if index_data.is_a?(String) or index_data.is_a?(Symbol)
246
246
  index_data = {:name => index_data, :columns => [index_data]}
247
247
  end
248
-
248
+
249
249
  begin
250
250
  index_obj = table_obj.index(index_data[:name])
251
-
251
+
252
252
  rewrite_index = false
253
253
  rewrite_index = true if index_data.key?(:unique) and index_data[:unique] != index_obj.unique?
254
-
254
+
255
255
  if rewrite_index
256
256
  index_obj.drop
257
257
  table_obj.create_indexes([index_data])
@@ -261,7 +261,7 @@ class Baza::Revision
261
261
  end
262
262
  end
263
263
  end
264
-
264
+
265
265
  if table_data[:indexes_remove]
266
266
  table_data[:indexes_remove].each do |index_name, index_data|
267
267
  begin
@@ -269,19 +269,19 @@ class Baza::Revision
269
269
  rescue Errno::ENOENT => e
270
270
  next
271
271
  end
272
-
272
+
273
273
  if index_data.is_a?(Hash) and index_data[:callback]
274
274
  index_data[:callback].call if index_data[:callback]
275
275
  end
276
-
276
+
277
277
  index_obj.drop
278
278
  end
279
279
  end
280
-
280
+
281
281
  rows_init(:db => db, :table => table_obj, :rows => table_data[:rows]) if table_data and table_data[:rows]
282
282
  rescue Errno::ENOENT => e
283
283
  puts "Table did not exist: '#{table_name}'." if args[:debug]
284
-
284
+
285
285
  if table_data.key?(:renames)
286
286
  table_data[:renames].each do |table_name_rename|
287
287
  begin
@@ -294,34 +294,34 @@ class Baza::Revision
294
294
  end
295
295
  end
296
296
  end
297
-
297
+
298
298
  if !table_data.key?(:columns)
299
- print "Notice: Skipping creation of '#{table_name}' because no columns were given in hash.\n"
299
+ puts "Notice: Skipping creation of '#{table_name}' because no columns were given in hash." if args[:debug]
300
300
  next
301
301
  end
302
-
302
+
303
303
  if table_data[:on_create]
304
304
  table_data[:on_create].call(:db => db, :table_name => table_name, :table_data => table_data)
305
305
  end
306
-
306
+
307
307
  table_data_create = table_data.clone
308
308
  table_data_create.delete(:rows)
309
-
309
+
310
310
  puts "Creating table: '#{table_name}'." if args[:debug]
311
311
  db.tables.create(table_name, table_data_create)
312
312
  table_obj = db.tables[table_name.to_sym]
313
-
313
+
314
314
  if table_data[:on_create_after]
315
315
  table_data[:on_create_after].call(:db => db, :table_name => table_name, :table_data => table_data)
316
316
  end
317
-
317
+
318
318
  rows_init(:db => db, :table => table_obj, :rows => table_data[:rows]) if table_data[:rows]
319
319
  end
320
320
  rescue Knj::Errors::Retry
321
321
  retry
322
322
  end
323
323
  end
324
-
324
+
325
325
  if schema[:tables_remove]
326
326
  schema[:tables_remove].each do |table_name, table_data|
327
327
  begin
@@ -333,28 +333,28 @@ class Baza::Revision
333
333
  end
334
334
  end
335
335
  end
336
-
337
-
336
+
337
+
338
338
  #Free cache.
339
339
  tables.clear if tables
340
340
  tables = nil
341
341
  end
342
-
342
+
343
343
  private
344
-
344
+
345
345
  ROWS_INIT_ALLOWED_ARGS = [:db, :table, :rows]
346
346
  #This method checks if certain rows are present in a table based on a hash.
347
347
  def rows_init(args)
348
348
  args.each do |key, val|
349
349
  raise "Invalid key: '#{key}' (#{key.class.name})." unless ROWS_INIT_ALLOWED_ARGS.include?(key)
350
350
  end
351
-
351
+
352
352
  db = args[:db]
353
353
  table = args[:table]
354
-
354
+
355
355
  raise "No db given." if !db
356
356
  raise "No table given." if !table
357
-
357
+
358
358
  args[:rows].each do |row_data|
359
359
  if row_data[:find_by]
360
360
  find_by = row_data[:find_by]
@@ -363,17 +363,17 @@ class Baza::Revision
363
363
  else
364
364
  raise "Could not figure out the find-by."
365
365
  end
366
-
366
+
367
367
  rows_found = 0
368
368
  args[:db].select(table.name, find_by) do |d_rows|
369
369
  rows_found += 1
370
-
370
+
371
371
  if Knj::ArrayExt.hash_diff?(Knj::ArrayExt.hash_sym(row_data[:data]), Knj::ArrayExt.hash_sym(d_rows), {"h2_to_h1" => false})
372
372
  print "Data was not right - updating row: #{JSON.generate(row_data[:data])}\n" if args[:debug]
373
373
  args[:db].update(table.name, row_data[:data], d_rows)
374
374
  end
375
375
  end
376
-
376
+
377
377
  if rows_found == 0
378
378
  print "Inserting row: #{JSON.generate(row_data[:data])}\n" if args[:debug]
379
379
  table.insert(row_data[:data])
data/lib/baza.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "string-cases"
2
+
1
3
  class Baza
2
4
  #Autoloader for subclasses.
3
5
  def self.const_missing(name)
@@ -6,4 +8,4 @@ class Baza
6
8
  raise "Still not defined: '#{name}'." if !Baza.const_defined?(name)
7
9
  return Baza.const_get(name)
8
10
  end
9
- end
11
+ end
data/shippable.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_script:
5
+ - cp spec/info_mysql_shippable.rb spec/info_mysql.rb
6
+ - cp spec/info_active_record_shippable.rb spec/info_active_record.rb
7
+ - mysql -e 'CREATE DATABASE baza;'
8
+ script:
9
+ - CODECLIMATE_REPO_TOKEN=98c06de7271764c9cd7bbde7cee4ddfa0d3e7db4bd9933f17779100276672e5f bundle exec rspec
10
+ notifications:
11
+ email: false
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+
3
+ describe Baza::Driver::ActiveRecord do
4
+ it_behaves_like "a baza driver"
5
+ it_should_behave_like "a baza tables driver"
6
+ it_should_behave_like "a baza columns driver"
7
+ it_should_behave_like "a baza indexes driver"
8
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Baza::Driver::Mysql do
4
+ it_should_behave_like "a baza driver"
5
+ it_should_behave_like "a baza tables driver"
6
+ it_should_behave_like "a baza columns driver"
7
+ it_should_behave_like "a baza indexes driver"
8
+
9
+ it "should dump to sqlite3" do
10
+ require "info_sqlite3"
11
+ require "info_mysql"
12
+
13
+ driver1 = Baza::InfoMysql.new
14
+ db1 = driver1.db
15
+ driver1.before
16
+
17
+ driver2 = Baza::InfoSqlite3.new
18
+ db2 = driver2.db
19
+ driver2.before
20
+
21
+ begin
22
+ db1.tables.create(:test_table, columns: [
23
+ {name: :id, type: :int, autoincr: true, primarykey: true},
24
+ {name: :name, type: :varchar, maxlength: 100}
25
+ ])
26
+ test_table = db1.tables[:test_table]
27
+
28
+
29
+ db1.copy_to(db2)
30
+
31
+ table_sqlite = db2.tables[:test_table]
32
+ table_sqlite.columns.length.should eq test_table.columns.length
33
+
34
+ col_id_sqlite = table_sqlite.column(:id)
35
+ col_id_sqlite.type.should eq :int
36
+ col_id_sqlite.autoincr?.should eq true
37
+ col_id_sqlite.primarykey?.should eq true
38
+
39
+ col_name_sqlite = table_sqlite.column(:name)
40
+ col_name_sqlite.type.should eq :varchar
41
+ col_name_sqlite.maxlength.to_i.should eq 100
42
+ ensure
43
+ driver1.after
44
+ driver2.after
45
+ end
46
+ end
47
+ end