sequel_mapper 0.0.1 → 0.0.3

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CODE_OF_CONDUCT.md +28 -0
  4. data/Gemfile.lock +32 -2
  5. data/MissingFeatures.md +64 -0
  6. data/README.md +141 -72
  7. data/Rakefile +29 -0
  8. data/TODO.md +16 -11
  9. data/features/env.rb +57 -0
  10. data/features/example.feature +121 -0
  11. data/features/step_definitions/example_steps.rb +46 -0
  12. data/lib/sequel_mapper.rb +6 -2
  13. data/lib/sequel_mapper/abstract_record.rb +53 -0
  14. data/lib/sequel_mapper/association_loaders.rb +52 -0
  15. data/lib/sequel_mapper/collection_mutability_proxy.rb +77 -0
  16. data/lib/sequel_mapper/configurations/conventional_association_configuration.rb +187 -0
  17. data/lib/sequel_mapper/configurations/conventional_configuration.rb +269 -0
  18. data/lib/sequel_mapper/dataset.rb +37 -0
  19. data/lib/sequel_mapper/deleted_record.rb +16 -0
  20. data/lib/sequel_mapper/dirty_map.rb +31 -0
  21. data/lib/sequel_mapper/graph_loader.rb +48 -0
  22. data/lib/sequel_mapper/graph_serializer.rb +107 -0
  23. data/lib/sequel_mapper/identity_map.rb +22 -0
  24. data/lib/sequel_mapper/lazy_object_proxy.rb +51 -0
  25. data/lib/sequel_mapper/many_to_many_association.rb +181 -0
  26. data/lib/sequel_mapper/many_to_one_association.rb +60 -0
  27. data/lib/sequel_mapper/mapper_facade.rb +180 -0
  28. data/lib/sequel_mapper/one_to_many_association.rb +51 -0
  29. data/lib/sequel_mapper/public_conveniencies.rb +27 -0
  30. data/lib/sequel_mapper/query_order.rb +32 -0
  31. data/lib/sequel_mapper/queryable_lazy_dataset_loader.rb +70 -0
  32. data/lib/sequel_mapper/relation_mapping.rb +35 -0
  33. data/lib/sequel_mapper/serializer.rb +18 -0
  34. data/lib/sequel_mapper/short_inspection_string.rb +18 -0
  35. data/lib/sequel_mapper/subset_queries_proxy.rb +11 -0
  36. data/lib/sequel_mapper/upserted_record.rb +15 -0
  37. data/lib/sequel_mapper/version.rb +1 -1
  38. data/sequel_mapper.gemspec +3 -0
  39. data/spec/config_override_spec.rb +167 -0
  40. data/spec/custom_serializers_spec.rb +77 -0
  41. data/spec/deletion_spec.rb +104 -0
  42. data/spec/graph_persistence_spec.rb +83 -88
  43. data/spec/graph_traversal_spec.rb +32 -31
  44. data/spec/new_graph_persistence_spec.rb +69 -0
  45. data/spec/object_identity_spec.rb +70 -0
  46. data/spec/ordered_association_spec.rb +46 -16
  47. data/spec/persistence_efficiency_spec.rb +186 -0
  48. data/spec/predefined_queries_spec.rb +73 -0
  49. data/spec/proxying_spec.rb +25 -19
  50. data/spec/querying_spec.rb +24 -27
  51. data/spec/readme_examples_spec.rb +35 -0
  52. data/spec/sequel_mapper/abstract_record_spec.rb +179 -0
  53. data/spec/sequel_mapper/{association_proxy_spec.rb → collection_mutability_proxy_spec.rb} +6 -6
  54. data/spec/sequel_mapper/deleted_record_spec.rb +59 -0
  55. data/spec/sequel_mapper/lazy_object_proxy_spec.rb +140 -0
  56. data/spec/sequel_mapper/public_conveniencies_spec.rb +49 -0
  57. data/spec/sequel_mapper/queryable_lazy_dataset_loader_spec.rb +103 -0
  58. data/spec/sequel_mapper/upserted_record_spec.rb +59 -0
  59. data/spec/spec_helper.rb +7 -10
  60. data/spec/support/blog_schema.rb +29 -0
  61. data/spec/support/have_persisted_matcher.rb +19 -0
  62. data/spec/support/mapper_setup.rb +234 -0
  63. data/spec/support/mock_sequel.rb +0 -1
  64. data/spec/support/object_graph_setup.rb +106 -0
  65. data/spec/support/seed_data_setup.rb +122 -0
  66. data/spec/support/sequel_persistence_setup.rb +19 -0
  67. data/spec/support/sequel_test_support.rb +159 -0
  68. metadata +121 -15
  69. data/lib/sequel_mapper/association_proxy.rb +0 -54
  70. data/lib/sequel_mapper/belongs_to_association_proxy.rb +0 -27
  71. data/lib/sequel_mapper/graph.rb +0 -174
  72. data/lib/sequel_mapper/queryable_association_proxy.rb +0 -23
  73. data/spec/sequel_mapper/belongs_to_association_proxy_spec.rb +0 -65
  74. data/spec/support/graph_fixture.rb +0 -331
  75. data/spec/support/query_counter.rb +0 -29
