plucky 0.6.3 → 0.8.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -3
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -4
- data/Gemfile +6 -5
- data/Gemfile.lock +84 -0
- data/LICENSE +1 -1
- data/README.md +17 -75
- data/Rakefile +0 -3
- data/examples/query.rb +8 -7
- data/lib/plucky.rb +1 -0
- data/lib/plucky/criteria_hash.rb +78 -62
- data/lib/plucky/extensions/symbol.rb +8 -0
- data/lib/plucky/normalizers/criteria_hash_value.rb +3 -1
- data/lib/plucky/normalizers/fields_value.rb +3 -3
- data/lib/plucky/normalizers/hash_key.rb +19 -0
- data/lib/plucky/normalizers/options_hash_value.rb +5 -7
- data/lib/plucky/normalizers/sort_value.rb +8 -6
- data/lib/plucky/options_hash.rb +9 -3
- data/lib/plucky/pagination.rb +1 -1
- data/lib/plucky/pagination/{decorator.rb → collection.rb} +10 -1
- data/lib/plucky/query.rb +56 -21
- data/lib/plucky/transformer.rb +14 -0
- data/lib/plucky/version.rb +1 -1
- data/plucky.gemspec +4 -5
- data/script/bootstrap +21 -0
- data/script/release +42 -0
- data/script/test +20 -0
- data/spec/functional/options_hash_spec.rb +41 -0
- data/spec/helper.rb +12 -4
- data/spec/plucky/criteria_hash_spec.rb +68 -4
- data/spec/plucky/normalizers/criteria_hash_value_spec.rb +1 -1
- data/spec/plucky/normalizers/fields_value_spec.rb +5 -5
- data/spec/plucky/normalizers/hash_key_spec.rb +15 -0
- data/spec/plucky/normalizers/options_hash_value_spec.rb +2 -2
- data/spec/plucky/normalizers/sort_value_spec.rb +24 -20
- data/spec/plucky/options_hash_spec.rb +2 -2
- data/spec/plucky/pagination/{decorator_spec.rb → collection_spec.rb} +8 -5
- data/spec/plucky/query_spec.rb +92 -35
- data/spec/plucky_spec.rb +5 -5
- data/spec/symbol_operator_spec.rb +18 -1
- metadata +37 -36
- data/lib/plucky/normalizers/options_hash_key.rb +0 -23
- data/script/criteria_hash.rb +0 -21
- data/spec/plucky/normalizers/options_hash_key_spec.rb +0 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6482980490f769425d02c3e26483021ce5d22839f733c9d46fcfb30eb762928
|
4
|
+
data.tar.gz: 0564b1238d7cb08823fedaadc7d3090349580967942750f5021dfd7b24f28cc8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 033bfdd0c0bee0b7b25ece80fa54d4bf8f229deec703b63bdcff772a7a0d82cd8b1f3d6e83c6f773f9100bccf655cf5d5da165a58dc276ae78ac5dcb5fe7883d
|
7
|
+
data.tar.gz: b83627ae90f345dac4587654d8b74434a384473caddf3512f0c2de978a08997e2778b489b3217905ac5c2e5c2ef4ab05b29b1b5b18834719d01d952a0da77d7f
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.7.1
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
gemspec
|
3
3
|
|
4
|
-
gem 'bson_ext', '~> 1.5'
|
5
4
|
gem 'rake'
|
6
5
|
|
7
|
-
group :performance do
|
8
|
-
gem 'perftools.rb', :require => 'perftools'
|
9
|
-
end
|
10
|
-
|
11
6
|
group(:test) do
|
12
7
|
gem 'rspec'
|
13
8
|
gem 'log_buddy'
|
9
|
+
|
10
|
+
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= '2.3'
|
11
|
+
platforms :mri do
|
12
|
+
gem 'byebug'
|
13
|
+
end
|
14
|
+
end
|
14
15
|
end
|
15
16
|
|
16
17
|
group(:guard) do
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
plucky (0.8.0)
|
5
|
+
mongo (~> 2.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
bson (4.10.0)
|
11
|
+
byebug (11.1.3)
|
12
|
+
coderay (1.1.3)
|
13
|
+
diff-lcs (1.4.4)
|
14
|
+
ffi (1.13.1)
|
15
|
+
formatador (0.2.5)
|
16
|
+
guard (2.16.2)
|
17
|
+
formatador (>= 0.2.4)
|
18
|
+
listen (>= 2.7, < 4.0)
|
19
|
+
lumberjack (>= 1.0.12, < 2.0)
|
20
|
+
nenv (~> 0.1)
|
21
|
+
notiffany (~> 0.0)
|
22
|
+
pry (>= 0.9.12)
|
23
|
+
shellany (~> 0.0)
|
24
|
+
thor (>= 0.18.1)
|
25
|
+
guard-bundler (3.0.0)
|
26
|
+
bundler (>= 2.1, < 3)
|
27
|
+
guard (~> 2.2)
|
28
|
+
guard-compat (~> 1.1)
|
29
|
+
guard-compat (1.2.1)
|
30
|
+
guard-rspec (4.7.3)
|
31
|
+
guard (~> 2.1)
|
32
|
+
guard-compat (~> 1.1)
|
33
|
+
rspec (>= 2.99.0, < 4.0)
|
34
|
+
listen (3.2.1)
|
35
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
36
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
37
|
+
log_buddy (0.7.0)
|
38
|
+
lumberjack (1.2.8)
|
39
|
+
method_source (1.0.0)
|
40
|
+
mongo (2.13.0)
|
41
|
+
bson (>= 4.8.2, < 5.0.0)
|
42
|
+
nenv (0.3.0)
|
43
|
+
notiffany (0.1.3)
|
44
|
+
nenv (~> 0.1)
|
45
|
+
shellany (~> 0.0)
|
46
|
+
pry (0.13.1)
|
47
|
+
coderay (~> 1.1)
|
48
|
+
method_source (~> 1.0)
|
49
|
+
rake (13.0.1)
|
50
|
+
rb-fsevent (0.10.4)
|
51
|
+
rb-inotify (0.10.1)
|
52
|
+
ffi (~> 1.0)
|
53
|
+
rspec (3.9.0)
|
54
|
+
rspec-core (~> 3.9.0)
|
55
|
+
rspec-expectations (~> 3.9.0)
|
56
|
+
rspec-mocks (~> 3.9.0)
|
57
|
+
rspec-core (3.9.2)
|
58
|
+
rspec-support (~> 3.9.3)
|
59
|
+
rspec-expectations (3.9.2)
|
60
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
+
rspec-support (~> 3.9.0)
|
62
|
+
rspec-mocks (3.9.1)
|
63
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
+
rspec-support (~> 3.9.0)
|
65
|
+
rspec-support (3.9.3)
|
66
|
+
shellany (0.0.1)
|
67
|
+
thor (1.0.1)
|
68
|
+
|
69
|
+
PLATFORMS
|
70
|
+
ruby
|
71
|
+
|
72
|
+
DEPENDENCIES
|
73
|
+
byebug
|
74
|
+
guard
|
75
|
+
guard-bundler
|
76
|
+
guard-rspec
|
77
|
+
log_buddy
|
78
|
+
plucky!
|
79
|
+
rake
|
80
|
+
rb-fsevent
|
81
|
+
rspec
|
82
|
+
|
83
|
+
BUNDLED WITH
|
84
|
+
2.1.4
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Plucky
|
2
2
|
|
3
|
-
|
3
|
+
A thin layer over the ruby driver that allows you to quickly grab hold of your data (pluck it!).
|
4
|
+
|
5
|
+
Used as a query selector inside of MongoMapper.
|
4
6
|
|
5
7
|
## Install
|
6
8
|
|
@@ -10,79 +12,7 @@ gem install plucky
|
|
10
12
|
|
11
13
|
## Examples
|
12
14
|
|
13
|
-
|
14
|
-
connection = Mongo::MongoClient.new
|
15
|
-
db = connection.db('test')
|
16
|
-
collection = db['users']
|
17
|
-
collection.remove # clear out the collection
|
18
|
-
|
19
|
-
collection.insert({'_id' => 'chris', 'age' => 26, 'name' => 'Chris'})
|
20
|
-
collection.insert({'_id' => 'steve', 'age' => 29, 'name' => 'Steve'})
|
21
|
-
collection.insert({'_id' => 'john', 'age' => 28, 'name' => 'John'})
|
22
|
-
|
23
|
-
# initialize query with collection
|
24
|
-
query = Plucky::Query.new(collection)
|
25
|
-
|
26
|
-
puts 'Querying'
|
27
|
-
pp query.where(:name => 'John').first
|
28
|
-
pp query.first(:name => 'John')
|
29
|
-
pp query.where(:name => 'John').all
|
30
|
-
pp query.all(:name => 'John')
|
31
|
-
|
32
|
-
puts 'Find by _id'
|
33
|
-
pp query.find('chris')
|
34
|
-
pp query.find('chris', 'steve')
|
35
|
-
pp query.find(['chris', 'steve'])
|
36
|
-
|
37
|
-
puts 'Sort'
|
38
|
-
pp query.sort(:age).all
|
39
|
-
pp query.sort(:age.asc).all # same as above
|
40
|
-
pp query.sort(:age.desc).all
|
41
|
-
pp query.sort(:age).last # steve
|
42
|
-
|
43
|
-
puts 'Counting'
|
44
|
-
pp query.count # 3
|
45
|
-
pp query.size # 3
|
46
|
-
pp query.count(:name => 'John') # 1
|
47
|
-
pp query.where(:name => 'John').count # 1
|
48
|
-
pp query.where(:name => 'John').size # 1
|
49
|
-
|
50
|
-
puts 'Distinct'
|
51
|
-
pp query.distinct(:age) # [26, 29, 28]
|
52
|
-
|
53
|
-
puts 'Select only certain fields'
|
54
|
-
pp query.fields(:age).find('chris') # {"_id"=>"chris", "age"=>26}
|
55
|
-
pp query.only(:age).find('chris') # {"_id"=>"chris", "age"=>26}
|
56
|
-
pp query.ignore(:name).find('chris') # {"_id"=>"chris", "age"=>26}
|
57
|
-
|
58
|
-
puts 'Pagination, yeah we got that'
|
59
|
-
pp query.sort(:age).paginate(:per_page => 1, :page => 2)
|
60
|
-
pp query.sort(:age).per_page(1).paginate(:page => 2)
|
61
|
-
|
62
|
-
pp query.sort(:age).limit(2).to_a # [chris, john]
|
63
|
-
pp query.sort(:age).skip(1).limit(2).to_a # [john, steve]
|
64
|
-
pp query.sort(:age).offset(1).limit(2).to_a # [john, steve]
|
65
|
-
|
66
|
-
puts 'Using a cursor'
|
67
|
-
cursor = query.find_each(:sort => :age) do |doc|
|
68
|
-
pp doc
|
69
|
-
end
|
70
|
-
pp cursor
|
71
|
-
|
72
|
-
puts 'Symbol Operators'
|
73
|
-
pp query.where(:age.gt => 28).count # 1 (steve)
|
74
|
-
pp query.where(:age.lt => 28).count # 1 (chris)
|
75
|
-
pp query.where(:age.in => [26, 28]).to_a # [chris, john]
|
76
|
-
pp query.where(:age.nin => [26, 28]).to_a # [steve]
|
77
|
-
|
78
|
-
puts 'Removing'
|
79
|
-
query.remove(:name => 'John')
|
80
|
-
pp query.count # 2
|
81
|
-
query.where(:name => 'Chris').remove
|
82
|
-
pp query.count # 1
|
83
|
-
query.remove
|
84
|
-
pp query.count # 0
|
85
|
-
```
|
15
|
+
See `examples/query.rb`.
|
86
16
|
|
87
17
|
## Help
|
88
18
|
|
@@ -98,4 +28,16 @@ https://groups.google.com/forum/#!forum/mongomapper
|
|
98
28
|
|
99
29
|
## Copyright
|
100
30
|
|
101
|
-
Copyright (c) 2010
|
31
|
+
Copyright (c) 2010-2020 MongoMapper. See LICENSE for details.
|
32
|
+
|
33
|
+
## Contributors
|
34
|
+
|
35
|
+
MongoMapper/Plucky is:
|
36
|
+
|
37
|
+
* John Nunemaker
|
38
|
+
* Chris Heald
|
39
|
+
* Scott Taylor
|
40
|
+
|
41
|
+
With contributions from:
|
42
|
+
|
43
|
+
* Frederick Cheung
|
data/Rakefile
CHANGED
data/examples/query.rb
CHANGED
@@ -7,18 +7,19 @@ lib_path = root_path.join('lib')
|
|
7
7
|
$:.unshift(lib_path)
|
8
8
|
require 'plucky'
|
9
9
|
|
10
|
-
connection = Mongo::
|
11
|
-
db = connection.
|
10
|
+
connection = Mongo::Client.new(["127.0.0.1"], :logger => Logger.new('/dev/null'))
|
11
|
+
db = connection.use('test').database
|
12
12
|
collection = db['users']
|
13
|
-
collection.remove # clear out the collection
|
14
|
-
|
15
|
-
collection.insert({'_id' => 'chris', 'age' => 26, 'name' => 'Chris'})
|
16
|
-
collection.insert({'_id' => 'steve', 'age' => 29, 'name' => 'Steve'})
|
17
|
-
collection.insert({'_id' => 'john', 'age' => 28, 'name' => 'John'})
|
18
13
|
|
19
14
|
# initialize query with collection
|
20
15
|
query = Plucky::Query.new(collection)
|
21
16
|
|
17
|
+
query.remove # clear out the collection
|
18
|
+
|
19
|
+
query.insert({'_id' => 'chris', 'age' => 26, 'name' => 'Chris'})
|
20
|
+
query.insert({'_id' => 'steve', 'age' => 29, 'name' => 'Steve'})
|
21
|
+
query.insert({'_id' => 'john', 'age' => 28, 'name' => 'John'})
|
22
|
+
|
22
23
|
puts 'Querying'
|
23
24
|
pp query.where(:name => 'John').first
|
24
25
|
pp query.first(:name => 'John')
|
data/lib/plucky.rb
CHANGED
data/lib/plucky/criteria_hash.rb
CHANGED
@@ -77,58 +77,9 @@ module Plucky
|
|
77
77
|
@source
|
78
78
|
end
|
79
79
|
|
80
|
-
# Public
|
80
|
+
# Public
|
81
81
|
def merge(other)
|
82
|
-
|
83
|
-
other.source.each_key do |key|
|
84
|
-
value, other_value = target[key], other[key]
|
85
|
-
target[key] =
|
86
|
-
if target.key?(key)
|
87
|
-
value_is_hash = value.is_a?(Hash)
|
88
|
-
other_is_hash = other_value.is_a?(Hash)
|
89
|
-
|
90
|
-
if value_is_hash && other_is_hash
|
91
|
-
value.update(other_value) do |key, old_value, new_value|
|
92
|
-
if old_value.is_a?(Hash) && new_value.is_a?(Hash)
|
93
|
-
self.class.new(old_value).merge(self.class.new(new_value)).to_hash
|
94
|
-
else
|
95
|
-
merge_values_into_array(old_value, new_value)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
elsif value_is_hash && !other_is_hash
|
99
|
-
if modifier_key = value.keys.detect { |k| Plucky.modifier?(k) }
|
100
|
-
current_value = value[modifier_key]
|
101
|
-
value[modifier_key] = current_value.concat(array(other_value)).uniq
|
102
|
-
else
|
103
|
-
# kaboom! Array(value).concat(Array(other_value)).uniq
|
104
|
-
end
|
105
|
-
elsif other_is_hash && !value_is_hash
|
106
|
-
if modifier_key = other_value.keys.detect { |k| Plucky.modifier?(k) }
|
107
|
-
current_value = other_value[modifier_key]
|
108
|
-
other_value[modifier_key] = current_value.concat(array(value)).uniq
|
109
|
-
else
|
110
|
-
# kaboom! Array(value).concat(Array(other_value)).uniq
|
111
|
-
end
|
112
|
-
else
|
113
|
-
merge_values_into_array(value, other_value)
|
114
|
-
end
|
115
|
-
else
|
116
|
-
other_value
|
117
|
-
end
|
118
|
-
end
|
119
|
-
self.class.new(target)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Private
|
123
|
-
def merge_values_into_array(value, other_value)
|
124
|
-
array(value).concat(array(other_value)).uniq
|
125
|
-
end
|
126
|
-
|
127
|
-
# Private: Array(BSON::ObjectId) returns the byte array or what not instead
|
128
|
-
# of the object id. This makes sure it is an array of object ids, not the
|
129
|
-
# guts of the object id.
|
130
|
-
def array(value)
|
131
|
-
value.is_a?(BSON::ObjectId) ? [value] : Array(value)
|
82
|
+
self.class.new hash_merge(@source, other.source)
|
132
83
|
end
|
133
84
|
|
134
85
|
# Public
|
@@ -139,17 +90,6 @@ module Plucky
|
|
139
90
|
self
|
140
91
|
end
|
141
92
|
|
142
|
-
# Private
|
143
|
-
def object_ids
|
144
|
-
@options[:object_ids] ||= []
|
145
|
-
end
|
146
|
-
|
147
|
-
# Private
|
148
|
-
def object_ids=(value)
|
149
|
-
raise ArgumentError unless value.is_a?(Array)
|
150
|
-
@options[:object_ids] = value.flatten
|
151
|
-
end
|
152
|
-
|
153
93
|
# Public: The definition of simple is querying by only _id or _id and _type.
|
154
94
|
# If this is the case, you can use IdentityMap in library to not perform
|
155
95
|
# query and instead just return from map.
|
@@ -165,6 +105,82 @@ module Plucky
|
|
165
105
|
object_ids.include?(key.to_sym)
|
166
106
|
end
|
167
107
|
|
108
|
+
# Private
|
109
|
+
def object_ids
|
110
|
+
@options[:object_ids] ||= []
|
111
|
+
end
|
112
|
+
|
113
|
+
# Private
|
114
|
+
def object_ids=(value)
|
115
|
+
raise ArgumentError unless value.is_a?(Array)
|
116
|
+
@options[:object_ids] = value.flatten
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
# Private
|
122
|
+
def hash_merge(oldhash, newhash)
|
123
|
+
merge_compound_or_clauses!(oldhash, newhash)
|
124
|
+
oldhash.merge(newhash) do |key, oldval, newval|
|
125
|
+
old_is_hash = oldval.instance_of? Hash
|
126
|
+
new_is_hash = newval.instance_of? Hash
|
127
|
+
|
128
|
+
if oldval == newval
|
129
|
+
oldval
|
130
|
+
elsif old_is_hash && new_is_hash
|
131
|
+
hash_merge(oldval, newval)
|
132
|
+
elsif old_is_hash
|
133
|
+
modifier_merge(oldval, newval)
|
134
|
+
elsif new_is_hash
|
135
|
+
modifier_merge(newval, oldval)
|
136
|
+
else
|
137
|
+
merge_values_into_array(oldval, newval)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def merge_compound_or_clauses!(oldhash, newhash)
|
143
|
+
old_or = oldhash[:$or]
|
144
|
+
new_or = newhash[:$or]
|
145
|
+
if old_or && new_or
|
146
|
+
oldhash[:$and] ||= []
|
147
|
+
oldhash[:$and] << {:$or => oldhash.delete(:$or)}
|
148
|
+
oldhash[:$and] << {:$or => newhash.delete(:$or)}
|
149
|
+
elsif new_or && oldhash[:$and]
|
150
|
+
if oldhash[:$and].any? {|v| v.key? :$or }
|
151
|
+
oldhash[:$and] << {:$or => newhash.delete(:$or)}
|
152
|
+
end
|
153
|
+
elsif old_or && newhash[:$and]
|
154
|
+
if newhash[:$and].any? {|v| v.key? :$or }
|
155
|
+
newhash[:$and] << {:$or => oldhash.delete(:$or)}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Private
|
161
|
+
def modifier_merge(hash, value)
|
162
|
+
if modifier_key = hash.keys.detect { |k| Plucky.modifier?(k) }
|
163
|
+
hash[modifier_key].concat( array(value) ).uniq
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Private
|
168
|
+
def merge_values_into_array(value, other_value)
|
169
|
+
array(value).concat(array(other_value)).uniq
|
170
|
+
end
|
171
|
+
|
172
|
+
# Private: Array(BSON::ObjectId) returns the byte array or what not instead
|
173
|
+
# of the object id. This makes sure it is an array of object ids, not the
|
174
|
+
# guts of the object id.
|
175
|
+
def array(value)
|
176
|
+
case value
|
177
|
+
when nil, BSON::ObjectId
|
178
|
+
[value]
|
179
|
+
else
|
180
|
+
Array(value)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
168
184
|
# Private
|
169
185
|
def normalized_key(key)
|
170
186
|
key_normalizer.call(key)
|