baza 0.0.4 → 0.0.5

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.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ source "http://rubygems.org"
6
6
  gem "datet"
7
7
  gem "wref"
8
8
  gem "knjrbfw"
9
+ gem "array_enumerator"
9
10
 
10
11
  # Add dependencies to develop your gem here.
11
12
  # Include everything needed to run rake, tests, features, etc.
@@ -1,6 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ array_enumerator (0.0.3)
4
5
  datet (0.0.25)
5
6
  diff-lcs (1.1.3)
6
7
  git (1.2.5)
@@ -46,6 +47,7 @@ PLATFORMS
46
47
  ruby
47
48
 
48
49
  DEPENDENCIES
50
+ array_enumerator
49
51
  bundler (>= 1.0.0)
50
52
  datet
51
53
  jeweler (~> 1.8.4)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "baza"
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
@@ -56,6 +56,7 @@ Gem::Specification.new do |s|
56
56
  "spec/db_spec_encoding_test_file.txt",
57
57
  "spec/info_mysql_example.rb",
58
58
  "spec/info_sqlite3.rb",
59
+ "spec/model_handler_spec.rb",
59
60
  "spec/spec_helper.rb"
60
61
  ]
61
62
  s.homepage = "http://github.com/kaspernj/baza"
@@ -71,6 +72,7 @@ Gem::Specification.new do |s|
71
72
  s.add_runtime_dependency(%q<datet>, [">= 0"])
72
73
  s.add_runtime_dependency(%q<wref>, [">= 0"])
73
74
  s.add_runtime_dependency(%q<knjrbfw>, [">= 0"])
75
+ s.add_runtime_dependency(%q<array_enumerator>, [">= 0"])
74
76
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
75
77
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
76
78
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
@@ -81,6 +83,7 @@ Gem::Specification.new do |s|
81
83
  s.add_dependency(%q<datet>, [">= 0"])
82
84
  s.add_dependency(%q<wref>, [">= 0"])
83
85
  s.add_dependency(%q<knjrbfw>, [">= 0"])
86
+ s.add_dependency(%q<array_enumerator>, [">= 0"])
84
87
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
85
88
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
86
89
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -92,6 +95,7 @@ Gem::Specification.new do |s|
92
95
  s.add_dependency(%q<datet>, [">= 0"])
93
96
  s.add_dependency(%q<wref>, [">= 0"])
94
97
  s.add_dependency(%q<knjrbfw>, [">= 0"])
98
+ s.add_dependency(%q<array_enumerator>, [">= 0"])
95
99
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
96
100
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
97
101
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -421,11 +421,11 @@ class Baza::Driver::Sqlite3::Tables::Table
421
421
  end
422
422
 
423
423
  index_arr.each do |index_data|
424
- if index_data.is_a?(String)
424
+ if index_data.is_a?(String) or index_data.is_a?(Symbol)
425
425
  index_data = {:name => index_data, :columns => [index_data]}
426
426
  end
427
427
 
428
- raise "No name was given in data: '#{index_data}'." if !index_data.key?(:name) or index_data[:name].strip.empty?
428
+ raise "No name was given in data: '#{index_data}'." if !index_data.key?(:name) or index_data[:name].to_s.strip.empty?
429
429
  raise "No columns was given on index #{index_data[:name]}." if index_data[:columns].empty?
430
430
 
431
431
  name = index_data[:name]
@@ -1,3 +1,5 @@
1
+ require "#{File.dirname(__FILE__)}/model_handler_sqlhelper.rb"
2
+
1
3
  class Baza::ModelHandler
2
4
  attr_reader :args, :events, :data, :ids_cache, :ids_cache_should
3
5
 
@@ -47,6 +47,8 @@ class Baza::QueryBuffer
47
47
  def update(table, update, terms)
48
48
  STDOUT.puts "Update called on table #{table}." if @debug
49
49
  self.query(@args[:db].update(table, update, terms, :return_sql => true))
50
+ self.flush if @queries_count >= 1000
51
+ return nil
50
52
  end
51
53
 