@@ -0,0 +1,19 @@
1
+ require "support/sequel_test_support"
2
+
3
+ RSpec.shared_context "sequel persistence setup" do
4
+ include SequelMapper::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
+ SequelMapper::SequelTestSupport::QueryCounter.new
18
+ }
19
+ end
@@ -0,0 +1,159 @@
1
+ require "sequel"
2
+
3
+ module SequelMapper
4
+ module SequelTestSupport
5
+ def create_database
6
+ `psql postgres --command "CREATE DATABASE $PGDATABASE;"`
7
+ end
8
+ module_function :create_database
9
+
10
+ def drop_database
11
+ `psql postgres --command "DROP DATABASE $PGDATABASE;"`
12
+ end
13
+ module_function :drop_database
14
+
15
+ def drop_tables
16
+ db_connection.tables.each do |table_name|
17
+ db_connection.drop_table(table_name)
18
+ end
19
+ end
20
+ module_function :drop_tables
21
+
22
+ def truncate_tables
23
+ db_connection.tables.each do |table_name|
24
+ db_connection[table_name].truncate
25
+ end
26
+ end
27
+ module_function :truncate_tables
28
+
29
+ def db_connection
30
+ Sequel.default_timezone = :utc
31
+ @db_connection ||= Sequel.postgres(
32
+ host: ENV.fetch("PGHOST"),
33
+ user: ENV.fetch("PGUSER"),
34
+ database: ENV.fetch("PGDATABASE"),
35
+ )
36
+ end
37
+ module_function :db_connection
38
+
39
+ def create_tables(schema)
40
+ options_map = {
41
+ id: { primary_key: true },
42
+ }
43
+
44
+ schema.each do |table_name, fields|
45
+
46
+ db_connection.create_table(table_name) do
47
+ fields.each do |field|
48
+ type = field.fetch(:type)
49
+ name = field.fetch(:name)
50
+ options = options_map.fetch(name, {})
51
+
52
+ send(type, name, options)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ module_function :create_tables
58
+
59
+ def insert_records(datastore, records)
60
+ records.each { |(namespace, record)|
61
+ datastore[namespace].insert(record)
62
+ }
63
+ end
64
+
65
+ class QueryCounter
66
+ def initialize
67
+ reset
68
+ end
69
+
70
+ def read_count
71
+ read_count_with_describes -
72
+ list_tables_query_count -
73
+ describe_table_queries_count
74
+ end
75
+
76
+ def delete_count
77
+ @info.count { |query|
78
+ /\A\([0-9\.]+s\) DELETE/i === query
79
+ }
80
+ end
81
+
82
+ def read_count_with_describes
83
+ @info.count { |query|
84
+ /\A\([0-9\.]+s\) SELECT/i === query
85
+ }
86
+ end
87
+
88
+ def update_count
89
+ @info.count { |query|
90
+ /\A\([0-9\.]+s\) UPDATE/i === query
91
+ }
92
+ end
93
+
94
+ def show_queries
95
+ puts @info.join("\n")
96
+ end
97
+
98
+ def info(message)
99
+ @info.push(message)
100
+ end
101
+
102
+ def error(message)
103
+ @error.push(message)
104
+ end
105
+
106
+ def warn(message)
107
+ @warn.push(message)
108
+ end
109
+
110
+ def reset
111
+ @described_table_queries = []
112
+ @info = []
113
+ @error = []
114
+ @warn = []
115
+ end
116
+
117
+ private
118
+
119
+ def list_tables_query_count
120
+ @info.count { |query| list_tables_query_pattern.match(query) }
121
+ end
122
+
123
+ def describe_table_queries_count
124
+ describe_table_queries.count
125
+ end
126
+
127
+ def describe_table_queries
128
+ # TODO this could probably be better solved with finite automata
129
+ described_table_queries = []
130
+
131
+ queries_without_table_list
132
+ .take_while { |query|
133
+ described_table_queries.push(query)
134
+ described_table_query_pattern.match(query) &&
135
+ described_table_queries.length == described_table_queries.uniq.length
136
+ }
137
+ end
138
+
139
+ def queries_without_table_list
140
+ @info
141
+ .drop_while { |query|
142
+ !list_tables_query_pattern.match(query)
143
+ }
144
+ .drop_while { |query|
145
+ list_tables_query_pattern.match(query)
146
+ }
147
+ end
148
+
149
+
150
+ def list_tables_query_pattern
151
+ /\A\([0-9\.]+s\) SELECT "relname" FROM "pg_class"/
152
+ end
153
+
154
+ def described_table_query_pattern
155
+ /\A\([0-9\.]+s\) SELECT \* FROM "[^"]+" LIMIT 1/i
156
+ end
157
+ end
158
+ end
159
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Best
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-27 00:00:00.000000000 Z
11
+ date: 2016-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: cucumber
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pg
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,34 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '4.16'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '4.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '4.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: fetchable
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
97
139
  description: ''
