rod 0.6.1 → 0.6.2

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.
Files changed (50) hide show
  1. data/.gitignore +7 -0
  2. data/{README → README.rdoc} +33 -2
  3. data/Rakefile +7 -2
  4. data/changelog.txt +13 -0
  5. data/contributors.txt +2 -0
  6. data/features/append.feature +221 -0
  7. data/features/assoc_indexing.feature +66 -0
  8. data/features/basic.feature +199 -0
  9. data/features/collection.feature +171 -0
  10. data/features/flat_indexing.feature +140 -0
  11. data/features/fred.feature +49 -0
  12. data/features/inheritence.feature +211 -0
  13. data/features/muliple_db.feature +113 -0
  14. data/features/relationships.feature +195 -0
  15. data/features/segmented_indexing.feature +172 -0
  16. data/features/steps/model.rb +386 -0
  17. data/features/steps/rod.rb +71 -0
  18. data/features/steps/test_helper.rb +5 -0
  19. data/lib/rod/abstract_database.rb +17 -5
  20. data/lib/rod/constants.rb +1 -1
  21. data/lib/rod/database.rb +95 -74
  22. data/lib/rod/join_element.rb +6 -2
  23. data/lib/rod/model.rb +37 -9
  24. data/rod.gemspec +15 -12
  25. data/tests/check_strings.rb +10 -0
  26. data/tests/class_compatibility_create.rb +14 -0
  27. data/tests/class_compatibility_verify.rb +18 -0
  28. data/tests/eff1_test.rb +60 -0
  29. data/tests/eff2_test.rb +61 -0
  30. data/tests/full_runs.rb +68 -0
  31. data/tests/generate_classes_create.rb +25 -0
  32. data/tests/generate_classes_model.rb +23 -0
  33. data/tests/generate_classes_rewrite.rb +7 -0
  34. data/tests/generate_classes_verify.rb +46 -0
  35. data/tests/load_struct.rb +24 -0
  36. data/tests/migration_create.rb +25 -0
  37. data/tests/migration_migrate.rb +22 -0
  38. data/tests/migration_model1.rb +23 -0
  39. data/tests/migration_model2.rb +27 -0
  40. data/tests/migration_verify.rb +56 -0
  41. data/tests/mock_tests.rb +128 -0
  42. data/tests/read_on_create.rb +45 -0
  43. data/tests/save_struct.rb +49 -0
  44. data/tests/structures.rb +52 -0
  45. data/tests/unit/database.rb +60 -0
  46. data/tests/unit/model.rb +36 -0
  47. data/tests/unit/model_tests.rb +116 -0
  48. data/tests/validate_read_on_create.rb +12 -0
  49. data/utils/convert_index.rb +31 -0
  50. metadata +77 -28
data/rod.gemspec CHANGED
@@ -4,24 +4,27 @@ require 'rod/constants'
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rod"
6
6
  s.version = Rod::VERSION
7
- s.date = "#{Time.now}"
7
+ s.date = "#{Time.now.strftime("%Y-%m-%d")}"
8
+ # TODO set to Linux/MacOSX and Ruby 1.9
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ['Aleksander Pohl']
11
+ s.email = ["apohllo@o2.pl"]
12
+ s.homepage = "http://github.com/apohllo/rod"
8
13
  s.summary = "Ruby object database"
9
- s.email = "apohllo@o2.pl"
10
- #s.homepage = "http://wierzba.wzks.uj.edu.pl/~mag/dilp"
11
14
  s.description = "Ruby object database is designed for large amount of data, whose structure rarely changes."
15
+
16
+ s.rubyforge_project = "rod"
17
+ s.rdoc_options = ["--main", "README.rdoc"]
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
22
  s.require_path = "lib"
13
- s.has_rdoc = true
14
- s.authors = ['Aleksander Pohl', 'Piotr Gurgul', 'Marcin Sieniek']
15
- s.files = ["Rakefile", "rod.gemspec", 'lib/rod.rb', 'README',
16
- 'changelog.txt', 'Gemfile'] + Dir.glob("lib/**/*")
17
- #s.test_files = Dir.glob("{test,spect}/**/*")
18
- #s.rdoc_options = ["--main", "README.txt"]
19
- #s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
23
+
20
24
  s.add_dependency("RubyInline", [">= 3.8.3","< 4.0.0"])
21
25
  s.add_dependency("english", [">= 0.5.0","< 0.6.0"])
22
26
  s.add_dependency("activemodel", [">= 3.0.7","< 3.1.0"])
23
27
  s.add_development_dependency("mocha", [">= 0.9.8","< 1.0.0"])
