rod 0.7.1 → 0.7.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.
- data/.travis.yml +1 -1
- data/README.rdoc +38 -10
- data/Rakefile +20 -9
- data/changelog.txt +25 -0
- data/contributors.txt +1 -0
- data/data/backward/0.7.0/_join_element.dat +0 -0
- data/data/backward/0.7.0/_polymorphic_join_element.dat +0 -0
- data/data/backward/0.7.0/char.dat +0 -0
- data/data/backward/0.7.0/database.yml +58 -0
- data/data/backward/0.7.0/rod_test__automobile.dat +0 -0
- data/data/backward/0.7.0/rod_test__caveman.dat +0 -0
- data/data/backward/0.7.0/rod_test__dog.dat +0 -0
- data/data/backward/0.7.0/rod_test__test_model.dat +0 -0
- data/data/portability/_join_element.dat +0 -0
- data/data/portability/_polymorphic_join_element.dat +0 -0
- data/data/portability/char.dat +0 -0
- data/data/portability/database.yml +49 -0
- data/data/portability/rod_test__automobile.dat +0 -0
- data/data/portability/rod_test__caveman.dat +0 -0
- data/data/portability/rod_test__dog.dat +0 -0
- data/data/portability/rod_test__test_model.dat +0 -0
- data/features/backward.feature +33 -0
- data/features/basic.feature +3 -0
- data/features/collection_proxy.feature +95 -0
- data/features/flat_indexing.feature +44 -2
- data/features/hash_indexing.feature +63 -9
- data/features/portability.feature +72 -0
- data/features/segmented_indexing.feature +45 -2
- data/features/steps/collection_proxy.rb +1 -1
- data/features/steps/model.rb +48 -5
- data/features/steps/rod.rb +15 -16
- data/lib/rod.rb +11 -1
- data/lib/rod/abstract_database.rb +52 -42
- data/lib/rod/berkeley/collection_proxy.rb +96 -0
- data/lib/rod/berkeley/database.rb +337 -0
- data/lib/rod/berkeley/environment.rb +209 -0
- data/lib/rod/berkeley/sequence.rb +222 -0
- data/lib/rod/berkeley/transaction.rb +233 -0
- data/lib/rod/collection_proxy.rb +76 -1
- data/lib/rod/constants.rb +3 -2
- data/lib/rod/database.rb +127 -14
- data/lib/rod/index/base.rb +12 -3
- data/lib/rod/index/hash_index.rb +295 -70
- data/lib/rod/index/segmented_index.rb +3 -0
- data/lib/rod/model.rb +154 -531
- data/lib/rod/property/base.rb +190 -0
- data/lib/rod/property/field.rb +258 -0
- data/lib/rod/property/plural_association.rb +145 -0
- data/lib/rod/property/singular_association.rb +139 -0
- data/rod.gemspec +6 -4
- data/spec/berkeley/database.rb +83 -0
- data/spec/berkeley/environment.rb +58 -0
- data/spec/berkeley/sequence.rb +101 -0
- data/spec/berkeley/transaction.rb +92 -0
- data/spec/collection_proxy.rb +38 -0
- data/spec/database.rb +36 -0
- data/spec/model.rb +26 -0
- data/spec/property/base.rb +73 -0
- data/spec/property/field.rb +244 -0
- data/spec/property/plural_association.rb +67 -0
- data/spec/property/singular_association.rb +65 -0
- data/tests/class_compatibility_create.rb +2 -2
- data/tests/eff1_test.rb +1 -1
- data/tests/eff2_test.rb +1 -1
- data/tests/full_runs.rb +1 -1
- data/tests/generate_classes_create.rb +14 -14
- data/tests/migration_create.rb +47 -47
- data/tests/migration_verify.rb +1 -1
- data/tests/missing_class_create.rb +6 -6
- data/tests/properties_order_create.rb +4 -4
- data/tests/read_on_create.rb +33 -34
- data/tests/save_struct.rb +40 -39
- data/tests/unit/database.rb +1 -1
- data/tests/unit/model_tests.rb +73 -65
- metadata +71 -15
- data/tests/unit/model.rb +0 -36
data/.travis.yml
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
= ROD -- Ruby Object Database
|
2
2
|
|
3
|
-
* http://github.com/apohllo/rod
|
3
|
+
* http://github.com/apohllo/rod - source code
|
4
|
+
* http://rubydoc.info/github/apohllo/rod/master/frames - API
|
5
|
+
* https://www.relishapp.com/apohllo/rod - Cucumber features
|
4
6
|
|
5
7
|
== WARNING
|
6
8
|
|
@@ -15,22 +17,28 @@ fast access for data, which rarely changes.
|
|
15
17
|
|
16
18
|
== FEATURES:
|
17
19
|
|
18
|
-
*
|
20
|
+
* object-oriented Ruby interface
|
19
21
|
* Ruby-to-C on-the-fly translation based on mmap and RubyInline
|
20
22
|
* optimized for (reading) speed
|
21
23
|
* weak reference collections for easy memory reclaims
|
22
24
|
* Berkeley DB hash index for the best index performance
|
25
|
+
* immediate updates of hash indices
|
23
26
|
* compatibility check of library version
|
24
27
|
* compatibility check of data model
|
25
|
-
*
|
26
|
-
* automatic model migrations (
|
28
|
+
* auto-generation of model (based on the database meta-data)
|
29
|
+
* automatic model migrations (limited to addition/removal of properties and indexes)
|
27
30
|
* full update of the database (removal of objects not available yet)
|
28
31
|
* databases interlinking (via direct links or inverted indices)
|
32
|
+
* data portability between big and little-endian systems
|
33
|
+
* works on Linux and BSD
|
29
34
|
|
30
35
|
== PROBLEMS
|
31
36
|
|
32
37
|
* tested mostly on 64-bit systems
|
33
38
|
* doesn't work on Windows
|
39
|
+
* concurrent writes not supported
|
40
|
+
* batch-only data input/update
|
41
|
+
* data removal not supported
|
34
42
|
|
35
43
|
== SYNOPSIS:
|
36
44
|
|
@@ -71,7 +79,7 @@ number of disk reads was designed. The Ruby interface facilitates it's usage.
|
|
71
79
|
|
72
80
|
== TROUBLESHOOTING
|
73
81
|
|
74
|
-
If you get the following error
|
82
|
+
If you get the following error:
|
75
83
|
|
76
84
|
error: db.h: No such file or directory
|
77
85
|
|
@@ -79,6 +87,19 @@ then you don't have Berkeley DB installed or its header fiels are not available
|
|
79
87
|
on the default path. Make sure that the library is installed and the headers
|
80
88
|
are available.
|
81
89
|
|
90
|
+
If you get the following error:
|
91
|
+
|
92
|
+
.ruby: symbol lookup error: /home/vagrant/.ruby_inline/... undefined symbol: db_env_create
|
93
|
+
|
94
|
+
then you have to provide system-specific linker information. By default the library
|
95
|
+
is linked with '-ldb' linker flag. To change it you have to set up ROD_BDB_LINK_FLAGS
|
96
|
+
environment variable, e.g.
|
97
|
+
|
98
|
+
ROD_BDB_LINK_FLAGS='-ldb-4.8'
|
99
|
+
export ROD_BDB_LINK_FLAGS
|
100
|
+
|
101
|
+
This configuration option will select the libdb-4.8.so library.
|
102
|
+
|
82
103
|
== BASIC USAGE:
|
83
104
|
|
84
105
|
class MyDatabase < Rod::Database
|
@@ -107,7 +128,7 @@ are available.
|
|
107
128
|
field :data, :string
|
108
129
|
end
|
109
130
|
|
110
|
-
MyDatabase.create_database("data")
|
131
|
+
MyDatabase.instance.create_database("data")
|
111
132
|
user = User.new(:name => 'Fred',
|
112
133
|
:surname => 'Smith',
|
113
134
|
:age => 22)
|
@@ -127,9 +148,9 @@ are available.
|
|
127
148
|
account.store
|
128
149
|
file1.store
|
129
150
|
file2.store
|
130
|
-
MyDatabase.close_database
|
151
|
+
MyDatabase.instance.close_database
|
131
152
|
|
132
|
-
MyDatabase.open_database("data")
|
153
|
+
MyDatabase.instance.open_database("data")
|
133
154
|
User.each do |user|
|
134
155
|
puts "Name: #{user.name} surname: #{user.surname}"
|
135
156
|
puts "login: #{user.account.login} e-mail: #{user.account.email}"
|
@@ -170,11 +191,18 @@ Then be sure to write tests covering the added feature/fixed bug.
|
|
170
191
|
Include the tests in Rakefile, run the tests and if everything is fine
|
171
192
|
send me a pull request.
|
172
193
|
|
194
|
+
== BENCHMARKS:
|
195
|
+
|
196
|
+
There is a separate project available under http://github.com/apohllo/rod-benchmark
|
197
|
+
that shows how ROD behave compared to the other storage engines.
|
198
|
+
It should be noted that this benchmarks are biased towards the design goals
|
199
|
+
of ROD. So don't expect general purpose database tests.
|
200
|
+
|
173
201
|
== LICENSE:
|
174
202
|
|
175
|
-
(The MIT License)
|
203
|
+
(The MIT/X11 License)
|
176
204
|
|
177
|
-
Copyright (c) 2008-
|
205
|
+
Copyright (c) 2008-2012 Aleksander Pohl
|
178
206
|
|
179
207
|
Permission is hereby granted, free of charge, to any person obtaining
|
180
208
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ task :uninstall do
|
|
27
27
|
sh "sudo gem uninstall #$gem_name"
|
28
28
|
end
|
29
29
|
|
30
|
-
task :all_tests => [:test,:regression_test,:
|
30
|
+
task :all_tests => [:test,:unit_test,:regression_test,:features] do
|
31
31
|
end
|
32
32
|
|
33
33
|
desc "Run performence tests"
|
@@ -37,7 +37,7 @@ task :perf do
|
|
37
37
|
sh "ruby tests/full_runs.rb"
|
38
38
|
end
|
39
39
|
|
40
|
-
desc "Run tests
|
40
|
+
desc "Run multi-step tests"
|
41
41
|
task :test do
|
42
42
|
sh "ruby tests/save_struct.rb"
|
43
43
|
sh "ruby tests/load_struct.rb"
|
@@ -47,17 +47,28 @@ task :test do
|
|
47
47
|
sh "ruby tests/generate_classes_rewrite.rb"
|
48
48
|
sh "ruby tests/generate_classes_rewrite.rb"
|
49
49
|
sh "ruby tests/generate_classes_verify.rb"
|
50
|
-
|
51
|
-
sh "ruby tests/
|
52
|
-
sh "ruby tests/
|
50
|
+
# TODO #206 fix index migration
|
51
|
+
#sh "ruby tests/migration_create.rb 1000"
|
52
|
+
#sh "ruby tests/migration_migrate.rb 1000"
|
53
|
+
#sh "ruby tests/migration_verify.rb 1000"
|
53
54
|
sh "ruby tests/missing_class_create.rb"
|
54
55
|
sh "ruby tests/missing_class_verify.rb"
|
55
56
|
sh "ruby tests/properties_order_create.rb"
|
56
57
|
sh "ruby tests/properties_order_verify.rb"
|
57
|
-
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Run unit tests and model specs"
|
61
|
+
task :unit_test do
|
58
62
|
sh "ruby tests/unit/model_tests.rb"
|
59
63
|
sh "ruby tests/unit/database.rb"
|
60
64
|
sh "ruby tests/unit/abstract_database.rb"
|
65
|
+
sh "ruby spec/property/base.rb"
|
66
|
+
sh "ruby spec/property/field.rb"
|
67
|
+
sh "ruby spec/property/singular_association.rb"
|
68
|
+
sh "ruby spec/property/plural_association.rb"
|
69
|
+
sh "ruby spec/berkeley/environment.rb"
|
70
|
+
sh "ruby spec/berkeley/database.rb"
|
71
|
+
sh "ruby spec/berkeley/transaction.rb"
|
61
72
|
end
|
62
73
|
|
63
74
|
# Should be removed some time -- specs should cover all these cases
|
@@ -66,12 +77,12 @@ task :regression_test do
|
|
66
77
|
sh "ruby tests/check_strings.rb"
|
67
78
|
end
|
68
79
|
|
69
|
-
desc "Run all
|
70
|
-
task :
|
80
|
+
desc "Run all cucumber features without the ignored ones"
|
81
|
+
task :features do
|
71
82
|
sh "bundle exec cucumber --tags ~@ignore features/*"
|
72
83
|
end
|
73
84
|
|
74
|
-
desc "Run only work-in-progress
|
85
|
+
desc "Run only work-in-progress features"
|
75
86
|
task :wip do
|
76
87
|
sh "bundle exec cucumber --tags @wip features/*"
|
77
88
|
end
|
data/changelog.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
0.7.2
|
2
|
+
- Fix variable declaration place #118
|
3
|
+
- Implementation of & and | for collection proxies
|
4
|
+
- Fix strange error caused by mocha #219
|
5
|
+
- Change compile flags to link flags and API accordingly #200
|
6
|
+
- Fix memleak when growing DB file #211
|
7
|
+
- Change hash cache size to 0.5 MB
|
8
|
+
- Add flags needed on BSD #215
|
9
|
+
- Fix destroy of hash index #217 #218
|
10
|
+
- Immediate hash index updates #209 #213
|
11
|
+
- Add method for computing collections' intersection size #224
|
12
|
+
- Add hash index compile flags env. variable #223
|
13
|
+
- Add negative float values in basic feature
|
14
|
+
- #204 fix features for out-of-scope indexing
|
15
|
+
- Fix: too large values for 32-bit systems in tests
|
16
|
+
- Remove old unit tests
|
17
|
+
- Change directory of Berkeley env
|
18
|
+
- #199 spec and new implementation for Model#[]
|
19
|
+
- Change libdb to 4.8 in travis script
|
20
|
+
- Updated links and year, note about benchmarks
|
21
|
+
- Berkeley DB building blocks
|
22
|
+
- Update requires for latest Active Model
|
23
|
+
- Allow latest version of active model to be used
|
24
|
+
- Fix example in README
|
25
|
+
- #190 #98 #173 refactoring of properties
|
1
26
|
0.7.1
|
2
27
|
- #189 guard object load against empty strings.
|
3
28
|
- Don't close hash index when it is destroyed.
|
data/contributors.txt
CHANGED
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,58 @@
|
|
1
|
+
---
|
2
|
+
Rod:
|
3
|
+
:version: 0.7.0
|
4
|
+
:created_at: 2012-04-30 10:49:34.260940 +02:00
|
5
|
+
:updated_at: 2012-04-30 10:49:34.281290 +02:00
|
6
|
+
Rod::JoinElement:
|
7
|
+
:superclass: Rod::AbstractModel
|
8
|
+
:count: 1
|
9
|
+
Rod::PolymorphicJoinElement:
|
10
|
+
:superclass: Rod::JoinElement
|
11
|
+
:count: 0
|
12
|
+
Rod::StringElement:
|
13
|
+
:superclass: Rod::AbstractModel
|
14
|
+
:count: 25
|
15
|
+
RodTest::Automobile:
|
16
|
+
:superclass: RodTest::TestModel
|
17
|
+
:fields:
|
18
|
+
:name:
|
19
|
+
:options:
|
20
|
+
:type: :string
|
21
|
+
:count: 1
|
22
|
+
RodTest::Caveman:
|
23
|
+
:superclass: RodTest::TestModel
|
24
|
+
:fields:
|
25
|
+
:name:
|
26
|
+
:options:
|
27
|
+
:type: :string
|
28
|
+
:age:
|
29
|
+
:options:
|
30
|
+
:type: :integer
|
31
|
+
:identifier:
|
32
|
+
:options:
|
33
|
+
:type: :ulong
|
34
|
+
:height:
|
35
|
+
:options:
|
36
|
+
:type: :float
|
37
|
+
:account_balance:
|
38
|
+
:options:
|
39
|
+
:type: :float
|
40
|
+
:has_one:
|
41
|
+
:automobile:
|
42
|
+
:options: {}
|
43
|
+
|
44
|
+
:has_many:
|
45
|
+
:dogs:
|
46
|
+
:options: {}
|
47
|
+
|
48
|
+
:count: 1
|
49
|
+
RodTest::Dog:
|
50
|
+
:superclass: RodTest::TestModel
|
51
|
+
:fields:
|
52
|
+
:nickname:
|
53
|
+
:options:
|
54
|
+
:type: :string
|
55
|
+
:count: 1
|
56
|
+
RodTest::TestModel:
|
57
|
+
:superclass: Rod::Model
|
58
|
+
:count: 0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,49 @@
|
|
1
|
+
---
|
2
|
+
Rod:
|
3
|
+
:version: 0.7.1
|
4
|
+
:created_at: 2012-05-02 01:00:18.322307 +02:00
|
5
|
+
:updated_at: 2012-05-02 01:00:18.380358 +02:00
|
6
|
+
Rod::JoinElement:
|
7
|
+
:superclass: Rod::AbstractModel
|
8
|
+
:count: 1
|
9
|
+
Rod::PolymorphicJoinElement:
|
10
|
+
:superclass: Rod::JoinElement
|
11
|
+
:count: 0
|
12
|
+
Rod::StringElement:
|
13
|
+
:superclass: Rod::AbstractModel
|
14
|
+
:count: 25
|
15
|
+
RodTest::Automobile:
|
16
|
+
:superclass: RodTest::TestModel
|
17
|
+
:fields:
|
18
|
+
:name:
|
19
|
+
:type: :string
|
20
|
+
:count: 1
|
21
|
+
RodTest::Caveman:
|
22
|
+
:superclass: RodTest::TestModel
|
23
|
+
:fields:
|
24
|
+
:name:
|
25
|
+
:type: :string
|
26
|
+
:age:
|
27
|
+
:type: :integer
|
28
|
+
:identifier:
|
29
|
+
:type: :ulong
|
30
|
+
:height:
|
31
|
+
:type: :float
|
32
|
+
:account_balance:
|
33
|
+
:type: :float
|
34
|
+
:has_one:
|
35
|
+
:automobile: {}
|
36
|
+
|
37
|
+
:has_many:
|
38
|
+
:dogs: {}
|
39
|
+
|
40
|
+
:count: 1
|
41
|
+
RodTest::Dog:
|
42
|
+
:superclass: RodTest::TestModel
|
43
|
+
:fields:
|
44
|
+
:nickname:
|
45
|
+
:type: :string
|
46
|
+
:count: 1
|
47
|
+
RodTest::TestModel:
|
48
|
+
:superclass: Rod::Model
|
49
|
+
:count: 0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: Data backward compatiblity
|
2
|
+
The data scheme should be compatible between certain library versions.
|
3
|
+
Some of the scenarios might be ignored and run only directly to
|
4
|
+
indicate the incompatiblities.
|
5
|
+
Background:
|
6
|
+
Given the library works in development mode
|
7
|
+
|
8
|
+
@ignore
|
9
|
+
Scenario: compatiblity with version 0.7.0
|
10
|
+
To make the data compatible, the 'options' key should be removed from
|
11
|
+
the database.yml
|
12
|
+
Given the class space is cleared
|
13
|
+
And the model is connected with the default database
|
14
|
+
And a class Caveman has a name field of type string
|
15
|
+
And a class Caveman has an age field of type integer
|
16
|
+
And a class Caveman has an identifier field of type ulong
|
17
|
+
And a class Caveman has a height field of type float
|
18
|
+
And a class Caveman has a account_balance field of type float
|
19
|
+
And a class Automobile has a name field of type string
|
20
|
+
And a class Caveman has one automobile
|
21
|
+
And a class Dog has a nickname field of type string
|
22
|
+
And a class Caveman has many dogs
|
23
|
+
When I open the database for reading in data/backward/0.7.0
|
24
|
+
Then there should be 1 Caveman
|
25
|
+
And there should be 1 Dog
|
26
|
+
And there should be 1 Automobile
|
27
|
+
And the name of the first Caveman should be 'Fred'
|
28
|
+
And the age of the first Caveman should be '25'
|
29
|
+
And the identifier of the first Caveman should be '111222333'
|
30
|
+
And the height of the first Caveman should be '1.86'
|
31
|
+
And the account_balance of the first Caveman should be '-0.00000001'
|
32
|
+
And the automobile of the first Caveman should be equal to the first Automobile persisted
|
33
|
+
And the first of dogs of the first Caveman should be equal to the first Dog persisted
|
data/features/basic.feature
CHANGED
@@ -38,6 +38,7 @@ Feature: Store and load small amount of data from one class
|
|
38
38
|
And a class Caveman has an age field of type integer
|
39
39
|
And a class Caveman has an identifier field of type ulong
|
40
40
|
And a class Caveman has a height field of type float
|
41
|
+
And a class Caveman has a account_balance field of type float
|
41
42
|
And a class Caveman has a symbol field of type object
|
42
43
|
And a class Caveman has a empty_string field of type string
|
43
44
|
And a class Caveman has a empty_object field of type object
|
@@ -47,6 +48,7 @@ Feature: Store and load small amount of data from one class
|
|
47
48
|
And his age is '25'
|
48
49
|
And his identifier is '111222333'
|
49
50
|
And his height is '1.86'
|
51
|
+
And his account_balance is '-0.00000001'
|
50
52
|
And his symbol is ':fred'
|
51
53
|
# nil is converted to an empty string, consider using object field
|
52
54
|
# if you wish to store nil for string fields
|
@@ -61,6 +63,7 @@ Feature: Store and load small amount of data from one class
|
|
61
63
|
And the age of the first Caveman should be '25'
|
62
64
|
And the identifier of the first Caveman should be '111222333'
|
63
65
|
And the height of the first Caveman should be '1.86'
|
66
|
+
And the account_balance of the first Caveman should be '-0.00000001'
|
64
67
|
And the symbol of the first Caveman should be ':fred'
|
65
68
|
And the empty_string of the first Caveman should be ''
|
66
69
|
And the empty_object of the first Caveman should be nil
|
@@ -143,3 +143,98 @@ Feature: collection proxy specification
|
|
143
143
|
Given the initial size of the collection proxy is 5
|
144
144
|
# Can't figure out anything better.
|
145
145
|
Then an exception should be raised when the collection is modified during iteration
|
146
|
+
|
147
|
+
Scenario: fast intersection computing
|
148
|
+
Given the class space is cleared
|
149
|
+
And the model is connected with the default database
|
150
|
+
And a class Caveman has a name field of type string
|
151
|
+
And a class Automobile has a name field of type string
|
152
|
+
And a class Caveman has many automobiles
|
153
|
+
When the database is created
|
154
|
+
And I create an Automobile
|
155
|
+
And its name is 'Car 1'
|
156
|
+
And I store it in the database
|
157
|
+
And I create another Automobile
|
158
|
+
And its name is 'Car 2'
|
159
|
+
And I store it in the database
|
160
|
+
And I create another Automobile
|
161
|
+
And its name is 'Car 3'
|
162
|
+
And I store it in the database
|
163
|
+
And I create another Automobile
|
164
|
+
And its name is 'Car 4'
|
165
|
+
And I store it in the database
|
166
|
+
And I create another Automobile
|
167
|
+
And its name is 'Car 5'
|
168
|
+
And I store it in the database
|
169
|
+
And I create another Automobile
|
170
|
+
And its name is 'Car 6'
|
171
|
+
And I store it in the database
|
172
|
+
And I create another Automobile
|
173
|
+
And its name is 'Car 7'
|
174
|
+
And I store it in the database
|
175
|
+
And I create a Caveman
|
176
|
+
And his name is 'Fred'
|
177
|
+
# The automobiles have to be in the creation order, since this is assumed by the
|
178
|
+
# fast intersection computation routine.
|
179
|
+
And his automobiles contain the first Automobile created
|
180
|
+
And his automobiles contain the second Automobile created
|
181
|
+
And his automobiles contain the third Automobile created
|
182
|
+
And his automobiles contain the fourth Automobile created
|
183
|
+
And I store him in the database
|
184
|
+
And I create another Caveman
|
185
|
+
And his name is 'Bill'
|
186
|
+
And his automobiles contain the third Automobile created
|
187
|
+
And his automobiles contain the fourth Automobile created
|
188
|
+
And his automobiles contain the fifth Automobile created
|
189
|
+
And his automobiles contain the sixth Automobile created
|
190
|
+
And his automobiles contain the seventh Automobile created
|
191
|
+
And I store him in the database
|
192
|
+
And I reopen database for reading
|
193
|
+
Then there should be 2 Caveman(s)
|
194
|
+
And there should be 7 Automobile(s)
|
195
|
+
And the first Caveman should have 4 automobiles
|
196
|
+
And the second Caveman should have 5 automobiles
|
197
|
+
And the intersection size of automobiles of the first and the second Caveman should equal 2
|
198
|
+
|
199
|
+
When the database is created
|
200
|
+
And I create an Automobile
|
201
|
+
And its name is 'Car 1'
|
202
|
+
And I store it in the database
|
203
|
+
And I create another Automobile
|
204
|
+
And its name is 'Car 2'
|
205
|
+
And I store it in the database
|
206
|
+
And I create another Automobile
|
207
|
+
And its name is 'Car 3'
|
208
|
+
And I store it in the database
|
209
|
+
And I create another Automobile
|
210
|
+
And its name is 'Car 4'
|
211
|
+
And I store it in the database
|
212
|
+
And I create another Automobile
|
213
|
+
And its name is 'Car 5'
|
214
|
+
And I store it in the database
|
215
|
+
And I create another Automobile
|
216
|
+
And its name is 'Car 6'
|
217
|
+
And I store it in the database
|
218
|
+
And I create another Automobile
|
219
|
+
And its name is 'Car 7'
|
220
|
+
And I store it in the database
|
221
|
+
And I create a Caveman
|
222
|
+
And his name is 'Fred'
|
223
|
+
And his automobiles contain the first Automobile created
|
224
|
+
And his automobiles contain the fifth Automobile created
|
225
|
+
And his automobiles contain the sixth Automobile created
|
226
|
+
And his automobiles contain the seventh Automobile created
|
227
|
+
And I store him in the database
|
228
|
+
And I create another Caveman
|
229
|
+
And his name is 'Bill'
|
230
|
+
And his automobiles contain the first Automobile created
|
231
|
+
And his automobiles contain the second Automobile created
|
232
|
+
And his automobiles contain the third Automobile created
|
233
|
+
And his automobiles contain the sixth Automobile created
|
234
|
+
And I store him in the database
|
235
|
+
And I reopen database for reading
|
236
|
+
Then there should be 2 Caveman(s)
|
237
|
+
And there should be 7 Automobile(s)
|
238
|
+
And the first Caveman should have 4 automobiles
|
239
|
+
And the second Caveman should have 4 automobiles
|
240
|
+
And the intersection size of automobiles of the first and the second Caveman should equal 2
|