98
140
  email:
99
141
  - bestie@gmail.com
@@ -104,31 +146,74 @@ files:
104
146
  - ".gitignore"
105
147
  - ".rspec"
106
148
  - ".ruby-version"
149
+ - CODE_OF_CONDUCT.md
107
150
  - Gemfile
108
151
  - Gemfile.lock
109
152
  - LICENSE.txt
153
+ - MissingFeatures.md
110
154
  - README.md
111
155
  - Rakefile
112
156
  - TODO.md
157
+ - features/env.rb
158
+ - features/example.feature
159
+ - features/step_definitions/example_steps.rb
113
160
  - lib/sequel_mapper.rb
114
- - lib/sequel_mapper/association_proxy.rb
115
- - lib/sequel_mapper/belongs_to_association_proxy.rb
116
- - lib/sequel_mapper/graph.rb
117
- - lib/sequel_mapper/queryable_association_proxy.rb
161
+ - lib/sequel_mapper/abstract_record.rb
162
+ - lib/sequel_mapper/association_loaders.rb
163
+ - lib/sequel_mapper/collection_mutability_proxy.rb
164
+ - lib/sequel_mapper/configurations/conventional_association_configuration.rb
165
+ - lib/sequel_mapper/configurations/conventional_configuration.rb
166
+ - lib/sequel_mapper/dataset.rb
167
+ - lib/sequel_mapper/deleted_record.rb
168
+ - lib/sequel_mapper/dirty_map.rb
169
+ - lib/sequel_mapper/graph_loader.rb
170
+ - lib/sequel_mapper/graph_serializer.rb
171
+ - lib/sequel_mapper/identity_map.rb
172
+ - lib/sequel_mapper/lazy_object_proxy.rb
173
+ - lib/sequel_mapper/many_to_many_association.rb
174
+ - lib/sequel_mapper/many_to_one_association.rb
175
+ - lib/sequel_mapper/mapper_facade.rb
176
+ - lib/sequel_mapper/one_to_many_association.rb
177
+ - lib/sequel_mapper/public_conveniencies.rb
178
+ - lib/sequel_mapper/query_order.rb
179
+ - lib/sequel_mapper/queryable_lazy_dataset_loader.rb
180
+ - lib/sequel_mapper/relation_mapping.rb
181
+ - lib/sequel_mapper/serializer.rb
182
+ - lib/sequel_mapper/short_inspection_string.rb
118
183
  - lib/sequel_mapper/struct_factory.rb
184
+ - lib/sequel_mapper/subset_queries_proxy.rb
185
+ - lib/sequel_mapper/upserted_record.rb
119
186
  - lib/sequel_mapper/version.rb
120
187
  - sequel_mapper.gemspec
188
+ - spec/config_override_spec.rb
189
+ - spec/custom_serializers_spec.rb
190
+ - spec/deletion_spec.rb
121
191
  - spec/graph_persistence_spec.rb
122
192
  - spec/graph_traversal_spec.rb
193
+ - spec/new_graph_persistence_spec.rb
194
+ - spec/object_identity_spec.rb
123
195
  - spec/ordered_association_spec.rb
196
+ - spec/persistence_efficiency_spec.rb
197
+ - spec/predefined_queries_spec.rb
124
198
  - spec/proxying_spec.rb
125
199
  - spec/querying_spec.rb
126
- - spec/sequel_mapper/association_proxy_spec.rb
127
- - spec/sequel_mapper/belongs_to_association_proxy_spec.rb
200
+ - 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/lazy_object_proxy_spec.rb
205
+ - spec/sequel_mapper/public_conveniencies_spec.rb
206
+ - spec/sequel_mapper/queryable_lazy_dataset_loader_spec.rb
207
+ - spec/sequel_mapper/upserted_record_spec.rb
128
208
  - spec/spec_helper.rb
129
- - spec/support/graph_fixture.rb
209
+ - spec/support/blog_schema.rb
210
+ - spec/support/have_persisted_matcher.rb
211
+ - spec/support/mapper_setup.rb
130
212
  - spec/support/mock_sequel.rb