24
- s.add_development_dependency("cucumber", [">= 0.9.4","< 0.10.0"])
28
+ s.add_development_dependency("cucumber", "~> 1.0.0")
25
29
  s.add_development_dependency("rspec", [">= 2.2.0","< 2.3.0"])
26
30
  end
27
-
@@ -0,0 +1,10 @@
1
+ $:.unshift("tests")
2
+ require 'structures'
3
+ require 'validate_read_on_create'
4
+
5
+ Rod::Database.development_mode = true
6
+ RodTest::Database.instance.open_database("tmp/read_write")
7
+ MAGNITUDO.times do |index|
8
+ validate(index,RodTest::MyStruct[index])
9
+ end
10
+ RodTest::Database.instance.close_database
@@ -0,0 +1,14 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+
4
+ Rod::Database.development_mode = true
5
+ class TestDatabase < Rod::Database
6
+ end
7
+
8
+ class TestClass < Rod::Model
9
+ field :test, :string
10
+ database_class TestDatabase
11
+ end
12
+
13
+ TestDatabase.instance.create_database("tmp/class_compatibility")
14
+ TestDatabase.instance.close_database
@@ -0,0 +1,18 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+
4
+ Rod::Database.development_mode = true
5
+ class TestDatabase < Rod::Database
6
+ end
7
+
8
+ class TestClass < Rod::Model
9
+ field :test, :integer
10
+ database_class TestDatabase
11
+ end
12
+
13
+ begin
14
+ TestDatabase.instance.open_database("tmp/class_compatibility")
15
+ raise "Should raise an error"
16
+ rescue Rod::IncompatibleVersion => ex
17
+ # ok, this should be thrown
18
+ end
@@ -0,0 +1,60 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+
4
+ module RodTest
5
+ class Model < Rod::Model
6
+ end
7
+
8
+ %w{A B C D E}.each do |letter|
9
+ klass = Class.new(Model) do
10
+ 10.times do |i|
11
+ field "a#{i}".to_sym, :ulong
12
+ end
13
+
14
+ end
15
+ const_set("#{letter}Struct",klass)
16
+ klass.send(:build_structure)
17
+ end
18
+
19
+ class EffectivenessTest
20
+
21
+ MAGNITUDE = 100000
22
+ FILENAME = "tmp/eff1"
23
+
24
+ def setup
25
+ Model.create_database(FILENAME)
26
+ @structs = {}
27
+ %w{A B C D E}.each do |letter|
28
+ @structs[letter.to_sym] = []
29
+ (MAGNITUDE).times do |i|
30
+ @structs[letter.to_sym][i] = RodTest.const_get("#{letter}Struct").new
31
+ 10.times do |j|
32
+ @structs[letter.to_sym][i].send("a#{j}=",j)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def main
39
+ start_t = Time.now.to_f
40
+ %w{A B C D E}.each do |letter|
41
+ (MAGNITUDE / 2).times {|i| @structs[letter.to_sym][i].store }
42
+ end
43
+ %w{A B C D E}.each do |letter|
44
+ (MAGNITUDE / 2).times {|i| @structs[letter.to_sym][MAGNITUDE/2 + i].store }
45
+ end
46
+ end_t = Time.now.to_f
47
+ puts "Storing the objects in the DB took #{end_t - start_t} seconds"
48
+
49
+ start_t = Time.now.to_f
50
+ Model.close_database
51
+ end_t = Time.now.to_f
52
+
53
+ puts "Closing the DB took #{end_t - start_t} seconds"
54
+ end
55
+ end
56
+ end
57
+
58
+ e = RodTest::EffectivenessTest.new
59
+ e.setup
60
+ e.main
@@ -0,0 +1,61 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+
4
+ module RodTest
5
+ class Model < Rod::Model
6
+ end
7
+
8
+ %w{E D C B A}.each do |letter|
9
+ klass = Class.new(Model) do
10
+ 10.times do |i|
11
+ field "a#{i}".to_sym, :ulong
12
+ end
13
+
14
+ end
15
+ const_set("#{letter}Struct",klass)
16
+ klass.send(:build_structure)
17
+ end
18
+
19
+ class EffectivenessTest
20
+
21
+ MAGNITUDE = 100000
22
+ FILENAME = "tmp/eff2"
23
+
24
+ def setup
25
+ @structs = {}
26
+ %w{A B C D E}.each do |letter|
27
+ @structs[letter.to_sym] = []
28
+ (MAGNITUDE).times do |i|
29
+ @structs[letter.to_sym][i] = RodTest.const_get("#{letter}Struct").new
30
+ 10.times do |j|
31
+ @structs[letter.to_sym][i].send("a#{j}=",j)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def main
38
+ start_t = Time.now.to_f
39
+ Model.create_database(FILENAME)
40
+ %w{A B C D E}.each do |letter|
41
+ (MAGNITUDE / 2).times {|i| @structs[letter.to_sym][i].store }
42
+ end
43
+ %w{A B C D E}.each do |letter|
44
+ (MAGNITUDE / 2).times {|i| @structs[letter.to_sym][MAGNITUDE/2 + i].store }
45
+ end
46
+ end_t = Time.now.to_f
47
+ puts "Storing the objects in the DB took #{end_t - start_t} seconds"
48
+
49
+ start_t = Time.now.to_f
50
+ Model.close_database
51
+ end_t = Time.now.to_f
52
+
53
+ puts "Closing the DB took #{end_t - start_t} seconds"
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ e = RodTest::EffectivenessTest.new
60
+ e.setup
61
+ e.main
@@ -0,0 +1,68 @@
1
+ $:.unshift("tests")
2
+ $:.unshift("lib")
3
+ require 'structures'
4
+ require 'rod'
5
+ require 'test/unit'
6
+
7
+ module RodTest
8
+ class FullRuns < Test::Unit::TestCase
9
+
10
+ MAGNITUDE = 10000
11
+ def setup
12
+ @test_filename = "tmp/noncontinuous_pages"
13
+ Model.create_database(@test_filename)
14
+ @hs = []
15
+ (MAGNITUDE).times do |i|
16
+ @hs[i] = HisStruct.new
17
+ @hs[i].inde = i
18
+ end
19
+
20
+ @ys = []
21
+ (MAGNITUDE).times do |i|
22
+ @ys[i] = YourStruct.new
23
+ @ys[i].counter = 10
24
+ @ys[i].his_structs = @hs[i*10...(i+1)*10]
25
+ end
26
+
27
+ @ms = []
28
+ (MAGNITUDE * 10).times do |i|
29
+ @ms[i] = MyStruct.new
30
+ @ms[i].count = 10 * i
31
+ @ms[i].precision = 0.1 * i
32
+ @ms[i].identifier = i
33
+ @ms[i].your_struct = @ys[i]
34
+ @ms[i].title = "title_#{i}"
35
+ @ms[i].body = "body_#{i}"
36
+ end
37
+ end
38
+
39
+
40
+ def test_noncontinuous_pages
41
+
42
+ #creation
43
+ (0..2).each do |j|
44
+ @ms.each_index do |i|
45
+ @ms[i].store if i % 3 == j
46
+ end
47
+ @ys.each_index do |i|
48
+ @ys[i].store if i % 3 == j
49
+ end
50
+ @hs.each_index do |i|
51
+ @hs[i].store if i % 3 == j
52
+ end
53
+ end
54
+ Model.close_database
55
+
56
+ # verification
57
+ Model.open_database(@test_filename)
58
+ assert MyStruct.count == @ms.count,
59
+ "MyStruct: should be #{@ms.count}, was #{MyStruct.count}!"
60
+ assert YourStruct.count == @ys.count,
61
+ "YourStruct: should be #{@ys.count}, was #{YourStruct.count}!"
62
+ assert HisStruct.count == @hs.count,
63
+ "HisStruct: should be #{@hs.count}, was #{HisStruct.count}!"
64
+ Model.close_database
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,25 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+ require File.join(".",File.dirname(__FILE__),"generate_classes_model")
4
+
5
+ Rod::Database.development_mode = true
6
+
7
+
8
+ Database.instance.create_database("tmp/generate_classes")
9
+
10
+ files = 10.times.map{|i| UserFile.new(:data => "#{i} data")}
11
+ files.each{|f| f.store}
12
+
13
+ account = Account.new(:login => "john")
14
+ account.store
15
+ user = User.new(:name => "John", :account => account,
16
+ :files => [files[0],files[1],files[2]])
17
+ user.store
18
+
19
+ account = Account.new(:login => "amanda")
20
+ account.store
21
+ user = User.new(:name => "Amanda", :account => account,
22
+ :files => [files[0],files[4],files[5],nil,files[6]])
23
+ user.store
24
+
25
+ Database.instance.close_database
@@ -0,0 +1,23 @@
1
+ require 'rod'
2
+
3
+ class Database < Rod::Database
4
+ end
5
+
6
+ class Model < Rod::Model
7
+ database_class Database
8
+ end
9
+
10
+ class User < Model
11
+ field :name, :string, :index => :flat
12
+ has_one :account, :index => :flat
13
+ has_many :files, :index => :flat, :class_name => "UserFile"
14
+ end
15
+
16
+ class Account < Model
17
+ field :login, :string
18
+ end
19
+
20
+ class UserFile < Model
21
+ field :data, :string
22
+ end
23
+
@@ -0,0 +1,7 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+ require File.join(".",File.dirname(__FILE__),"generate_classes_model")
4
+
5
+ Rod::Database.development_mode = true
6
+ Database.instance.open_database("tmp/generate_classes",:readonly => false)
7
+ Database.instance.close_database
@@ -0,0 +1,46 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+ require 'rspec/expectations'
4
+
5
+ module RodTest
6
+ end
7
+
8
+ Rod::Database.development_mode = true
9
+
10
+ Rod::Database.instance.open_database("tmp/generate_classes",:generate => RodTest)
11
+
12
+ user = RodTest::User[0]
13
+ user = RodTest::User.find_by_name("John")
14
+ user.should_not == nil
15
+ user.name.should == "John"
16
+ user.account.should_not == nil
17
+ user.account.should == RodTest::Account[0]
18
+ user.files.size.should == 3
19
+
20
+ account = RodTest::Account[0]
21
+ account.login.should == "john"
22
+ RodTest::User.find_all_by_account(account).size.should == 1
23
+ RodTest::User.find_all_by_account(account)[0].should == user
24
+ RodTest::User.find_by_account(account).should_not == nil
25
+ user.account.should == account
26
+
27
+ user = RodTest::User.find_by_name("Amanda")
28
+ user.should_not == nil
29
+ user.name.should == "Amanda"
30
+ user.account.should_not == nil
31
+ user.files.size.should == 5
32
+
33
+ account = RodTest::Account[1]
34
+ account.login.should == "amanda"
35
+ RodTest::User.find_by_account(account).should_not == nil
36
+ user.account.should == account
37
+
38
+ file = RodTest::UserFile[0]
39
+ file.data.should == "0 data"
40
+
41
+ RodTest::UserFile.each{|f| f.data.should_not == nil}
42
+ users = RodTest::User.find_all_by_files(file)
43
+ users.size.should == 2
44
+ users[1].should == user
45
+
46
+ Rod::Database.instance.close_database
@@ -0,0 +1,24 @@
1
+ $:.unshift("tests")
2
+ require 'structures'
3
+
4
+ puts "-- Load sample structures test --"
5
+
6
+ Rod::Database.development_mode = true
7
+ RodTest::Database.instance.open_database("tmp/abc")
8
+ RodTest::Database.instance.print_layout
9
+ puts RodTest::MyStruct.count
10
+ puts RodTest::YourStruct.count
11
+ puts RodTest::HisStruct.count
12
+ index = 0
13
+ RodTest::MyStruct.each do |object|
14
+ index += 1
15
+ puts index if index % 1000 == 0
16
+ object.to_s
17
+ end
18
+ RodTest::YourStruct.each do |object|
19
+ object.to_s
20
+ end
21
+
22
+ puts RodTest::MyStruct.find_by_title("title_10")
23
+
24
+ RodTest::Database.instance.close_database
@@ -0,0 +1,25 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+ require File.join(".",File.dirname(__FILE__),"migration_model1")
4
+
5
+ Rod::Database.development_mode = true
6
+
7
+
8
+ Database.instance.create_database("tmp/migration")
9
+
10
+ files = 10.times.map{|i| UserFile.new(:data => "#{i} data")}
11
+ files.each{|f| f.store}
12
+
13
+ account = Account.new(:login => "john")
14
+ account.store
15
+ user = User.new(:name => "John", :account => account,
16
+ :files => [files[0],files[1],files[2]])
17
+ user.store
18
+
19
+ account = Account.new(:login => "amanda")
20
+ account.store
21
+ user = User.new(:name => "Amanda", :account => account,
22
+ :files => [files[0],files[4],files[5],nil,files[6]])
23
+ user.store
24
+
25
+ Database.instance.close_database
@@ -0,0 +1,22 @@
1
+ $:.unshift("lib")
2
+ require 'rod'
3
+ require File.join(".",File.dirname(__FILE__),"migration_model2")
4
+ require 'rspec/expectations'
5
+
6
+ $ROD_DEBUG = true
7
+ Rod::Database.development_mode = true
8
+
9
+ Database.instance.open_database("tmp/migration", :migrate => true,
10
+ :readonly => false)
11
+
12
+ user = User[0]
13
+ user.accounts << Account[0]
14
+ user.store
15
+
16
+ user = User[1]
17
+ user.accounts << Account[1]
18
+ user.store
19
+
20
+ Database.instance.close_database
21
+
22
+ test(?f,"tmp/migration/#{Rod::DATABASE_FILE}#{Rod::LEGACY_DATA_SUFFIX}").should == true