terrestrial 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile.lock +29 -24
  4. data/README.md +35 -17
  5. data/Rakefile +4 -9
  6. data/TODO.md +25 -18
  7. data/bin/test +31 -0
  8. data/docs/domain_object_contract.md +50 -0
  9. data/features/env.rb +4 -6
  10. data/features/example.feature +28 -28
  11. data/features/step_definitions/example_steps.rb +2 -2
  12. data/lib/terrestrial/adapters/memory_adapter.rb +241 -0
  13. data/lib/terrestrial/collection_mutability_proxy.rb +7 -2
  14. data/lib/terrestrial/dirty_map.rb +5 -0
  15. data/lib/terrestrial/error.rb +69 -0
  16. data/lib/terrestrial/graph_loader.rb +58 -35
  17. data/lib/terrestrial/graph_serializer.rb +37 -30
  18. data/lib/terrestrial/inspection_string.rb +19 -0
  19. data/lib/terrestrial/lazy_collection.rb +2 -2
  20. data/lib/terrestrial/lazy_object_proxy.rb +1 -1
  21. data/lib/terrestrial/many_to_one_association.rb +17 -11
  22. data/lib/terrestrial/public_conveniencies.rb +125 -95
  23. data/lib/terrestrial/relation_mapping.rb +30 -0
  24. data/lib/terrestrial/{mapper_facade.rb → relational_store.rb} +11 -1
  25. data/lib/terrestrial/version.rb +1 -1
  26. data/spec/config_override_spec.rb +10 -14
  27. data/spec/custom_serializers_spec.rb +4 -6
  28. data/spec/deletion_spec.rb +12 -14
  29. data/spec/error_handling/factory_error_handling_spec.rb +61 -0
  30. data/spec/error_handling/serialization_error_spec.rb +50 -0
  31. data/spec/error_handling/upsert_error_spec.rb +132 -0
  32. data/spec/graph_persistence_spec.rb +80 -24
  33. data/spec/graph_traversal_spec.rb +14 -6
  34. data/spec/new_graph_persistence_spec.rb +43 -9
  35. data/spec/object_identity_spec.rb +5 -7
  36. data/spec/ordered_association_spec.rb +4 -6
  37. data/spec/predefined_queries_spec.rb +4 -6
  38. data/spec/querying_spec.rb +4 -12
  39. data/spec/readme_examples_spec.rb +3 -6
  40. data/spec/{persistence_efficiency_spec.rb → sequel_query_efficiency_spec.rb} +101 -19
  41. data/spec/spec_helper.rb +24 -2
  42. data/spec/support/memory_adapter_test_support.rb +21 -0
  43. data/spec/support/{mapper_setup.rb → object_store_setup.rb} +5 -5
  44. data/spec/support/seed_data_setup.rb +3 -1
  45. data/spec/support/sequel_test_support.rb +58 -25
  46. data/spec/{sequel_mapper → terrestrial}/abstract_record_spec.rb +0 -0
  47. data/spec/{sequel_mapper → terrestrial}/collection_mutability_proxy_spec.rb +0 -0
  48. data/spec/{sequel_mapper → terrestrial}/deleted_record_spec.rb +0 -0
  49. data/spec/{sequel_mapper → terrestrial}/dirty_map_spec.rb +38 -6
  50. data/spec/{sequel_mapper → terrestrial}/lazy_collection_spec.rb +2 -3
  51. data/spec/{sequel_mapper → terrestrial}/lazy_object_proxy_spec.rb +0 -0
  52. data/spec/{sequel_mapper → terrestrial}/public_conveniencies_spec.rb +12 -7
  53. data/spec/{sequel_mapper → terrestrial}/upserted_record_spec.rb +0 -0
  54. data/{sequel_mapper.gemspec → terrestrial.gemspec} +3 -3
  55. metadata +47 -39
  56. data/lib/terrestrial/short_inspection_string.rb +0 -18
  57. data/spec/proxying_spec.rb +0 -88
  58. data/spec/support/mock_sequel.rb +0 -193
  59. data/spec/support/sequel_persistence_setup.rb +0 -19
@@ -11,7 +11,7 @@ RSpec.describe Terrestrial::DirtyMap do
11
11
 
12
12
  let(:storage) { {} }
13
13
 
14
- let(:loaded_record) {
14
+ let(:record) {
15
15
  create_record( namespace, identity_fields, attributes, depth)
16
16
  }
17
17
 
@@ -27,15 +27,47 @@ RSpec.describe Terrestrial::DirtyMap do
27
27
  }