52
54
  #Shortcut to doing upsert through the buffer instead of through the db-object with the buffer as an argument.
@@ -54,18 +56,15 @@ class Baza::QueryBuffer
54
56
  # buffer.upsert(:users, {:id => 5}, {:name => "Kasper"})
55
57
  def upsert(table, data, terms)
56
58
  @args[:db].upsert(table, data, terms, :buffer => self)
59
+ self.flush if @queries_count >= 1000
60
+ return nil
57
61
  end
58
62
 
59
63
  #Plans to inset a hash into a table. It will only be inserted when flush is called.
60
64
  #===Examples
61
65
  # buffer.insert(:users, {:name => "John Doe"})
62
66
  def insert(table, data)
63
- @lock.synchronize do
64
- @inserts[table] = [] if !@inserts.key?(table)
65
- @inserts[table] << data
66
- @queries_count += 1
67
- end
68
-
67
+ self.query(@args[:db].insert(table, data, :return_sql => true))
69
68
  self.flush if @queries_count >= 1000
70
69
  return nil
71
70
  end
@@ -0,0 +1,394 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require "tmpdir"
3
+
4
+ describe "Objects" do
5
+ it "should be able to cache rows" do
6
+ begin
7
+ require "#{File.dirname(__FILE__)}/../../array_enumerator/lib/array_enumerator"
8
+ rescue LoadError
9
+ require "array_enumerator"
10
+ end
11
+
12
+ require "sqlite3" if RUBY_ENGINE != "jruby"
13
+
14
+ $db_path = "#{Dir.tmpdir}/knjrbfw_objects_cache_test.sqlite3"
15
+ File.unlink($db_path) if File.exists?($db_path)
16
+ $db = Baza::Db.new(:type => :sqlite3, :path => $db_path, :return_keys => "symbols", :debug => false)
17
+
18
+ schema = {
19
+ :tables => {
20
+ "Group" => {
21
+ :columns => [
22
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
23
+ {:name => :groupname, :type => :varchar}
24
+ ]
25
+ },
26
+ "User" => {
27
+ :columns => [
28
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
29
+ {:name => :username, :type => :varchar}
30
+ ]
31
+ }
32
+ }
33
+ }
34
+ Baza::Revision.new.init_db(:schema => schema, :db => $db)
35
+
36
+ class User < Baza::Model; end
37
+
38
+ $ob = Baza::ModelHandler.new(
39
+ :db => $db,
40
+ :datarow => true,
41
+ :require => false,
42
+ :array_enum => true,
43
+ :models => {
44
+ :User => {
45
+ :cache_ids => true
46
+ }
47
+ }
48
+ )
49
+
50
+ $ob.adds(:User, [
51
+ {:username => "User 1"},
52
+ {:username => "User 2"},
53
+ {:username => "User 3"},
54
+ {:username => "User 4"},
55
+ {:username => "User 5"}
56
+ ])
57
+
58
+ raise "Expected user-ID-cache to be 5 but it wasnt: #{$ob.ids_cache[:User].length}" if $ob.ids_cache[:User].length != 5
59
+
60
+ user = $ob.get(:User, 4)
61
+ raise "No user returned." if !user
62
+ $ob.delete(user)
63
+ raise "Expected user-ID-cache to be 4 but it wasnt: #{$ob.ids_cache[:User].length} #{$ob.ids_cache}" if $ob.ids_cache[:User].length != 4
64
+
65
+ $ob.deletes([$ob.get(:User, 1), $ob.get(:User, 2)])
66
+ raise "Expected user-ID-cache to be 2 but it wasnt: #{$ob.ids_cache[:User].length} #{$ob.ids_cache}" if $ob.ids_cache[:User].length != 2
67
+ end
68
+
69
+ it "should be able to do 'select_col_as_array'" do
70
+ res = $ob.list(:User, {"select_col_as_array" => "id"}).to_a
71
+ raise "Expected length of 2 but got: #{res.length}" if res.length != 2
72
+ end
73
+
74
+ it "should work even though stressed by threads (thread-safe)." do
75
+ userd = []
76
+ 10.upto(25) do |i|
77
+ userd << {:username => "User #{i}"}
78
+ end
79
+
80
+ $ob.adds(:User, userd)
81
+ users = $ob.list(:User).to_a
82
+
83
+ #Stress it to test threadsafety...
84
+ threads = []
85
+ 0.upto(5) do |tc|
86
+ threads << Knj::Thread.new do
87
+ 0.upto(5) do |ic|
88
+ user = $ob.add(:User, {:username => "User #{tc}-#{ic}"})
89
+ raise "No user returned." if !user
90
+ $ob.delete(user)
91
+
92
+ user1 = $ob.add(:User, {:username => "User #{tc}-#{ic}-1"})
93
+ user2 = $ob.add(:User, {:username => "User #{tc}-#{ic}-2"})
94
+ user3 = $ob.add(:User, {:username => "User #{tc}-#{ic}-3"})
95
+
96
+ raise "Missing user?" if !user1 or !user2 or !user3 or user1.deleted? or user2.deleted? or user3.deleted?
97
+ $ob.deletes([user1, user2, user3])
98
+
99
+ count = 0
100
+ users.each do |user|
101
+ count += 1
102
+ user[:username] = "#{user[:username]}." if !user.deleted?
103
+ end
104
+
105
+ raise "Expected at least 15 users but got #{count}." if count != 18
106
+ end
107
+ end
108
+ end
109
+
110
+ threads.each do |thread|
111
+ thread.join
112
+ end
113
+ end
114
+
115
+ it "should be able to skip queries when adding" do
116
+ class Group < Baza::Model; end
117
+
118
+ $ob2 = Baza::ModelHandler.new(
119
+ :db => $db,
120
+ :datarow => true,
121
+ :require => false
122
+ )
123
+
124
+ threads = []
125
+ 0.upto(5) do
126
+ threads << Knj::Thread.new do
127
+ 0.upto(5) do
128
+ ret = $ob2.add(:Group, {:groupname => "User 1"}, {:skip_ret => true})
129
+ raise "Expected empty return but got something: #{ret}" if ret
130
+ end
131
+ end
132
+ end
133
+
134
+ threads.each do |thread|
135
+ thread.join
136
+ end
137
+ end
138
+
139
+ it "should delete the temporary database." do
140
+ File.unlink($db_path) if File.exists?($db_path)
141
+ end
142
+
143
+ #Moved from "knjrbfw_spec.rb"
144
+ it "should be able to generate a sample SQLite database and add a sample table, with sample columns and with a sample index to it" do
145
+ $db_path = "#{Knj::Os.tmpdir}/knjrbfw_test_sqlite3.sqlite3"
146
+ $db = Baza::Db.new(
147
+ :type => :sqlite3,
148
+ :path => $db_path,
149
+ :index_append_table_name => true
150
+ )
151
+
152
+ $db.tables.create("Project", {
153
+ :columns => [
154
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
155
+ {:name => :category_id, :type => :int},
156
+ {:name => :name, :type => :varchar}
157
+ ],
158
+ :indexes => [
159
+ {:name => :category_id, :columns => [:category_id]}
160
+ ]
161
+ })
162
+
163
+ $db.tables.create("Task", {
164
+ :columns => [
165
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
166
+ {:name => :project_id, :type => :int},
167
+ {:name => :person_id, :type => :int},
168
+ {:name => :name, :type => :varchar}
169
+ ],
170
+ :indexes => [
171
+ {:name => :project_id, :columns => [:project_id]}
172
+ ]
173
+ })
174
+
175
+ $db.tables.create("Person", {
176
+ :columns => [
177
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
178
+ {:name => :name, :type => :varchar}
179
+ ]
180
+ })
181
+
182
+ $db.tables.create("Timelog", {
183
+ :columns => [
184
+ {:name => :id, :type => :int, :autoincr => true, :primarykey => true},
185
+ {:name => :person_id, :type => :int}
186
+ ],
187
+ :indexes => [
188
+ :person_id
189
+ ]
190
+ })
191
+
192
+ table = $db.tables[:Project]
193
+
194
+ indexes = table.indexes
195
+ raise "Could not find the sample-index 'category_id' that should have been created." if !indexes[:Project__category_id]
196
+
197
+
198
+ #If we insert a row the ID should increase and the name should be the same as inserted (or something is very very wrong)...
199
+ $db.insert("Project", {
200
+ "name" => "Test project"
201
+ })
202
+
203
+ count = 0
204
+ $db.q("SELECT * FROM Project") do |d|
205
+ raise "Somehow name was not 'Test project'" if d[:name] != "Test project"
206
+ raise "ID was not set?" if d[:id].to_i <= 0
207
+ count += 1
208
+ end
209
+
210
+ raise "Expected count of 1 but it wasnt: #{count}" if count != 1
211
+ end
212
+
213
+ it "should be able to automatic generate methods on datarow-classes (has_many, has_one)." do
214
+ class Project < Baza::Model
215
+ has_many [
216
+ {:class => :Task, :col => :project_id, :depends => true}
217
+ ]
218
+ end
219
+
220
+ class Task < Baza::Model
221
+ has_one [
222
+ {:class => :Person, :required => true},
223
+ :Project
224
+ ]
225
+ end
226
+
227
+ class Person < Baza::Model
228
+ has_one [:Project]
229
+
230
+ has_many [
231
+ {:class => :Timelog, :autozero => true}
232
+ ]
233
+
234
+ def html
235
+ return self[:name]
236
+ end
237
+ end
238
+
239
+ class Timelog < Baza::Model
240
+
241
+ end
242
+
243
+ $ob = Baza::ModelHandler.new(:db => $db, :datarow => true, :require => false)
244
+
245
+ $ob.add(:Person, {
246
+ :name => "Kasper"
247
+ })
248
+ $ob.add(:Task, {
249
+ :name => "Test task",
250
+ :person_id => 1,
251
+ :project_id => 1
252
+ })
253
+
254
+ begin
255
+ $obb.add(:Task, {:name => "Test task"})
256
+ raise "Method should fail but didnt."
257
+ rescue
258
+ #ignore.
259
+ end
260
+
261
+
262
+ #Test 'list_invalid_required'.
263
+ $db.insert(:Task, :name => "Invalid require")
264
+ id = $db.last_id
265
+ found = false
266
+
267
+ $ob.list_invalid_required(:class => :Task) do |d|
268
+ raise "Expected object ID to be #{id} but it wasnt: #{d[:obj].id}" if d[:obj].id.to_i != id.to_i
269
+ $ob.delete(d[:obj])
270
+ found = true
271
+ end
272
+
273
+ raise "Expected to find a task but didnt." if !found
274
+
275
+
276
+ ret_proc = []
277
+ $ob.list(:Task) do |task|
278
+ ret_proc << task
279
+ end
280
+
281
+ raise "list with proc should return one task but didnt." if ret_proc.length != 1
282
+
283
+
284
+ project = $ob.get(:Project, 1)
285
+
286
+ tasks = project.tasks
287
+ raise "No tasks were found on project?" if tasks.empty?
288
+
289
+
290
+ ret_proc = []
291
+ ret_test = project.tasks do |task|
292
+ ret_proc << task
293
+ end
294
+
295
+ raise "When given a block the return should be nil so it doesnt hold weak-ref-objects in memory but it didnt return nil." if ret_test != nil
296
+ raise "list for project with proc should return one task but didnt (#{ret_proc.length})." if ret_proc.length != 1
297
+
298
+ person = tasks.first.person
299
+ project_second = tasks.first.project
300
+
301
+ raise "Returned object was not a person on task." if !person.is_a?(Person)
302
+ raise "Returned object was not a project on task." if !project_second.is_a?(Project)
303
+
304
+
305
+ #Check that has_many-depending is actually working.
306
+ begin
307
+ $ob.delete(project)
308
+ raise "It was possible to delete project 1 even though task 1 depended on it!"
309
+ rescue
310
+ #this should happen - it should not possible to delete project 1 because task 1 depends on it."
311
+ end
312
+ end
313
+
314
+ it "should be able to generate lists for inputs" do
315
+ Knj::Web.inputs([{
316
+ :title => "Test 3",
317
+ :name => :seltest3,
318
+ :type => :select,
319
+ :default => 1,
320
+ :opts => $ob.list_optshash(:Task)
321
+ }])
322
+ end
323
+
324
+ it "should be able to connect to objects 'no-html' callback and test it." do
325
+ task = $ob.get(:Task, 1)
326
+ $ob.events.connect(:no_html) do |event, classname|
327
+ "[no #{classname.to_s.downcase}]"
328
+ end
329
+
330
+ raise "Unexpected person_html from task (should have been 'Kasper'): '#{task.person_html}'." if task.person_html != "Kasper"
331
+ task.update(:person_id => 0)
332
+ raise "Unexpected person_html from task (should have been '[no person]')." if task.person_html != "[no person]"
333
+ end
334
+
335
+ it "should be able to to multiple additions and delete objects through a buffer" do
336
+ objs = []
337
+ 0.upto(500) do
338
+ objs << {:name => :Kasper}
339
+ end
340
+
341
+ $ob.adds(:Person, objs)
342
+ pers_length = $ob.list(:Person, "count" => true)
343
+
344
+ count = 0
345
+ $db.q_buffer do |buffer|
346
+ $ob.list(:Person) do |person|
347
+ count += 1
348
+ $ob.delete(person, :db_buffer => buffer)
349
+ end
350
+
351
+ buffer.flush
352
+ end
353
+
354
+ raise "Expected count to be #{pers_length} but it wasnt: #{count}" if count != pers_length
355
+
356
+ persons = $ob.list(:Person).to_a
357
+ raise "Expected persons count to be 0 but it wasnt: #{persons.map{|e| e.data} }" if persons.length > 0
358
+ end
359
+
360
+ it "should do autozero when deleting objects" do
361
+ person1 = $ob.add(:Person, {
362
+ :name => "Kasper"
363
+ })
364
+ person2 = $ob.add(:Person, {
365
+ :name => "Charlotte"
366
+ })
367
+
368
+ timelog1 = $ob.add(:Timelog, {
369
+ :person_id => person1.id
370
+ })
371
+ timelog2 = $ob.add(:Timelog, {
372
+ :person_id => person2.id
373
+ })
374
+
375
+ $ob.delete(person1)
376
+
377
+ raise "Expected timelog1's person-ID to be zero but it wasnt: '#{timelog1[:person_id]}'." if timelog1[:person_id].to_i != 0
378
+ raise "Expected timelog2's person-ID to be #{person2.id} but it wasnt: '#{timelog2[:person_id]}'." if timelog2[:person_id].to_i != person2.id.to_i
379
+ end
380
+
381
+ it "should be able to do multiple deletes from ids" do
382
+ ids = []
383
+ 1.upto(10) do |count|
384
+ ids << $ob.add(:Person).id
385
+ end
386
+
387
+ $ob.delete_ids(:class => :Person, :ids => ids)
388
+ end
389
+
390
+ it "should delete the temp database again." do
391
+ db_path = "#{Knj::Os.tmpdir}/knjrbfw_test_sqlite3.sqlite3"
392
+ File.unlink(db_path) if File.exists?(db_path)
393
+ end
394
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baza
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: array_enumerator
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: rspec
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -202,6 +218,7 @@ files:
202
218
  - spec/db_spec_encoding_test_file.txt
203
219
  - spec/info_mysql_example.rb
204
220
  - spec/info_sqlite3.rb
221
+ - spec/model_handler_spec.rb
205
222
  - spec/spec_helper.rb
206
223
  homepage: http://github.com/kaspernj/baza
207
224
  licenses:
@@ -218,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
235
  version: '0'
219
236
  segments:
220
237
  - 0
221
- hash: 3400246052753672673
238
+ hash: -3065201151015911898
222
239
  required_rubygems_version: !ruby/object:Gem::Requirement
223
240
  none: false
224
241
  requirements: