praxis-mapper 4.3 → 4.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/praxis-mapper/query/base.rb +5 -1
- data/lib/praxis-mapper/query/sql.rb +1 -1
- data/lib/praxis-mapper/selector_generator.rb +17 -9
- data/lib/praxis-mapper/version.rb +1 -1
- data/praxis-mapper.gemspec +5 -5
- data/spec/praxis-mapper/query/base_spec.rb +15 -0
- data/spec/praxis-mapper/selector_generator_spec.rb +41 -0
- data/spec/support/spec_sequel_models.rb +4 -0
- metadata +12 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 537418afacaff7e279f5e83fe0a53b36414fe763
|
4
|
+
data.tar.gz: 443de06327dd6afc1799984487680bbaff421442
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95ab80beda829e6ef44d6fe78d323dc98a91d62f04f96b82bd10cd3ec5927f575dfd83cc0034c47973421c24f3da3a6eee5330ca944f7bfaf1b2ebee9814aa1c
|
7
|
+
data.tar.gz: 983977fdb56fdb9395459ebd66992eefc0e50c4fbda2fda4e5afb713fe56419a1a2eaf40b7c421d6409613dad3f04fdb7f6c6102f74aa6bd978482497460325f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
## next
|
4
4
|
|
5
|
+
## 4.4 (12/10/2017)
|
6
|
+
|
7
|
+
* Fix selector generator to properly handle composite key associations.
|
8
|
+
* Fix `default_selection` in `Query::Base` to accountt for models with composite identities.
|
9
|
+
* Support `many_to_many` relationships without requiring the `:through` annotations (for ORMs that
|
10
|
+
can transparently load the intermediate relationships)
|
11
|
+
|
5
12
|
## 4.3
|
6
13
|
|
7
14
|
* Added a `:through` option to `Resource.property` to specify that the property
|
@@ -96,7 +96,11 @@ module Praxis::Mapper
|
|
96
96
|
|
97
97
|
def default_select
|
98
98
|
model.identities.each_with_object({}).each do |identity, hash|
|
99
|
-
|
99
|
+
if identity.is_a? Array
|
100
|
+
identity.each { |id| hash[id] = nil }
|
101
|
+
else
|
102
|
+
hash[identity] = nil
|
103
|
+
end
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
@@ -56,19 +56,27 @@ module Praxis::Mapper
|
|
56
56
|
case association[:type]
|
57
57
|
when :many_to_one
|
58
58
|
add_track(resource, name)
|
59
|
-
|
59
|
+
Array(association[:key]).each do |akey|
|
60
|
+
add_select(resource, akey)
|
61
|
+
end
|
60
62
|
when :one_to_many
|
61
63
|
add_track(resource, name)
|
62
|
-
|
63
|
-
|
64
|
-
head, *tail = association.fetch(:through) do
|
65
|
-
raise "Association #{name} on #{resource.model} must specify the " +
|
66
|
-
"':through' option. "
|
64
|
+
Array(association[:key]).each do |akey|
|
65
|
+
add_select(associated_resource, akey)
|
67
66
|
end
|
68
|
-
|
69
|
-
|
67
|
+
when :many_to_many
|
68
|
+
# If we haven't explicitly added the "through" option in the association
|
69
|
+
# then we'll assume the underlying ORM is able to fill in the gap. We will
|
70
|
+
# simply add the fields for the associated resource below
|
71
|
+
if association.key? :through
|
72
|
+
head, *tail = association[:through]
|
73
|
+
new_fields = tail.reverse.inject(fields) do |thing, step|
|
74
|
+
{step => thing}
|
75
|
+
end
|
76
|
+
return add_association(resource, head, new_fields)
|
77
|
+
else
|
78
|
+
add_track(resource, name)
|
70
79
|
end
|
71
|
-
return add_association(resource, head, new_fields)
|
72
80
|
else
|
73
81
|
raise "no select applicable for #{association[:type].inspect}"
|
74
82
|
end
|
data/praxis-mapper.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Josep M. Blanquer","Dane Jensen"]
|
10
10
|
spec.summary = %q{A multi-datastore library designed for efficiency in loading large datasets.}
|
11
11
|
spec.email = ["blanquer@gmail.com","dane.jensen@gmail.com"]
|
12
|
-
|
12
|
+
|
13
13
|
spec.homepage = "https://github.com/rightscale/praxis-mapper"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = ">=2.1"
|
@@ -17,16 +17,16 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
spec.files = `git ls-files -z`.split("\x0")
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
-
|
20
|
+
|
21
21
|
spec.add_runtime_dependency(%q<randexp>, ["~> 0"])
|
22
22
|
spec.add_runtime_dependency(%q<sequel>, ["~> 4"])
|
23
23
|
spec.add_runtime_dependency(%q<activesupport>, [">= 3"])
|
24
24
|
|
25
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency('bundler', ['>= 1'])
|
26
26
|
spec.add_development_dependency "rake", "~> 0"
|
27
27
|
|
28
28
|
spec.add_development_dependency(%q<redcarpet>, ["< 3.0"])
|
29
|
-
spec.add_development_dependency(%q<yard
|
29
|
+
spec.add_development_dependency(%q<yard>)
|
30
30
|
spec.add_development_dependency(%q<guard>, ["~> 2"])
|
31
31
|
spec.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
32
32
|
spec.add_development_dependency(%q<rspec>, ["< 2.99"])
|
@@ -35,6 +35,6 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_development_dependency(%q<pry-stack_explorer>, ["~> 0"])
|
36
36
|
spec.add_development_dependency(%q<fuubar>, ["~> 1"])
|
37
37
|
spec.add_development_dependency('sqlite3')
|
38
|
-
spec.add_development_dependency('
|
38
|
+
spec.add_development_dependency('factory_bot')
|
39
39
|
spec.add_development_dependency('coveralls')
|
40
40
|
end
|
@@ -191,6 +191,21 @@ describe Praxis::Mapper::Query::Base do
|
|
191
191
|
|
192
192
|
end
|
193
193
|
|
194
|
+
context "#default selection fields are always included" do
|
195
|
+
it "using a non-identity field" do
|
196
|
+
subject.select :name
|
197
|
+
subject.select.should include(:id => nil, :name => nil)
|
198
|
+
end
|
199
|
+
|
200
|
+
context "for a model with a composite identity" do
|
201
|
+
let(:model) { CompositeIdModel }
|
202
|
+
it "has a default" do
|
203
|
+
subject.select :id
|
204
|
+
subject.select.should include(:id => nil, :type => nil)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
194
209
|
context "with no query body" do
|
195
210
|
subject { Praxis::Mapper::Query::Base.new(identity_map, model) }
|
196
211
|
|
@@ -75,6 +75,47 @@ describe Praxis::Mapper::SelectorGenerator do
|
|
75
75
|
generator.selectors.should eq expected_selectors
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
context 'that is many_to_many without a :through option' do
|
80
|
+
let(:properties) { {other_commented_posts: { id: true} } }
|
81
|
+
let(:resource) { UserResource }
|
82
|
+
let(:expected_selectors) do
|
83
|
+
{
|
84
|
+
PostModel => {
|
85
|
+
select: Set.new([:id]),
|
86
|
+
track: Set.new([])
|
87
|
+
},
|
88
|
+
UserModel => {
|
89
|
+
select: Set.new([]),
|
90
|
+
track: Set.new([:other_commented_posts])
|
91
|
+
}
|
92
|
+
}
|
93
|
+
end
|
94
|
+
it 'generates the correct set of selectors' do
|
95
|
+
generator.selectors.should eq expected_selectors
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
context 'that uses a composite key' do
|
101
|
+
let(:properties) { {composite_model: {id: true, type: true} } }
|
102
|
+
let(:resource) { OtherResource }
|
103
|
+
let(:expected_selectors) do
|
104
|
+
{
|
105
|
+
OtherModel => {
|
106
|
+
select: Set.new([:composite_id,:composite_type]),
|
107
|
+
track: Set.new([:composite_model])
|
108
|
+
},
|
109
|
+
CompositeIdModel => {
|
110
|
+
select: Set.new([:id,:type]),
|
111
|
+
track: Set.new
|
112
|
+
}
|
113
|
+
}
|
114
|
+
end
|
115
|
+
it 'generates the correct set of selectors' do
|
116
|
+
generator.selectors.should eq expected_selectors
|
117
|
+
end
|
118
|
+
end
|
78
119
|
end
|
79
120
|
|
80
121
|
context 'for a property that specifies a field from an association' do
|
@@ -89,6 +89,10 @@ class UserModel < Sequel::Model(:users)
|
|
89
89
|
join_table: 'comments', join_model: 'CommentModel',
|
90
90
|
through: [:comments, :post]
|
91
91
|
|
92
|
+
many_to_many :other_commented_posts, class: 'PostModel',
|
93
|
+
left_key: :author_id, right_key: :post_id,
|
94
|
+
join_table: 'comments', join_model: 'CommentModel' #Explicitly not specify the :through option
|
95
|
+
|
92
96
|
many_to_one :main_blog, class: 'BlogModel', key: :main_blog_id
|
93
97
|
end
|
94
98
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: praxis-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '4.
|
4
|
+
version: '4.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Blanquer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: randexp
|
@@ -57,16 +57,16 @@ dependencies:
|
|
57
57
|
name: bundler
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '1
|
62
|
+
version: '1'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - "
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: '1
|
69
|
+
version: '1'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rake
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,16 +99,16 @@ dependencies:
|
|
99
99
|
name: yard
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0
|
104
|
+
version: '0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: 0
|
111
|
+
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: guard
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,7 +222,7 @@ dependencies:
|
|
222
222
|
- !ruby/object:Gem::Version
|
223
223
|
version: '0'
|
224
224
|
- !ruby/object:Gem::Dependency
|
225
|
-
name:
|
225
|
+
name: factory_bot
|
226
226
|
requirement: !ruby/object:Gem::Requirement
|
227
227
|
requirements:
|
228
228
|
- - ">="
|
@@ -333,7 +333,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
333
333
|
version: '0'
|
334
334
|
requirements: []
|
335
335
|
rubyforge_project:
|
336
|
-
rubygems_version: 2.
|
336
|
+
rubygems_version: 2.6.12
|
337
337
|
signing_key:
|
338
338
|
specification_version: 4
|
339
339
|
summary: A multi-datastore library designed for efficiency in loading large datasets.
|
@@ -360,4 +360,3 @@ test_files:
|
|
360
360
|
- spec/support/spec_resources.rb
|
361
361
|
- spec/support/spec_sequel_models.rb
|
362
362
|
- spec/support/spec_sequel_resources.rb
|
363
|
-
has_rdoc:
|