28
28
  }
29
29
 
30
+ describe "#load_if_new" do
31
+ context "when a record is new" do
32
+ it "adds it to the map" do
33
+ dirty_map.load_if_new(record)
34
+
35
+ expect(storage).to include([:table_name, { id: "record/id" }])
36
+ end
37
+
38
+ it "returns the record" do
39
+ expect(dirty_map.load_if_new(record)).to eq(record)
40
+ end
41
+ end
42
+
43
+ context "when the record has already been loaded" do
44
+ let(:storage) {
45
+ {
46
+ [:table_name, { id: "record/id" }] => record
47
+ }
48
+ }
49
+
50
+ it "has no effect on the storage" do
51
+ expect {
52
+ dirty_map.load_if_new(record)
53
+ }.not_to change { storage }
54
+ end
55
+
56
+ it "returns the record" do
57
+ expect(dirty_map.load_if_new(record)).to eq(record)
58
+ end
59
+ end
60
+ end
61
+
30
62
  describe "#load" do
31
63
  it "adds the record to its storage" do
32
- dirty_map.load(loaded_record)
64
+ dirty_map.load(record)
33
65
 
34
- expect(storage.values).to include(loaded_record)
66
+ expect(storage.values).to include(record)
35
67
  end
36
68
 
37
69
  it "returns the loaded record" do
38
- expect(dirty_map.load(loaded_record)).to eq(loaded_record)
70
+ expect(dirty_map.load(record)).to eq(record)
39
71
  end
40
72
  end
41
73
 
@@ -61,7 +93,7 @@ RSpec.describe Terrestrial::DirtyMap do
61
93
 
62
94
  context "when a record with same identity has been loaded (existing record)" do
63
95
  before do
64
- dirty_map.load(loaded_record)
96
+ dirty_map.load(record)
65
97
  end
66
98
 
67
99
  context "when the record is unchanged" do
@@ -181,7 +213,7 @@ RSpec.describe Terrestrial::DirtyMap do
181
213
 
182
214
  context "when a record with same identity has been loaded (existing record)" do
183
215
  before do
184
- dirty_map.load(loaded_record)
216
+ dirty_map.load(record)
185
217
  end
186
218
 
187
219
  context "with a equivalent record" do
@@ -7,7 +7,7 @@ RSpec.describe Terrestrial::LazyCollection do
7
7
  Terrestrial::LazyCollection.new(
8
8
  database_enum,
9
9
  loader,
10
- mapper,
10
+ queries,
11
11
  )
12
12
  }
13
13
 
@@ -24,8 +24,7 @@ RSpec.describe Terrestrial::LazyCollection do
24
24
  let(:collection_size) { row_object_map.size }
25
25
 
26
26
  let(:database_enum) { [row1, row2].each.lazy }
27
-
28
- let(:mapper) { double(:mapper) }
27
+ let(:queries) { {} }
29
28
 
30
29
  let(:loader_count) { @loader_count }
