rod 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/{README → README.rdoc} +33 -2
- data/Rakefile +7 -2
- data/changelog.txt +13 -0
- data/contributors.txt +2 -0
- data/features/append.feature +221 -0
- data/features/assoc_indexing.feature +66 -0
- data/features/basic.feature +199 -0
- data/features/collection.feature +171 -0
- data/features/flat_indexing.feature +140 -0
- data/features/fred.feature +49 -0
- data/features/inheritence.feature +211 -0
- data/features/muliple_db.feature +113 -0
- data/features/relationships.feature +195 -0
- data/features/segmented_indexing.feature +172 -0
- data/features/steps/model.rb +386 -0
- data/features/steps/rod.rb +71 -0
- data/features/steps/test_helper.rb +5 -0
- data/lib/rod/abstract_database.rb +17 -5
- data/lib/rod/constants.rb +1 -1
- data/lib/rod/database.rb +95 -74
- data/lib/rod/join_element.rb +6 -2
- data/lib/rod/model.rb +37 -9
- data/rod.gemspec +15 -12
- data/tests/check_strings.rb +10 -0
- data/tests/class_compatibility_create.rb +14 -0
- data/tests/class_compatibility_verify.rb +18 -0
- data/tests/eff1_test.rb +60 -0
- data/tests/eff2_test.rb +61 -0
- data/tests/full_runs.rb +68 -0
- data/tests/generate_classes_create.rb +25 -0
- data/tests/generate_classes_model.rb +23 -0
- data/tests/generate_classes_rewrite.rb +7 -0
- data/tests/generate_classes_verify.rb +46 -0
- data/tests/load_struct.rb +24 -0
- data/tests/migration_create.rb +25 -0
- data/tests/migration_migrate.rb +22 -0
- data/tests/migration_model1.rb +23 -0
- data/tests/migration_model2.rb +27 -0
- data/tests/migration_verify.rb +56 -0
- data/tests/mock_tests.rb +128 -0
- data/tests/read_on_create.rb +45 -0
- data/tests/save_struct.rb +49 -0
- data/tests/structures.rb +52 -0
- data/tests/unit/database.rb +60 -0
- data/tests/unit/model.rb +36 -0
- data/tests/unit/model_tests.rb +116 -0
- data/tests/validate_read_on_create.rb +12 -0
- data/utils/convert_index.rb +31 -0
- metadata +77 -28
@@ -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
|
+
field :surname, :string
|
13
|
+
has_one :account, :index => :flat
|
14
|
+
has_many :files, :index => :flat, :class_name => "UserFile"
|
15
|
+
end
|
16
|
+
|
17
|
+
class Account < Model
|
18
|
+
field :login, :string
|
19
|
+
end
|
20
|
+
|
21
|
+
class UserFile < Model
|
22
|
+
field :data, :string
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
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
|
+
field :age, :integer
|
13
|
+
has_one :account, :index => :flat
|
14
|
+
has_many :files, :index => :flat, :class_name => "UserFile"
|
15
|
+
has_many :accounts, :index => :flat
|
16
|
+
end
|
17
|
+
|
18
|
+
class Account < Model
|
19
|
+
field :login, :string
|
20
|
+
field :password, :string
|
21
|
+
end
|
22
|
+
|
23
|
+
class UserFile < Model
|
24
|
+
field :data, :string
|
25
|
+
field :name, :string, :index => :flat
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift("lib")
|
2
|
+
require 'rod'
|
3
|
+
require 'rspec/expectations'
|
4
|
+
require File.join(".",File.dirname(__FILE__),"migration_model2")
|
5
|
+
|
6
|
+
Rod::Database.development_mode = true
|
7
|
+
|
8
|
+
Database.instance.open_database("tmp/migration")
|
9
|
+
|
10
|
+
user = User[0]
|
11
|
+
user.should_not == nil
|
12
|
+
user = User.find_by_name("John")
|
13
|
+
user.should_not == nil
|
14
|
+
user.name.should == "John"
|
15
|
+
user.age.should == 0
|
16
|
+
user.account.should_not == nil
|
17
|
+
user.account.should == Account[0]
|
18
|
+
user.files.size.should == 3
|
19
|
+
user.accounts.size.should == 1
|
20
|
+
user.accounts[0].should == user.account
|
21
|
+
|
22
|
+
account = Account[0]
|
23
|
+
account.login.should == "john"
|
24
|
+
account.password.should == ""
|
25
|
+
User.find_all_by_account(account).size.should == 1
|
26
|
+
User.find_all_by_account(account)[0].should == user
|
27
|
+
User.find_by_account(account).should_not == nil
|
28
|
+
user.account.should == account
|
29
|
+
|
30
|
+
user = User.find_by_name("Amanda")
|
31
|
+
user.should_not == nil
|
32
|
+
user.name.should == "Amanda"
|
33
|
+
user.age.should == 0
|
34
|
+
user.account.should_not == nil
|
35
|
+
user.files.size.should == 5
|
36
|
+
user.accounts.size.should == 1
|
37
|
+
user.accounts[0].should == user.account
|
38
|
+
|
39
|
+
account = Account[1]
|
40
|
+
account.login.should == "amanda"
|
41
|
+
account.password.should == ""
|
42
|
+
User.find_by_account(account).should_not == nil
|
43
|
+
user.account.should == account
|
44
|
+
|
45
|
+
file = UserFile[0]
|
46
|
+
file.data.should == "0 data"
|
47
|
+
|
48
|
+
UserFile.each do |file|
|
49
|
+
file.data.should_not == nil
|
50
|
+
file.name.should == ""
|
51
|
+
end
|
52
|
+
users = User.find_all_by_files(file)
|
53
|
+
users.size.should == 2
|
54
|
+
users[1].should == user
|
55
|
+
|
56
|
+
Database.instance.close_database
|
data/tests/mock_tests.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
$:.unshift("lib")
|
2
|
+
|
3
|
+
require 'rod'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha'
|
6
|
+
|
7
|
+
module RodTest
|
8
|
+
class InnerExporter < Rod::Exporter
|
9
|
+
end
|
10
|
+
|
11
|
+
class InnerLoader < Rod::Loader
|
12
|
+
end
|
13
|
+
|
14
|
+
class Exporter
|
15
|
+
def self.method_missing(method_sym, *arguments)
|
16
|
+
arguments_str = ""
|
17
|
+
# begin
|
18
|
+
arguments_str = arguments.to_s
|
19
|
+
# rescue TypeError
|
20
|
+
# empty is ok - thrown when trying to access fields too early
|
21
|
+
# end
|
22
|
+
puts "EX: static #{method_sym.to_s} (#{arguments_str})"
|
23
|
+
InnerExporter.send(method_sym, *arguments)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Loader
|
28
|
+
def self.method_missing(method_sym, *arguments)
|
29
|
+
arguments_str = arguments.to_s
|
30
|
+
puts "LD: static #{method_sym.to_s} (#{arguments_str})"
|
31
|
+
InnerLoader.send(method_sym, *arguments)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Database < Rod::Database
|
36
|
+
end
|
37
|
+
|
38
|
+
class Model < Rod::Model
|
39
|
+
attr_accessor :used
|
40
|
+
database_class Database
|
41
|
+
end
|
42
|
+
|
43
|
+
class BStruct < Model
|
44
|
+
field :b, :string
|
45
|
+
has_one :a_struct
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
"#{self.b}"
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
class AStruct < Model
|
54
|
+
field :a1, :integer
|
55
|
+
field :a2, :ulong, :index => true
|
56
|
+
has_many :b_structs, :class_name => "RodTest::BStruct"
|
57
|
+
|
58
|
+
# def to_s <- causes strange Error - see Exporter::method_missing
|
59
|
+
# "#{a1}, #{a2}"
|
60
|
+
# end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ModuleTests < Test::Unit::TestCase
|
64
|
+
|
65
|
+
MAGNITUDE = 5
|
66
|
+
TEST_FILENAME = "tmp/db"
|
67
|
+
|
68
|
+
def setup
|
69
|
+
@as = Array.new
|
70
|
+
@bs = Array.new
|
71
|
+
|
72
|
+
(0..MAGNITUDE).each do |j|
|
73
|
+
@as[j] = AStruct.new
|
74
|
+
@as[j].a1 = j
|
75
|
+
@as[j].a2 = j * 10000
|
76
|
+
end
|
77
|
+
|
78
|
+
(0..MAGNITUDE).each do |j|
|
79
|
+
@bs[j] = BStruct.new
|
80
|
+
@bs[j].b = "string_#{j}"
|
81
|
+
@bs[j].a_struct = @as[j]
|
82
|
+
end
|
83
|
+
|
84
|
+
# (0..MAGNITUDE).each do |j|
|
85
|
+
# @as[j].b_structs = @bs[j .. ((j+1) % MAGNITUDE)]
|
86
|
+
# end
|
87
|
+
end
|
88
|
+
|
89
|
+
def teardown
|
90
|
+
begin
|
91
|
+
RodTest::Database.instance.close_database
|
92
|
+
rescue RuntimeError
|
93
|
+
#ok, because of mocking store subroutines not all references are marked as stored
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_store
|
98
|
+
puts
|
99
|
+
|
100
|
+
Database.instance.create_database("#{TEST_FILENAME}2")
|
101
|
+
|
102
|
+
Database.instance.expects(:_store_rod_test__a_struct).times(6)
|
103
|
+
Database.instance.expects(:_store_rod_test__b_struct).times(6)
|
104
|
+
@as.each do |a|
|
105
|
+
a.store
|
106
|
+
end
|
107
|
+
@bs.each do |b|
|
108
|
+
b.store
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_create
|
113
|
+
puts
|
114
|
+
|
115
|
+
Database.instance..expects(:create)
|
116
|
+
Database.instance.create_database("#{TEST_FILENAME}3")
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_close
|
120
|
+
puts
|
121
|
+
|
122
|
+
Database.instance.create_database("#{TEST_FILENAME}4")
|
123
|
+
Exporter.instance.expects(:close)
|
124
|
+
Database.instance.close_database()
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$:.unshift("tests")
|
2
|
+
require 'structures'
|
3
|
+
require 'validate_read_on_create'
|
4
|
+
|
5
|
+
puts "-- Read data while creating DB --"
|
6
|
+
Rod::Database.development_mode = true
|
7
|
+
|
8
|
+
|
9
|
+
RodTest::Database.instance.create_database("tmp/read_write")
|
10
|
+
my_structures = []
|
11
|
+
MAGNITUDO.times do |index|
|
12
|
+
your_struct = RodTest::YourStruct.new
|
13
|
+
your_struct.counter = index
|
14
|
+
your_struct.title = "Title_#{index}"
|
15
|
+
your_struct.store
|
16
|
+
|
17
|
+
my_struct = RodTest::MyStruct.new
|
18
|
+
my_struct.count = index
|
19
|
+
my_struct.your_struct = your_struct
|
20
|
+
my_struct.title = "Title_#{index}"
|
21
|
+
my_struct.title2 = "Title2_#{index}"
|
22
|
+
|
23
|
+
my_struct.store
|
24
|
+
my_structures << my_struct
|
25
|
+
end
|
26
|
+
|
27
|
+
MAGNITUDO.times do |index|
|
28
|
+
# validate object fetched from cache
|
29
|
+
struct = RodTest::MyStruct[index]
|
30
|
+
validate(index,struct)
|
31
|
+
# validate object referenced previously
|
32
|
+
validate(index,my_structures[index])
|
33
|
+
# validate referential integrity
|
34
|
+
if struct.object_id != my_structures[index].object_id
|
35
|
+
raise "Object stored and recived are different #{struct.object_id} " +
|
36
|
+
"#{my_structures[index].object_id}"
|
37
|
+
end
|
38
|
+
if struct != my_structures[index]
|
39
|
+
raise "Object stored and recived are different #{struct} " +
|
40
|
+
"#{my_structures[index]}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
RodTest::Database.instance.close_database
|
@@ -0,0 +1,49 @@
|
|
1
|
+
$:.unshift("tests")
|
2
|
+
require 'structures'
|
3
|
+
|
4
|
+
puts "-- Save sample structures test --"
|
5
|
+
Rod::Database.development_mode = true
|
6
|
+
RodTest::Database.instance.create_database("tmp/abc")
|
7
|
+
|
8
|
+
#MAGNITUDE = 100000
|
9
|
+
MAGNITUDE = 50
|
10
|
+
|
11
|
+
his = []
|
12
|
+
(MAGNITUDE * 10).times do |i|
|
13
|
+
his[i] = RodTest::HisStruct.new
|
14
|
+
his[i].inde = i
|
15
|
+
end
|
16
|
+
|
17
|
+
ys = []
|
18
|
+
(MAGNITUDE * 1).times do |i|
|
19
|
+
ys[i] = RodTest::YourStruct.new
|
20
|
+
ys[i].counter = 10
|
21
|
+
ys[i].his_structs = his[i*10...(i+1)*10]
|
22
|
+
end
|
23
|
+
|
24
|
+
ms = []
|
25
|
+
(MAGNITUDE * 1).times do |i|
|
26
|
+
ms[i] = RodTest::MyStruct.new
|
27
|
+
ms[i].count = 10 * i
|
28
|
+
ms[i].precision = 0.1 * i
|
29
|
+
ms[i].identifier = i
|
30
|
+
ms[i].your_struct = ys[i]
|
31
|
+
ms[i].title = "title_#{i}"
|
32
|
+
ms[i].title2 = "title2_#{i}"
|
33
|
+
ms[i].body = "body_#{i}"
|
34
|
+
end
|
35
|
+
|
36
|
+
RodTest::Database.instance.print_layout
|
37
|
+
ms.each_with_index{|s,i|
|
38
|
+
begin
|
39
|
+
puts i if i % 1000 == 0
|
40
|
+
s.store
|
41
|
+
rescue Exception => e
|
42
|
+
puts e
|
43
|
+
raise
|
44
|
+
end
|
45
|
+
}
|
46
|
+
ys.each{|y| y.store}
|
47
|
+
his.each{|h| h.store}
|
48
|
+
RodTest::Database.instance.print_layout
|
49
|
+
RodTest::Database.instance.close_database
|
data/tests/structures.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$:.unshift("lib")
|
2
|
+
require 'rod'
|
3
|
+
|
4
|
+
module RodTest
|
5
|
+
class Database < Rod::Database
|
6
|
+
end
|
7
|
+
|
8
|
+
class Model < Rod::Model
|
9
|
+
database_class Database
|
10
|
+
end
|
11
|
+
|
12
|
+
class MyStruct < Model
|
13
|
+
field :count, :integer
|
14
|
+
field :precision, :float
|
15
|
+
field :identifier, :ulong
|
16
|
+
field :title, :string, :index => :segmented
|
17
|
+
field :title2, :string
|
18
|
+
field :body, :string
|
19
|
+
has_one :your_struct
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"#{self.title} #{self.body} " +
|
23
|
+
"count #{self.count}, precision #{self.precision}, " +
|
24
|
+
"identifier #{self.identifier} rod_id #{self.rod_id} " +
|
25
|
+
"your_struct #{self.your_struct}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class YourStruct < Model
|
30
|
+
field :counter, :integer
|
31
|
+
field :title, :string
|
32
|
+
has_many :his_structs
|
33
|
+
has_many :her_structs, :class_name => "RodTest::HisStruct"
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"counter #{self.counter}, title #{self.title} his structs " +
|
37
|
+
"#{self.his_structs.map{|e| e.inde}.join("")}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class HisStruct < Model
|
42
|
+
field :inde, :integer
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
"inde #{self.inde}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
self.to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.unshift("lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rod'
|
4
|
+
|
5
|
+
class DatabaseTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@database = Rod::Database.instance
|
8
|
+
@database.create_database("tmp/unit_database")
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@database.close_database
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_version_validity
|
16
|
+
Rod::VERSION.sub!(/.*/,"0.1.0")
|
17
|
+
file = "0.1.0"
|
18
|
+
assert(@database.send(:valid_version?,file))
|
19
|
+
|
20
|
+
Rod::VERSION.sub!(/.*/,"0.1.1")
|
21
|
+
file = "0.1.0"
|
22
|
+
assert(not(@database.send(:valid_version?,file)))
|
23
|
+
|
24
|
+
Rod::VERSION.sub!(/.*/,"0.2.1")
|
25
|
+
file = "0.2.0"
|
26
|
+
assert(@database.send(:valid_version?,file))
|
27
|
+
|
28
|
+
Rod::VERSION.sub!(/.*/,"0.2.0")
|
29
|
+
file = "0.2.1"
|
30
|
+
assert(!@database.send(:valid_version?,file))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_created_at
|
34
|
+
assert(Time.now - @database.metadata["Rod"][:created_at] < 10)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_updated_at
|
38
|
+
sleep(1)
|
39
|
+
@database.close_database
|
40
|
+
@database.open_database("tmp/unit_database",false)
|
41
|
+
assert(@database.metadata["Rod"][:updated_at] -
|
42
|
+
@database.metadata["Rod"][:created_at] >= 1)
|
43
|
+
assert(@database.metadata["Rod"][:updated_at] -
|
44
|
+
@database.metadata["Rod"][:created_at] < 4)
|
45
|
+
sleep(2)
|
46
|
+
@database.close_database
|
47
|
+
@database.open_database("tmp/unit_database",false)
|
48
|
+
assert(@database.metadata["Rod"][:updated_at] -
|
49
|
+
@database.metadata["Rod"][:created_at] >= 3)
|
50
|
+
assert(@database.metadata["Rod"][:updated_at] -
|
51
|
+
@database.metadata["Rod"][:created_at] < 6)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_superclass
|
55
|
+
@database.close_database
|
56
|
+
@database.open_database("tmp/unit_database")
|
57
|
+
assert(@database.metadata["Rod::StringElement"][:superclass] ==
|
58
|
+
Rod::AbstractModel.name)
|
59
|
+
end
|
60
|
+
end
|