131
- - spec/support/query_counter.rb
213
+ - spec/support/object_graph_setup.rb
214
+ - spec/support/seed_data_setup.rb
215
+ - spec/support/sequel_persistence_setup.rb
216
+ - spec/support/sequel_test_support.rb
132
217
  homepage: https://github.com/bestie/sequel_mapper
133
218
  licenses:
134
219
  - MIT
@@ -149,19 +234,40 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
234
  version: '0'
150
235
  requirements: []
151
236
  rubyforge_project:
152
- rubygems_version: 2.2.2
237
+ rubygems_version: 2.4.5
153
238
  signing_key:
154
239
  specification_version: 4
155
240
  summary: A data mapper built on top of the Sequel database toolkit
156
241
  test_files:
242
+ - features/env.rb
243
+ - features/example.feature
244
+ - features/step_definitions/example_steps.rb
245
+ - spec/config_override_spec.rb
246
+ - spec/custom_serializers_spec.rb
247
+ - spec/deletion_spec.rb
157
248
  - spec/graph_persistence_spec.rb
158
249
  - spec/graph_traversal_spec.rb
250
+ - spec/new_graph_persistence_spec.rb
251
+ - spec/object_identity_spec.rb
159
252
  - spec/ordered_association_spec.rb
253
+ - spec/persistence_efficiency_spec.rb
254
+ - spec/predefined_queries_spec.rb
160
255
  - spec/proxying_spec.rb
161
256
  - spec/querying_spec.rb
162
- - spec/sequel_mapper/association_proxy_spec.rb
163
- - spec/sequel_mapper/belongs_to_association_proxy_spec.rb
257
+ - spec/readme_examples_spec.rb
258
+ - spec/sequel_mapper/abstract_record_spec.rb
259
+ - spec/sequel_mapper/collection_mutability_proxy_spec.rb
260
+ - spec/sequel_mapper/deleted_record_spec.rb
261
+ - spec/sequel_mapper/lazy_object_proxy_spec.rb
262
+ - spec/sequel_mapper/public_conveniencies_spec.rb
263
+ - spec/sequel_mapper/queryable_lazy_dataset_loader_spec.rb
264
+ - spec/sequel_mapper/upserted_record_spec.rb
164
265
  - spec/spec_helper.rb
165
- - spec/support/graph_fixture.rb
266
+ - spec/support/blog_schema.rb
267
+ - spec/support/have_persisted_matcher.rb
268
+ - spec/support/mapper_setup.rb
166
269
  - spec/support/mock_sequel.rb
167
- - spec/support/query_counter.rb
270
+ - spec/support/object_graph_setup.rb
271
+ - spec/support/seed_data_setup.rb
272
+ - spec/support/sequel_persistence_setup.rb
273
+ - spec/support/sequel_test_support.rb
@@ -1,54 +0,0 @@
1
- require "forwardable"
2
-
3
- module SequelMapper
4
- class AssociationProxy
5
- def initialize(assoc_enum)
6
- @assoc_enum = assoc_enum
7
- @added_nodes = []
8
- @removed_nodes = []
9
- end
10
-
11
- attr_reader :assoc_enum, :removed_nodes, :added_nodes
12
- private :assoc_enum
13
-
14
- include Enumerable
15
- def each(&block)
16
- enum = Enumerator.new do |yielder|
17
- assoc_enum.each do |element|
18
- yielder.yield(element) unless removed?(element)
19
- end
20
-
21
- @added_nodes.each do |node|
22
- yielder.yield(node)
23
- end
24
- end
25
-
26
- if block
27
- enum.each(&block)
28
- self
29
- else
30
- enum
31
- end
32
- end
33
-
34
- def remove(node)
35
- @removed_nodes.push(node)
36
- self
37
- end
38
-
39
- def push(node)
40
- @added_nodes.push(node)
41
- end
42
-
43
- def where(criteria)
44
- @assoc_enum.where(criteria)
45
- self
46
- end
47
-
48
- private
49
-
50
- def removed?(node)
51
- @removed_nodes.include?(node)
52
- end
53
- end
54
- end
@@ -1,27 +0,0 @@
1
- require "delegate"
2
-
3
- class BelongsToAssociationProxy < SimpleDelegator
4
- def initialize(object_loader)
5
- @object_loader = object_loader
6
- @loaded = false
7
- end
8
-
9
- def method_missing(method_id, *args, &block)
10
- __load_object__
11
-
12
- super
13
- end
14
-
15
- def __getobj__
16
- __load_object__
17
- super
18
- end
19
-
20
- private
21
-
22
- def __load_object__
23
- __setobj__(@object_loader.call).tap {
24
- @loaded = true
25
- } unless @loaded
26
- end
27
- end