terrestrial 0.1.1 → 0.3.0

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 (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
@@ -1,193 +0,0 @@
1
- class Terrestrial::MockSequel
2
- def initialize(relations)
3
- @relations = {}
4
-
5
- relations.each do |table_name|
6
- @relations[table_name] = Relation.new(self, [])
7
- end
8
-
9
- @reads, @writes, @deletes = 0, 0, 0
10
- end
11
-
12
- attr_reader :relations
13
- private :relations
14
-
15
- def [](table_name)
16
- @relations.fetch(table_name)
17
- end
18
-
19
- def log_read
20
- @reads += 1
21
- end
22
-
23
- def log_write
24
- @writes += 1
25
- end
26
-
27
- def log_delete
28
- @deletes += 1
29
- end
30
-
31
- def read_count
32
- @reads
33
- end
34
-
35
- def write_count
36
- @writes
37
- end
38
-
39
- def delete_count
40
- @deletes
41
- end
42
-
43
- class Query
44
- def initialize(criteria: {}, order: [], reverse: false, &block)
45
- if block
46
- raise NotImplementedError.new("Block filtering not implemented")
47
- end
48
-
49
- @criteria = criteria
50
- @order_columns = order
51
- @reverse_order = reverse
52
- end
53
-
54
- attr_reader :criteria, :order_columns
55
-
56
- def where(new_criteria, &block)
57
- self.class.new(
58
- criteria: criteria.merge(new_criteria),
59
- order: order,
60
- reverse: reverse,
61
- &block
62
- )
63
- end
64
-
65
- def order(columns)
66
- self.class.new(
67
- criteria: criteria,
68
- order: columns,
69
- )
70
- end
71
-
72
- def reverse
73
- self.class.new(
74
- criteria: criteria,
75
- order: order_columns,
76
- reverse: true,
77
- )
78
- end
79
-
80
- def reverse_order?
81
- !!@reverse_order
82
- end
83
- end
84
-
85
- class Relation
86
- include Enumerable
87
-
88
- def initialize(database, all_rows, applied_query: Query.new)
89
- @database = database
90
- @all_rows = all_rows
91
- @applied_query = applied_query
92
- end
93
-
94
- attr_reader :database, :all_rows, :applied_query
95
- private :database, :all_rows, :applied_query
96
-
97
- def where(criteria, &block)
98
- new_with_query(Query.new(criteria: criteria, &block))
99
- end
100
-
101
- def order(columns)
102
- new_with_query(applied_query.order(columns))
103
- end
104
-
105
- def reverse
106
- @applied_query = @applied_query.reverse
107
- end
108
-
109
- def to_a
110
- database.log_read
111
-
112
- matching_rows
113
- end
114
-
115
- def each(&block)
116
- database.log_read
117
-
118
- matching_rows.each(&block)
119
- end
120
-
121
- def delete
122
- database.log_delete
123
-
124
- matching_rows.each do |row_to_delete|
125
- all_rows.delete(row_to_delete)
126
- end
127
- end
128
-
129
- def insert(new_row)
130
- database.log_write
131
-
132
- all_rows.push(new_row)
133
- end
134
-
135
- def update(attrs)
136
- database.log_write
137
-
138
- # No need to get the rows from the canonical relation as the hashes can
139
- # just be mutated in plaace.
140
- matching_rows.each do |row|
141
- attrs.each do |k, v|
142
- row[k] = v
143
- end
144
- end
145
- end
146
-
147
- def empty?
148
- database.log_read
149
-
150
- matching_rows.empty?
151
- end
152
-
153
- private
154
-
155
- def matching_rows
156
- apply_sort(
157
- equality_filter(all_rows, applied_query.criteria),
158
- applied_query.order_columns,
159
- applied_query.reverse_order?,
160
- )
161
- end
162
-
163
- def apply_sort(rows, order_columns, reverse_order)
164
- sorted_rows = rows.sort_by{ |row|
165
- order_columns.map { |col| row.fetch(col) }
166
- }
167
-
168
- if reverse_order
169
- sorted_rows.reverse
170
- else
171
- sorted_rows
172
- end
173
- end
174
-
175
- def equality_filter(rows, criteria)
176
- rows.select { |row|
177
- criteria.all? { |k, v|
178
- if v.is_a?(Enumerable)
179
- v.include?(row.fetch(k))
180
- else
181
- row.fetch(k) == v
182
- end
183
- }
184
- }
185
- end
186
-
187
- private
188
-
189
- def new_with_query(query)
190
- self.class.new(database, all_rows, applied_query: query)
191
- end
192
- end
193
- end
@@ -1,19 +0,0 @@
1
- require "support/sequel_test_support"
2
-
3
- RSpec.shared_context "sequel persistence setup" do
4
- include Terrestrial::SequelTestSupport
5
-
6
- before { truncate_tables }
7
-
8
- let(:datastore) {
9
- db_connection.tap { |db|
10
- # The query_counter will let us make assertions about how efficiently
11
- # the database is being used
12
- db.loggers << query_counter
13
- }
14
- }
15
-
16
- let(:query_counter) {
17
- Terrestrial::SequelTestSupport::QueryCounter.new
18
- }
19
- end