31
30
  let(:loader) {
@@ -1,6 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  require "terrestrial/public_conveniencies"
4
+ require "ostruct"
4
5
 
5
6
  RSpec.describe Terrestrial::PublicConveniencies do
6
7
  subject(:conveniences) {
@@ -13,7 +14,7 @@ RSpec.describe Terrestrial::PublicConveniencies do
13
14
  end
14
15
  end
15
16
 
16
- describe "#mappers" do
17
+ describe "#object_store" do
17
18
  let(:datastore) {
18
19
  MockDatastore.new(
19
20
  {
@@ -22,7 +23,7 @@ RSpec.describe Terrestrial::PublicConveniencies do
22
23
  )
23
24
  }
24
25
 
25
- let(:mapper_config) {
26
+ let(:mappings) {
26
27
  {
27
28
  things: double(
28
29
  :thing_config,
@@ -31,7 +32,7 @@ RSpec.describe Terrestrial::PublicConveniencies do
31
32
  fields: [:id],
32
33
  associations: [],
33
34
  primary_key: [],
34
- factory: ->(x){x}
35
+ load: thing_object,
35
36
  )
36
37
  }
37
38
  }
@@ -44,14 +45,18 @@ RSpec.describe Terrestrial::PublicConveniencies do
44
45
  }
45
46
  }
46
47
 
47
- it "returns a mapper for the specified mapping" do
48
- mappers = conveniences.mappers(
49
- mappings: mapper_config,
48
+ let(:thing_object) {
49
+ OpenStruct.new(thing_record)
50
+ }
51
+
52
+ it "returns an object store for given mappings" do
53
+ object_store = conveniences.object_store(
54
+ mappings: mappings,
50
55
  datastore: datastore,
51
56
  )
52
57
 
53
58
  expect(
54
- mappers[:things].all.first.fetch(:id)
59
+ object_store[:things].all.first.id
55
60
  ).to eq("THE THING")
56
61
  end
57
62
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Terrestrial::VERSION
9
9
  spec.authors = ["Stephen Best"]
10
10
  spec.email = ["bestie@gmail.com"]
11
- spec.summary = %q{A data mapping ORM to make your objects feel less alien}
12
- spec.description = %q{Terrestial persists your POROs while keeping them free of database concerns.}
11
+ spec.summary = %q{A data mapper ORM for Ruby}
12
+ spec.description = %q{A data mapper ORM for Ruby. Persists POROs, enables DDD and fast tests. Makes your objects less alien.}
13
13
  spec.homepage = "https://github.com/bestie/terrestrial"
14
14
  spec.license = "MIT"
15
15
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "pry", "~> 0.10.1"
24
24
  spec.add_development_dependency "rspec", "~> 3.1"
25
- spec.add_development_dependency "cucumber"
25
+ spec.add_development_dependency "cucumber", "~> 2.4"
26
26
  spec.add_development_dependency "pg", "~> 0.17.1"
27
27
 
28
28
  spec.add_dependency "sequel", "~> 4.16"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terrestrial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Best
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-04 00:00:00.000000000 Z
11
+ date: 2017-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: cucumber
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '2.4'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '2.4'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pg
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,10 +136,12 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '1.0'
139
- description: Terrestial persists your POROs while keeping them free of database concerns.
139
+ description: A data mapper ORM for Ruby. Persists POROs, enables DDD and fast tests.
140
+ Makes your objects less alien.
140
141
  email:
141
142
  - bestie@gmail.com
142
- executables: []
143
+ executables:
144
+ - test
143
145
  extensions: []
144
146
  extra_rdoc_files: []
145
147
  files:
@@ -154,11 +156,14 @@ files:
154
156
  - README.md
155
157
  - Rakefile
156
158
  - TODO.md
159
+ - bin/test
160
+ - docs/domain_object_contract.md
157
161
  - features/env.rb
158
162
  - features/example.feature
159
163
  - features/step_definitions/example_steps.rb
160
164
  - lib/terrestrial.rb
161
165
  - lib/terrestrial/abstract_record.rb
166
+ - lib/terrestrial/adapters/memory_adapter.rb
162
167
  - lib/terrestrial/association_loaders.rb
163
168
  - lib/terrestrial/collection_mutability_proxy.rb
164
169
  - lib/terrestrial/configurations/conventional_association_configuration.rb
@@ -166,55 +171,57 @@ files:
166
171
  - lib/terrestrial/dataset.rb
167
172
  - lib/terrestrial/deleted_record.rb
168
173
  - lib/terrestrial/dirty_map.rb
174
+ - lib/terrestrial/error.rb
169
175
  - lib/terrestrial/graph_loader.rb
170
176
  - lib/terrestrial/graph_serializer.rb
171
177
  - lib/terrestrial/identity_map.rb
178
+ - lib/terrestrial/inspection_string.rb
172
179
  - lib/terrestrial/lazy_collection.rb
173
180
  - lib/terrestrial/lazy_object_proxy.rb
174
181
  - lib/terrestrial/many_to_many_association.rb
175
182
  - lib/terrestrial/many_to_one_association.rb
176
- - lib/terrestrial/mapper_facade.rb
177
183
  - lib/terrestrial/one_to_many_association.rb
178
184
  - lib/terrestrial/public_conveniencies.rb
179
185
  - lib/terrestrial/query_order.rb
180
186
  - lib/terrestrial/relation_mapping.rb
187
+ - lib/terrestrial/relational_store.rb
181
188
  - lib/terrestrial/serializer.rb
182
- - lib/terrestrial/short_inspection_string.rb
183
189
  - lib/terrestrial/struct_factory.rb
184
190
  - lib/terrestrial/subset_queries_proxy.rb
185
191
  - lib/terrestrial/upserted_record.rb
186
192
  - lib/terrestrial/version.rb
187
- - sequel_mapper.gemspec
188
193
  - spec/config_override_spec.rb
189
194
  - spec/custom_serializers_spec.rb
190
195
  - spec/deletion_spec.rb
196
+ - spec/error_handling/factory_error_handling_spec.rb
197
+ - spec/error_handling/serialization_error_spec.rb
198
+ - spec/error_handling/upsert_error_spec.rb
191
199
  - spec/graph_persistence_spec.rb
192
200
  - spec/graph_traversal_spec.rb
193
201
  - spec/new_graph_persistence_spec.rb
194
202
  - spec/object_identity_spec.rb
195
203
  - spec/ordered_association_spec.rb
196
- - spec/persistence_efficiency_spec.rb
197
204
  - spec/predefined_queries_spec.rb
198
- - spec/proxying_spec.rb
199
205
  - spec/querying_spec.rb
200
206
  - spec/readme_examples_spec.rb
201
- - spec/sequel_mapper/abstract_record_spec.rb
202
- - spec/sequel_mapper/collection_mutability_proxy_spec.rb
203
- - spec/sequel_mapper/deleted_record_spec.rb
204
- - spec/sequel_mapper/dirty_map_spec.rb
205
- - spec/sequel_mapper/lazy_collection_spec.rb
206
- - spec/sequel_mapper/lazy_object_proxy_spec.rb
207
- - spec/sequel_mapper/public_conveniencies_spec.rb
208
- - spec/sequel_mapper/upserted_record_spec.rb
207
+ - spec/sequel_query_efficiency_spec.rb
209
208
  - spec/spec_helper.rb
210
209
  - spec/support/blog_schema.rb
211
210
  - spec/support/have_persisted_matcher.rb
212
- - spec/support/mapper_setup.rb
213
- - spec/support/mock_sequel.rb
211
+ - spec/support/memory_adapter_test_support.rb
214
212
  - spec/support/object_graph_setup.rb
213
+ - spec/support/object_store_setup.rb
215
214
  - spec/support/seed_data_setup.rb
216
- - spec/support/sequel_persistence_setup.rb
217
215
  - spec/support/sequel_test_support.rb
216
+ - spec/terrestrial/abstract_record_spec.rb
217
+ - spec/terrestrial/collection_mutability_proxy_spec.rb
218
+ - spec/terrestrial/deleted_record_spec.rb
219
+ - spec/terrestrial/dirty_map_spec.rb
220
+ - spec/terrestrial/lazy_collection_spec.rb
221
+ - spec/terrestrial/lazy_object_proxy_spec.rb
222
+ - spec/terrestrial/public_conveniencies_spec.rb
223
+ - spec/terrestrial/upserted_record_spec.rb
224
+ - terrestrial.gemspec
218
225
  homepage: https://github.com/bestie/terrestrial
219
226
  licenses:
220
227
  - MIT
@@ -235,10 +242,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
242
  version: '0'
236
243
  requirements: []
237
244
  rubyforge_project:
238
- rubygems_version: 2.4.5
245
+ rubygems_version: 2.5.1
239
246
  signing_key:
240
247
  specification_version: 4
241
- summary: A data mapping ORM to make your objects feel less alien
248
+ summary: A data mapper ORM for Ruby
242
249
  test_files:
243
250
  - features/env.rb
244
251
  - features/example.feature
@@ -246,30 +253,31 @@ test_files:
246
253
  - spec/config_override_spec.rb
247
254
  - spec/custom_serializers_spec.rb
248
255
  - spec/deletion_spec.rb
256
+ - spec/error_handling/factory_error_handling_spec.rb
257
+ - spec/error_handling/serialization_error_spec.rb
258
+ - spec/error_handling/upsert_error_spec.rb
249
259
  - spec/graph_persistence_spec.rb
250
260
  - spec/graph_traversal_spec.rb
251
261
  - spec/new_graph_persistence_spec.rb
252
262
  - spec/object_identity_spec.rb
253
263
  - spec/ordered_association_spec.rb
254
- - spec/persistence_efficiency_spec.rb
255
264
  - spec/predefined_queries_spec.rb
256
- - spec/proxying_spec.rb
257
265
  - spec/querying_spec.rb
258
266
  - spec/readme_examples_spec.rb
259
- - spec/sequel_mapper/abstract_record_spec.rb
260
- - spec/sequel_mapper/collection_mutability_proxy_spec.rb
261
- - spec/sequel_mapper/deleted_record_spec.rb
262
- - spec/sequel_mapper/dirty_map_spec.rb
263
- - spec/sequel_mapper/lazy_collection_spec.rb
264
- - spec/sequel_mapper/lazy_object_proxy_spec.rb
265
- - spec/sequel_mapper/public_conveniencies_spec.rb
266
- - spec/sequel_mapper/upserted_record_spec.rb
267
+ - spec/sequel_query_efficiency_spec.rb
267
268
  - spec/spec_helper.rb
268
269
  - spec/support/blog_schema.rb
269
270
  - spec/support/have_persisted_matcher.rb
270
- - spec/support/mapper_setup.rb
271
- - spec/support/mock_sequel.rb
271
+ - spec/support/memory_adapter_test_support.rb
272
272
  - spec/support/object_graph_setup.rb
273
+ - spec/support/object_store_setup.rb
273
274
  - spec/support/seed_data_setup.rb
274
- - spec/support/sequel_persistence_setup.rb
275
275
  - spec/support/sequel_test_support.rb
276
+ - spec/terrestrial/abstract_record_spec.rb
277
+ - spec/terrestrial/collection_mutability_proxy_spec.rb
278
+ - spec/terrestrial/deleted_record_spec.rb
279
+ - spec/terrestrial/dirty_map_spec.rb
280
+ - spec/terrestrial/lazy_collection_spec.rb
281
+ - spec/terrestrial/lazy_object_proxy_spec.rb
282
+ - spec/terrestrial/public_conveniencies_spec.rb
283
+ - spec/terrestrial/upserted_record_spec.rb
@@ -1,18 +0,0 @@
1
- module Terrestrial
2
- module ShortInspectionString
3
- def inspect
4
- "\#<#{self.class.name}:#{self.object_id.<<(1).to_s(16)} " +
5
- inspectable_properties.map { |property|
6
- [
7
- property,
8
- instance_variable_get("@#{property}").inspect
9
- ].join("=")
10
- }
11
- .join(" ") + ">"
12
- end
13
-
14
- def inspectable_properties
15
- []
16
- end
17
- end
18
- end
@@ -1,88 +0,0 @@
1
- require "spec_helper"
2
-
3
- require "support/mapper_setup"
4
- require "support/sequel_persistence_setup"
5
- require "support/seed_data_setup"
6
- require "terrestrial"
7
-
8
- RSpec.describe "Proxying associations" do
9
- include_context "mapper setup"
10
- include_context "sequel persistence setup"
11
- include_context "seed data setup"
12
-
13
- context "of type `has_many`" do
14
- subject(:mapper) { user_mapper }
15
-
16
- let(:user) {
17
- mapper.where(id: "users/1").first
18
- }
19
-
20
- let(:posts) { user.posts }
21
-
22
- describe "limiting datastore reads" do
23
- context "when loading the root node" do
24
- it "only performs one read" do
25
- expect {
26
- user
27
- }.to change { query_counter.read_count }.by(1)
28
- end
29
- end
30
-
31
- context "when getting a reference to an association proxy" do
32
- before { user }
33
-
34
- it "does no additional reads" do
35
- expect{
36
- user.posts
37
- }.to change { query_counter.read_count }.by(0)
38
- end
39
- end
40
-
41
- context "when iteratiing over a has many association" do
42
- before { posts }
43
-
44
- it "does a single additional read for the association collection" do
45
- expect {
46
- user.posts.each { |x| x }
47
- }.to change { query_counter.read_count }.by(1)
48
- end
49
-
50
- context "when doing this more than once" do
51
- before do
52
- posts.each { |x| x }
53
- end
54
-
55
- it "performs no additional reads" do
56
- expect {
57
- user.posts.each { |x| x }
58
- }.not_to change { query_counter.read_count }
59
- end
60
- end
61
- end
62
-
63
- context "when getting a reference to a many to many association" do
64
- before { post }
65
-
66
- let(:post) { user.posts.first }
67
-
68
- it "does no additional reads" do
69
- expect {
70
- post.categories
71
- }.to change { query_counter.read_count }.by(0)
72
- end
73
- end
74
-
75
- context "when iterating over a many to many association" do
76
- let(:category_count) { 3 }
77
-
78
- it "does 1 read" do
79
- post = user.posts.first
80
-
81
- expect {
82
- post.categories.each { |x| x }
83
- }.to change { query_counter.read_count }.by(1)
84
- end
85
- end
86
- end
87
- end
88
- end