plucky 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +1 -4
- data/.ruby-version +1 -0
- data/.travis.yml +6 -4
- data/Gemfile +6 -5
- data/Gemfile.lock +84 -0
- data/LICENSE +1 -1
- data/README.md +17 -75
- data/examples/query.rb +8 -7
- data/lib/plucky.rb +1 -0
- data/lib/plucky/normalizers/fields_value.rb +3 -3
- data/lib/plucky/normalizers/options_hash_value.rb +1 -1
- data/lib/plucky/normalizers/sort_value.rb +8 -6
- data/lib/plucky/options_hash.rb +3 -2
- data/lib/plucky/query.rb +53 -20
- data/lib/plucky/transformer.rb +14 -0
- data/lib/plucky/version.rb +1 -1
- data/plucky.gemspec +4 -5
- data/spec/functional/options_hash_spec.rb +4 -4
- data/spec/helper.rb +11 -4
- data/spec/plucky/criteria_hash_spec.rb +3 -3
- data/spec/plucky/normalizers/fields_value_spec.rb +5 -5
- data/spec/plucky/normalizers/options_hash_value_spec.rb +2 -2
- data/spec/plucky/normalizers/sort_value_spec.rb +20 -20
- data/spec/plucky/options_hash_spec.rb +2 -2
- data/spec/plucky/query_spec.rb +92 -35
- data/spec/plucky_spec.rb +1 -1
- metadata +24 -19
- data/script/criteria_hash.rb +0 -21
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MmNmOGM2N2RmYmRmYjllN2Q2MjRjZjQyNzAwYzhkMmZjMzZiN2JkYw==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6482980490f769425d02c3e26483021ce5d22839f733c9d46fcfb30eb762928
|
4
|
+
data.tar.gz: 0564b1238d7cb08823fedaadc7d3090349580967942750f5021dfd7b24f28cc8
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NmNjNDliOTc0OTUxNzFmNDU5YWE4N2Q0NDc1ODMyMjMxZDljOWJmNWRiN2Mw
|
11
|
-
ZmUwNTQ4NTA5ZGFlYWFmZTA5M2E5ZGFjYTA4ZjRkMDcxZGIxNDk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NjExZmVhZjMyNDE2MTk2ODY1ZmRhMTdhYzdkNTliNDk1NmNkZTY3M2NkMTIy
|
14
|
-
OTgwNjZiNDE0NDUyYzc3YzdmYWQ1MmE4NWU5MDFiZWJiNzkxYjFjYjAxNjFk
|
15
|
-
YWVlOTA0YjA0NjI1YTkwMTJkNThjZmI1NTQ0MDI1OTYwNGM0OWU=
|
6
|
+
metadata.gz: 033bfdd0c0bee0b7b25ece80fa54d4bf8f229deec703b63bdcff772a7a0d82cd8b1f3d6e83c6f773f9100bccf655cf5d5da165a58dc276ae78ac5dcb5fe7883d
|
7
|
+
data.tar.gz: b83627ae90f345dac4587654d8b74434a384473caddf3512f0c2de978a08997e2778b489b3217905ac5c2e5c2ef4ab05b29b1b5b18834719d01d952a0da77d7f
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.7.1
|
data/.travis.yml
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.8.7
|
4
|
-
- ree
|
5
|
-
- 1.9.3
|
6
3
|
- jruby-19mode
|
4
|
+
- 2.4.10
|
5
|
+
- 2.5.8
|
6
|
+
- 2.6.6
|
7
|
+
- 2.7.1
|
7
8
|
notifications:
|
8
|
-
email:
|
9
|
+
email:
|
10
|
+
- scott@railsnewbie.com
|
9
11
|
bundler_args: --without debug guard performance
|
10
12
|
services: mongodb
|
data/Gemfile
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
gemspec
|
3
3
|
|
4
|
-
gem 'bson_ext', '~> 1.5', :platform => :mri
|
5
4
|
gem 'rake'
|
6
5
|
|
7
|
-
group :performance do
|
8
|
-
gem 'perftools.rb', :require => 'perftools', :platform => :mri
|
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/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
@@ -11,12 +11,12 @@ module Plucky
|
|
11
11
|
if value.size == 1 && value.first.is_a?(Hash)
|
12
12
|
value.first
|
13
13
|
else
|
14
|
-
value.flatten
|
14
|
+
value.flatten.inject({}) {|acc, field| acc.merge(field => 1)}
|
15
15
|
end
|
16
16
|
when Symbol
|
17
|
-
|
17
|
+
{value => 1}
|
18
18
|
when String
|
19
|
-
value.split(',').
|
19
|
+
value.split(',').inject({}) { |acc, v| acc.merge(v.strip => 1) }
|
20
20
|
else
|
21
21
|
value
|
22
22
|
end
|
@@ -34,7 +34,7 @@ module Plucky
|
|
34
34
|
}
|
35
35
|
|
36
36
|
@value_normalizers = {
|
37
|
-
:
|
37
|
+
:projection => default_fields_value_normalizer,
|
38
38
|
:sort => default_sort_value_normalizer,
|
39
39
|
:limit => default_limit_value_normalizer,
|
40
40
|
:skip => default_skip_value_normalizer,
|
@@ -21,7 +21,7 @@ module Plucky
|
|
21
21
|
if value.size == 1 && value[0].is_a?(String)
|
22
22
|
normalized_sort_piece(value[0])
|
23
23
|
else
|
24
|
-
value.compact.
|
24
|
+
value.compact.inject({}) { |acc, v| acc.merge(normalized_sort_piece(v)) }
|
25
25
|
end
|
26
26
|
else
|
27
27
|
normalized_sort_piece(value)
|
@@ -32,13 +32,15 @@ module Plucky
|
|
32
32
|
def normalized_sort_piece(value)
|
33
33
|
case value
|
34
34
|
when SymbolOperator
|
35
|
-
|
35
|
+
normalized_direction(value.field, value.operator)
|
36
36
|
when String
|
37
|
-
value.split(',').
|
38
|
-
normalized_direction(*piece.split(' '))
|
37
|
+
value.split(',').inject({}) do |acc, piece|
|
38
|
+
acc.merge(normalized_direction(*piece.split(' ')))
|
39
39
|
end
|
40
40
|
when Symbol
|
41
|
-
|
41
|
+
normalized_direction(value)
|
42
|
+
when Array
|
43
|
+
Hash[*value]
|
42
44
|
else
|
43
45
|
value
|
44
46
|
end
|
@@ -48,7 +50,7 @@ module Plucky
|
|
48
50
|
def normalized_direction(field, direction=nil)
|
49
51
|
direction ||= 'ASC'
|
50
52
|
direction = direction.upcase == 'ASC' ? 1 : -1
|
51
|
-
|
53
|
+
{@key_normalizer.call(field).to_s => direction}
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
data/lib/plucky/options_hash.rb
CHANGED
@@ -55,7 +55,7 @@ module Plucky
|
|
55
55
|
|
56
56
|
# Public
|
57
57
|
def fields?
|
58
|
-
!self[:
|
58
|
+
!self[:projection].nil?
|
59
59
|
end
|
60
60
|
|
61
61
|
# Public
|
@@ -84,7 +84,8 @@ module Plucky
|
|
84
84
|
@key_normalizer ||= @options.fetch(:key_normalizer) {
|
85
85
|
Normalizers::HashKey.new({
|
86
86
|
:order => :sort,
|
87
|
-
:select => :
|
87
|
+
:select => :projection,
|
88
|
+
:fields => :projection,
|
88
89
|
:offset => :skip,
|
89
90
|
:id => :_id,
|
90
91
|
})
|
data/lib/plucky/query.rb
CHANGED
@@ -9,11 +9,12 @@ module Plucky
|
|
9
9
|
|
10
10
|
# Private
|
11
11
|
OptionKeys = Set[
|
12
|
-
:select, :offset, :order,
|
13
|
-
:fields, :skip, :limit, :sort, :hint, :snapshot, # Ruby Driver
|
12
|
+
:select, :offset, :order, :transformer, # MM
|
13
|
+
:projection, :fields, :skip, :limit, :sort, :hint, :snapshot, # Ruby Driver
|
14
14
|
:batch_size, :timeout, :max_scan, :return_key, # Ruby Driver
|
15
|
-
:
|
15
|
+
:show_disk_loc, :comment, :read, # Ruby Driver
|
16
16
|
:tag_sets, :acceptable_latency, # Ruby Driver
|
17
|
+
:max_time_ms, :no_cursor_timeout, :collation, :modifiers
|
17
18
|
]
|
18
19
|
|
19
20
|
attr_reader :criteria, :options, :collection
|
@@ -68,21 +69,19 @@ module Plucky
|
|
68
69
|
query = clone.amend(opts)
|
69
70
|
|
70
71
|
if block_given?
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
cursor.each { |doc| yield doc }
|
75
|
-
cursor.rewind!
|
72
|
+
enumerator = query.enumerator
|
73
|
+
enumerator.each do |doc|
|
74
|
+
yield doc
|
76
75
|
end
|
77
|
-
|
76
|
+
enumerator
|
78
77
|
else
|
79
|
-
query.
|
78
|
+
query.enumerator
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
82
|
def find_one(opts={})
|
84
|
-
query = clone.amend(opts)
|
85
|
-
query.
|
83
|
+
query = clone.amend(opts.merge(limit: -1))
|
84
|
+
query.enumerator.first
|
86
85
|
end
|
87
86
|
|
88
87
|
def find(*ids)
|
@@ -109,12 +108,12 @@ module Plucky
|
|
109
108
|
|
110
109
|
def remove(opts={}, driver_opts={})
|
111
110
|
query = clone.amend(opts)
|
112
|
-
query.collection.
|
111
|
+
query.collection.find(query.criteria_hash, driver_opts).delete_many
|
113
112
|
end
|
114
113
|
|
115
114
|
def count(opts={})
|
116
115
|
query = clone.amend(opts)
|
117
|
-
cursor = query.
|
116
|
+
cursor = query.view
|
118
117
|
cursor.count
|
119
118
|
end
|
120
119
|
|
@@ -123,8 +122,8 @@ module Plucky
|
|
123
122
|
query.collection.distinct(key, query.criteria_hash)
|
124
123
|
end
|
125
124
|
|
126
|
-
def
|
127
|
-
clone.tap { |query| query.options[:
|
125
|
+
def projection(*args)
|
126
|
+
clone.tap { |query| query.options[:projection] = *args }
|
128
127
|
end
|
129
128
|
|
130
129
|
def ignore(*args)
|
@@ -178,12 +177,27 @@ module Plucky
|
|
178
177
|
alias_method :exist?, :exists?
|
179
178
|
alias_method :filter, :where
|
180
179
|
alias_method :to_a, :all
|
180
|
+
alias_method :fields, :projection
|
181
181
|
end
|
182
182
|
include DSL
|
183
183
|
|
184
184
|
def update(document, driver_opts={})
|
185
185
|
query = clone
|
186
|
-
|
186
|
+
if driver_opts[:multi]
|
187
|
+
query.collection.find(query.criteria_hash).update_many(document, driver_opts)
|
188
|
+
else
|
189
|
+
query.collection.find(query.criteria_hash).update_one(document, driver_opts)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def insert(document_or_array, driver_opts={})
|
194
|
+
query = clone
|
195
|
+
|
196
|
+
if document_or_array.is_a?(Array)
|
197
|
+
query.collection.insert_many(document_or_array, driver_opts)
|
198
|
+
else
|
199
|
+
query.collection.insert_one(document_or_array, driver_opts)
|
200
|
+
end
|
187
201
|
end
|
188
202
|
|
189
203
|
def amend(opts={})
|
@@ -232,8 +246,27 @@ module Plucky
|
|
232
246
|
@options.to_hash
|
233
247
|
end
|
234
248
|
|
235
|
-
def
|
236
|
-
|
249
|
+
def view
|
250
|
+
driver_opts = options_hash.dup
|
251
|
+
driver_opts.delete :transformer
|
252
|
+
case driver_opts[:read]
|
253
|
+
when Hash
|
254
|
+
driver_opts[:read] = Mongo::ServerSelector.get(driver_opts[:read])
|
255
|
+
when Symbol
|
256
|
+
driver_opts[:read] = Mongo::ServerSelector.get(mode: driver_opts[:read])
|
257
|
+
else
|
258
|
+
raise "Unexpected read options: #{driver_opts[:read]} - expected hash or symbol"
|
259
|
+
end if driver_opts.has_key?(:read)
|
260
|
+
|
261
|
+
@collection.find(criteria_hash, driver_opts)
|
262
|
+
end
|
263
|
+
|
264
|
+
def enumerator
|
265
|
+
if transformer = options_hash[:transformer]
|
266
|
+
Transformer.new(view, transformer).to_enum
|
267
|
+
else
|
268
|
+
view.to_enum
|
269
|
+
end
|
237
270
|
end
|
238
271
|
|
239
272
|
private
|
@@ -261,7 +294,7 @@ module Plucky
|
|
261
294
|
def set_field_inclusion(fields, value)
|
262
295
|
fields_option = {}
|
263
296
|
fields.each { |field| fields_option[symbolized_key(field)] = value }
|
264
|
-
clone.tap { |query| query.options[:
|
297
|
+
clone.tap { |query| query.options[:projection] = fields_option }
|
265
298
|
end
|
266
299
|
end
|
267
300
|
end
|
data/lib/plucky/version.rb
CHANGED
data/plucky.gemspec
CHANGED
@@ -3,12 +3,11 @@ require File.expand_path('../lib/plucky/version', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'plucky'
|
6
|
-
s.homepage = 'http://github.com/
|
6
|
+
s.homepage = 'http://github.com/mongomapper/plucky'
|
7
7
|
s.summary = 'Thin layer over the ruby driver that allows you to quickly grab hold of your data (pluck it!).'
|
8
8
|
s.require_path = 'lib'
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
s.email = ['nunemaker@gmail.com']
|
9
|
+
s.authors = ['John Nunemaker', 'Chris Heald', 'Scott Taylor']
|
10
|
+
s.email = ['nunemaker@gmail.com', 'cheald@gmail.com', 'scott@railsnewbie.com']
|
12
11
|
s.version = Plucky::Version
|
13
12
|
s.platform = Gem::Platform::RUBY
|
14
13
|
|
@@ -17,5 +16,5 @@ Gem::Specification.new do |s|
|
|
17
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
17
|
s.require_paths = ["lib"]
|
19
18
|
|
20
|
-
s.add_dependency 'mongo', '~>
|
19
|
+
s.add_dependency 'mongo', '~> 2.0'
|
21
20
|
end
|
@@ -6,18 +6,18 @@ describe Plucky::OptionsHash do
|
|
6
6
|
describe "#[]=" do
|
7
7
|
it "changes order to sort" do
|
8
8
|
subject[:order] = "foo asc"
|
9
|
-
subject[:sort].should ==
|
9
|
+
subject[:sort].should == {"foo" => 1}
|
10
10
|
subject[:order].should be_nil
|
11
11
|
end
|
12
12
|
|
13
13
|
it "changes sort(id) to sort(_id)" do
|
14
14
|
subject[:sort] = "id asc"
|
15
|
-
subject[:sort].should ==
|
15
|
+
subject[:sort].should == {"_id" => 1}
|
16
16
|
end
|
17
17
|
|
18
18
|
it "changes select to fields" do
|
19
19
|
subject[:select] = [:foo]
|
20
|
-
subject[:
|
20
|
+
subject[:projection].should == {:foo => 1}
|
21
21
|
subject[:select].should be_nil
|
22
22
|
end
|
23
23
|
|
@@ -35,7 +35,7 @@ describe Plucky::OptionsHash do
|
|
35
35
|
|
36
36
|
it "does not change the sort field" do
|
37
37
|
subject[:order] = :order.asc
|
38
|
-
subject[:sort].should ==
|
38
|
+
subject[:sort].should == {"order" => 1}
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/spec/helper.rb
CHANGED
@@ -11,6 +11,10 @@ require 'fileutils'
|
|
11
11
|
require 'logger'
|
12
12
|
require 'pp'
|
13
13
|
|
14
|
+
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= '2.3'
|
15
|
+
require 'byebug'
|
16
|
+
end
|
17
|
+
|
14
18
|
log_dir = File.expand_path('../../log', __FILE__)
|
15
19
|
FileUtils.mkdir_p(log_dir)
|
16
20
|
Log = Logger.new(File.join(log_dir, 'test.log'))
|
@@ -18,8 +22,8 @@ Log = Logger.new(File.join(log_dir, 'test.log'))
|
|
18
22
|
LogBuddy.init :logger => Log
|
19
23
|
|
20
24
|
port = ENV.fetch "BOXEN_MONGODB_PORT", 27017
|
21
|
-
connection = Mongo::
|
22
|
-
DB = connection.
|
25
|
+
connection = Mongo::Client.new(["127.0.0.1:#{port.to_i}"], :logger => Log)
|
26
|
+
DB = connection.use('test').database
|
23
27
|
|
24
28
|
RSpec.configure do |config|
|
25
29
|
config.filter_run :focused => true
|
@@ -27,16 +31,19 @@ RSpec.configure do |config|
|
|
27
31
|
config.alias_example_to :xit, :pending => true
|
28
32
|
config.run_all_when_everything_filtered = true
|
29
33
|
|
34
|
+
config.expect_with(:rspec) { |c| c.syntax = :should }
|
35
|
+
config.mock_with(:rspec) { |c| c.syntax = :should }
|
36
|
+
|
30
37
|
config.before(:suite) do
|
31
38
|
DB.collections.reject { |collection|
|
32
39
|
collection.name =~ /system\./
|
33
|
-
}.
|
40
|
+
}.each { |collection| collection.indexes.drop_all}
|
34
41
|
end
|
35
42
|
|
36
43
|
config.before(:each) do
|
37
44
|
DB.collections.reject { |collection|
|
38
45
|
collection.name =~ /system\./
|
39
|
-
}.map(&:
|
46
|
+
}.map(&:drop)
|
40
47
|
end
|
41
48
|
end
|
42
49
|
|
@@ -37,9 +37,9 @@ describe Plucky::CriteriaHash do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "raises argument error if not array" do
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
lambda { described_class.new.object_ids = {} }.should raise_error(ArgumentError)
|
41
|
+
lambda { described_class.new.object_ids = nil }.should raise_error(ArgumentError)
|
42
|
+
lambda { described_class.new.object_ids = 'foo' }.should raise_error(ArgumentError)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -15,7 +15,7 @@ describe Plucky::Normalizers::FieldsValue do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "works with array" do
|
18
|
-
subject.call(['one', 'two']).should eq(
|
18
|
+
subject.call(['one', 'two']).should eq({'one' => 1, 'two' => 1})
|
19
19
|
end
|
20
20
|
|
21
21
|
# Ruby 1.9.x was sending array [{:age => 20}], instead of hash.
|
@@ -24,15 +24,15 @@ describe Plucky::Normalizers::FieldsValue do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "flattens multi-dimensional array" do
|
27
|
-
subject.call([[:one, :two]]).should eq(
|
27
|
+
subject.call([[:one, :two]]).should eq({:one => 1, :two => 1})
|
28
28
|
end
|
29
29
|
|
30
30
|
it "works with symbol" do
|
31
|
-
subject.call(:one).should eq(
|
31
|
+
subject.call(:one).should eq({:one => 1})
|
32
32
|
end
|
33
33
|
|
34
34
|
it "works with array of symbols" do
|
35
|
-
subject.call([:one, :two]).should eq(
|
35
|
+
subject.call([:one, :two]).should eq({:one => 1, :two => 1})
|
36
36
|
end
|
37
37
|
|
38
38
|
it "works with hash" do
|
@@ -40,6 +40,6 @@ describe Plucky::Normalizers::FieldsValue do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "converts comma separated list to array" do
|
43
|
-
subject.call('one, two').should eq(
|
43
|
+
subject.call('one, two').should eq({'one' => 1, 'two' => 1})
|
44
44
|
end
|
45
45
|
end
|
@@ -26,9 +26,9 @@ describe Plucky::Normalizers::OptionsHashValue do
|
|
26
26
|
}
|
27
27
|
|
28
28
|
it "raises exception if missing key normalizer" do
|
29
|
-
|
29
|
+
lambda {
|
30
30
|
described_class.new
|
31
|
-
}.
|
31
|
+
}.should raise_error(ArgumentError, "Missing required key :key_normalizer")
|
32
32
|
end
|
33
33
|
|
34
34
|
it "allows injecting a new value normalizer" do
|
@@ -13,9 +13,9 @@ describe Plucky::Normalizers::SortValue do
|
|
13
13
|
}
|
14
14
|
|
15
15
|
it "raises exception if missing key normalizer" do
|
16
|
-
|
16
|
+
lambda {
|
17
17
|
described_class.new
|
18
|
-
}.
|
18
|
+
}.should raise_error(ArgumentError, "Missing required key :key_normalizer")
|
19
19
|
end
|
20
20
|
|
21
21
|
it "defaults to nil" do
|
@@ -31,68 +31,68 @@ describe Plucky::Normalizers::SortValue do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "converts single ascending field (string)" do
|
34
|
-
subject.call('foo asc').should eq(
|
35
|
-
subject.call('foo ASC').should eq(
|
34
|
+
subject.call('foo asc').should eq({'foo' => 1})
|
35
|
+
subject.call('foo ASC').should eq({'foo' => 1})
|
36
36
|
end
|
37
37
|
|
38
38
|
it "converts single descending field (string)" do
|
39
|
-
subject.call('foo desc').should eq(
|
40
|
-
subject.call('foo DESC').should eq(
|
39
|
+
subject.call('foo desc').should eq({'foo' => -1})
|
40
|
+
subject.call('foo DESC').should eq({'foo' => -1})
|
41
41
|
end
|
42
42
|
|
43
43
|
it "converts multiple fields (string)" do
|
44
|
-
subject.call('foo desc, bar asc').should eq(
|
44
|
+
subject.call('foo desc, bar asc').should eq({'foo' => -1, 'bar' => 1})
|
45
45
|
end
|
46
46
|
|
47
47
|
it "converts multiple fields and default no direction to ascending (string)" do
|
48
|
-
subject.call('foo desc, bar, baz').should eq(
|
48
|
+
subject.call('foo desc, bar, baz').should eq({'foo' => -1, 'bar' => 1, 'baz' => 1})
|
49
49
|
end
|
50
50
|
|
51
51
|
it "converts symbol" do
|
52
|
-
subject.call(:name).should eq(
|
52
|
+
subject.call(:name).should eq({'name' => 1})
|
53
53
|
end
|
54
54
|
|
55
55
|
it "converts operator" do
|
56
|
-
subject.call(:foo.desc).should eq(
|
56
|
+
subject.call(:foo.desc).should eq({'foo' => -1})
|
57
57
|
end
|
58
58
|
|
59
59
|
it "converts array of operators" do
|
60
|
-
subject.call([:foo.desc, :bar.asc]).should eq(
|
60
|
+
subject.call([:foo.desc, :bar.asc]).should eq({'foo' => -1, 'bar' => 1})
|
61
61
|
end
|
62
62
|
|
63
63
|
it "converts array of symbols" do
|
64
|
-
subject.call([:first_name, :last_name]).should eq(
|
64
|
+
subject.call([:first_name, :last_name]).should eq({'first_name' => 1, 'last_name' => 1})
|
65
65
|
end
|
66
66
|
|
67
67
|
it "works with array and one string element" do
|
68
|
-
subject.call(['foo, bar desc']).should eq(
|
68
|
+
subject.call(['foo, bar desc']).should eq({'foo' => 1, 'bar' => -1})
|
69
69
|
end
|
70
70
|
|
71
71
|
it "works with array of single array" do
|
72
|
-
subject.call([['foo', -1]]).should eq(
|
72
|
+
subject.call([['foo', -1]]).should eq({'foo' => -1})
|
73
73
|
end
|
74
74
|
|
75
75
|
it "works with array of multiple arrays" do
|
76
|
-
subject.call([['foo', -1], ['bar', 1]]).should eq(
|
76
|
+
subject.call([['foo', -1], ['bar', 1]]).should eq({'foo' => -1, 'bar' => 1})
|
77
77
|
end
|
78
78
|
|
79
79
|
it "compacts nil values in array" do
|
80
|
-
subject.call([nil, :foo.desc]).should eq(
|
80
|
+
subject.call([nil, :foo.desc]).should eq({'foo' => -1})
|
81
81
|
end
|
82
82
|
|
83
83
|
it "converts array with mix of values" do
|
84
|
-
subject.call([:foo.desc, 'bar']).should eq(
|
84
|
+
subject.call([:foo.desc, 'bar']).should eq({'foo' => -1, 'bar' => 1})
|
85
85
|
end
|
86
86
|
|
87
87
|
it "converts keys based on key normalizer" do
|
88
|
-
subject.call([:id.asc]).should eq(
|
88
|
+
subject.call([:id.asc]).should eq({'_id' => 1})
|
89
89
|
end
|
90
90
|
|
91
91
|
it "doesn't convert keys like :sort to :order via key normalizer" do
|
92
|
-
subject.call(:order.asc).should eq(
|
92
|
+
subject.call(:order.asc).should eq({'order' => 1})
|
93
93
|
end
|
94
94
|
|
95
95
|
it "converts string with $natural correctly" do
|
96
|
-
subject.call('$natural desc').should eq(
|
96
|
+
subject.call('$natural desc').should eq({'$natural' => -1})
|
97
97
|
end
|
98
98
|
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
describe Plucky::OptionsHash do
|
4
4
|
describe "#initialize_copy" do
|
5
5
|
before do
|
6
|
-
@original = described_class.new(:
|
6
|
+
@original = described_class.new(:projection => {:name => true}, :sort => :name, :limit => 10)
|
7
7
|
@cloned = @original.clone
|
8
8
|
end
|
9
9
|
|
@@ -12,7 +12,7 @@ describe Plucky::OptionsHash do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "clones duplicable? values" do
|
15
|
-
@cloned[:
|
15
|
+
@cloned[:projection].should_not equal(@original[:projection])
|
16
16
|
@cloned[:sort].should_not equal(@original[:sort])
|
17
17
|
end
|
18
18
|
end
|
data/spec/plucky/query_spec.rb
CHANGED
@@ -2,13 +2,13 @@ require 'helper'
|
|
2
2
|
|
3
3
|
describe Plucky::Query do
|
4
4
|
before do
|
5
|
-
@chris =
|
6
|
-
@steve =
|
7
|
-
@john =
|
5
|
+
@chris = Hash['_id', 'chris', 'age', 26, 'name', 'Chris']
|
6
|
+
@steve = Hash['_id', 'steve', 'age', 29, 'name', 'Steve']
|
7
|
+
@john = Hash['_id', 'john', 'age', 28, 'name', 'John']
|
8
8
|
@collection = DB['users']
|
9
|
-
@collection.
|
10
|
-
@collection.
|
11
|
-
@collection.
|
9
|
+
@collection.insert_one(@chris)
|
10
|
+
@collection.insert_one(@steve)
|
11
|
+
@collection.insert_one(@john)
|
12
12
|
end
|
13
13
|
|
14
14
|
context "#initialize" do
|
@@ -57,7 +57,7 @@ describe Plucky::Query do
|
|
57
57
|
context "#find_each" do
|
58
58
|
it "returns a cursor" do
|
59
59
|
cursor = described_class.new(@collection).find_each
|
60
|
-
cursor.should be_instance_of(
|
60
|
+
cursor.should be_instance_of(Enumerator)
|
61
61
|
end
|
62
62
|
|
63
63
|
it "works with and normalize criteria" do
|
@@ -78,8 +78,8 @@ describe Plucky::Query do
|
|
78
78
|
|
79
79
|
it "is Ruby-like and returns a reset cursor if a block is given" do
|
80
80
|
cursor = described_class.new(@collection).find_each {}
|
81
|
-
cursor.should be_instance_of(
|
82
|
-
cursor.next.should
|
81
|
+
cursor.should be_instance_of(Enumerator)
|
82
|
+
cursor.next.should be_kind_of(Hash)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -128,7 +128,7 @@ describe Plucky::Query do
|
|
128
128
|
end
|
129
129
|
|
130
130
|
it "normalizes if using object id" do
|
131
|
-
id = @collection.
|
131
|
+
id = @collection.insert_one(:name => 'Frank').inserted_id
|
132
132
|
@query.object_ids([:_id])
|
133
133
|
doc = @query.find(id.to_s)
|
134
134
|
doc['name'].should == 'Frank'
|
@@ -203,6 +203,27 @@ describe Plucky::Query do
|
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
|
+
context "#view" do
|
207
|
+
it 'returns a mongo::collection::view' do
|
208
|
+
described_class.new(@collection).view.should be_a(Mongo::Collection::View)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'converts criteria into the view' do
|
212
|
+
view = described_class.new(@collection).where(:name => "bob").view
|
213
|
+
view.filter.should == {"name" => "bob"}
|
214
|
+
end
|
215
|
+
|
216
|
+
it "converts read option symbol to a server selector" do
|
217
|
+
view = described_class.new(@collection, :read => :secondary_preferred).view
|
218
|
+
view.read.should be_a(Mongo::ServerSelector::SecondaryPreferred)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "converts read option hash to a server selector" do
|
222
|
+
view = described_class.new(@collection, :read => {:mode =>:secondary_preferred}).view
|
223
|
+
view.read.should be_a(Mongo::ServerSelector::SecondaryPreferred)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
206
227
|
context "#all" do
|
207
228
|
it "works with no arguments" do
|
208
229
|
docs = described_class.new(@collection).all
|
@@ -279,6 +300,10 @@ describe Plucky::Query do
|
|
279
300
|
query.count(:name => 'Steve')
|
280
301
|
query[:name].should be_nil
|
281
302
|
end
|
303
|
+
|
304
|
+
it 'counts the result set and not the enumerator' do
|
305
|
+
described_class.new(@collection).limit(1).count.should == 3
|
306
|
+
end
|
282
307
|
end
|
283
308
|
|
284
309
|
context "#size" do
|
@@ -290,8 +315,8 @@ describe Plucky::Query do
|
|
290
315
|
context "#distinct" do
|
291
316
|
before do
|
292
317
|
# same age as John
|
293
|
-
@mark =
|
294
|
-
@collection.
|
318
|
+
@mark = Hash['_id', 'mark', 'age', 28, 'name', 'Mark']
|
319
|
+
@collection.insert_one(@mark)
|
295
320
|
end
|
296
321
|
|
297
322
|
it "works with just a key" do
|
@@ -489,23 +514,23 @@ describe Plucky::Query do
|
|
489
514
|
end
|
490
515
|
|
491
516
|
it "works with symbol operators" do
|
492
|
-
subject.sort(:foo.asc, :bar.desc).options[:sort].should ==
|
517
|
+
subject.sort(:foo.asc, :bar.desc).options[:sort].should == {"foo" => 1, "bar" => -1}
|
493
518
|
end
|
494
519
|
|
495
520
|
it "works with string" do
|
496
|
-
subject.sort('foo, bar desc').options[:sort].should ==
|
521
|
+
subject.sort('foo, bar desc').options[:sort].should == {"foo" => 1, "bar" => -1}
|
497
522
|
end
|
498
523
|
|
499
524
|
it "works with just a symbol" do
|
500
|
-
subject.sort(:foo).options[:sort].should ==
|
525
|
+
subject.sort(:foo).options[:sort].should == {"foo" => 1}
|
501
526
|
end
|
502
527
|
|
503
528
|
it "works with symbol descending" do
|
504
|
-
subject.sort(:foo.desc).options[:sort].should ==
|
529
|
+
subject.sort(:foo.desc).options[:sort].should == {"foo" => -1}
|
505
530
|
end
|
506
531
|
|
507
532
|
it "works with multiple symbols" do
|
508
|
-
subject.sort(:foo, :bar).options[:sort].should ==
|
533
|
+
subject.sort(:foo, :bar).options[:sort].should == {"foo" => 1, "bar" => 1}
|
509
534
|
end
|
510
535
|
|
511
536
|
it "returns new instance of query" do
|
@@ -515,8 +540,8 @@ describe Plucky::Query do
|
|
515
540
|
end
|
516
541
|
|
517
542
|
it "is aliased to order" do
|
518
|
-
subject.order(:foo).options[:sort].should ==
|
519
|
-
subject.order(:foo, :bar).options[:sort].should ==
|
543
|
+
subject.order(:foo).options[:sort].should == {"foo" => 1}
|
544
|
+
subject.order(:foo, :bar).options[:sort].should == {"foo" => 1, "bar" => 1}
|
520
545
|
end
|
521
546
|
end
|
522
547
|
|
@@ -529,27 +554,27 @@ describe Plucky::Query do
|
|
529
554
|
end
|
530
555
|
|
531
556
|
it "does not error if no sort provided" do
|
532
|
-
|
557
|
+
lambda {
|
533
558
|
subject.reverse
|
534
|
-
}.
|
559
|
+
}.should_not raise_error
|
535
560
|
end
|
536
561
|
|
537
562
|
it "reverses the sort order" do
|
538
563
|
subject.sort('foo asc, bar desc').
|
539
|
-
reverse.options[:sort].should ==
|
564
|
+
reverse.options[:sort].should == {"foo" => -1, "bar" => 1}
|
540
565
|
end
|
541
566
|
|
542
567
|
it "returns new instance of query" do
|
543
568
|
sorted_query = subject.sort(:name)
|
544
569
|
new_query = sorted_query.reverse
|
545
570
|
new_query.should_not equal(sorted_query)
|
546
|
-
sorted_query[:sort].should ==
|
571
|
+
sorted_query[:sort].should == {'name' => 1}
|
547
572
|
end
|
548
573
|
end
|
549
574
|
|
550
575
|
context "#amend" do
|
551
576
|
it "normalizes and update options" do
|
552
|
-
described_class.new(@collection).amend(:order => :age.desc).options[:sort].should ==
|
577
|
+
described_class.new(@collection).amend(:order => :age.desc).options[:sort].should == {'age' => -1}
|
553
578
|
end
|
554
579
|
|
555
580
|
it "works with simple stuff" do
|
@@ -611,7 +636,7 @@ describe Plucky::Query do
|
|
611
636
|
|
612
637
|
context "#empty?" do
|
613
638
|
it "returns true if empty" do
|
614
|
-
@collection.
|
639
|
+
@collection.drop
|
615
640
|
described_class.new(@collection).should be_empty
|
616
641
|
end
|
617
642
|
|
@@ -672,7 +697,7 @@ describe Plucky::Query do
|
|
672
697
|
it "returns a working enumerator" do
|
673
698
|
query = described_class.new(@collection)
|
674
699
|
query.each.methods.map(&:to_sym).include?(:group_by).should be(true)
|
675
|
-
query.each.next.should be_instance_of(BSON::
|
700
|
+
query.each.next.should be_instance_of(BSON::Document)
|
676
701
|
end
|
677
702
|
end
|
678
703
|
|
@@ -737,8 +762,8 @@ describe Plucky::Query do
|
|
737
762
|
end
|
738
763
|
|
739
764
|
{
|
740
|
-
:
|
741
|
-
:sort =>
|
765
|
+
:projection => {'foo' => 1},
|
766
|
+
:sort => {'foo' => 1},
|
742
767
|
:hint => '',
|
743
768
|
:skip => 0,
|
744
769
|
:limit => 0,
|
@@ -754,14 +779,14 @@ describe Plucky::Query do
|
|
754
779
|
|
755
780
|
it "knows select is an option and remove it from options" do
|
756
781
|
query = described_class.new(@collection, :select => 'foo')
|
757
|
-
query.options[:
|
782
|
+
query.options[:projection].should == {'foo' => 1}
|
758
783
|
query.criteria.keys.should_not include(:select)
|
759
784
|
query.options.keys.should_not include(:select)
|
760
785
|
end
|
761
786
|
|
762
787
|
it "knows order is an option and remove it from options" do
|
763
788
|
query = described_class.new(@collection, :order => 'foo')
|
764
|
-
query.options[:sort].should ==
|
789
|
+
query.options[:sort].should == {'foo' => 1}
|
765
790
|
query.criteria.keys.should_not include(:order)
|
766
791
|
query.options.keys.should_not include(:order)
|
767
792
|
end
|
@@ -777,15 +802,15 @@ describe Plucky::Query do
|
|
777
802
|
query = described_class.new(@collection, {
|
778
803
|
:foo => 'bar',
|
779
804
|
:baz => true,
|
780
|
-
:sort =>
|
805
|
+
:sort => {"foo" => 1},
|
781
806
|
:fields => ['foo', 'baz'],
|
782
807
|
:limit => 10,
|
783
808
|
:skip => 10,
|
784
809
|
})
|
785
810
|
query.criteria.source.should eq(:foo => 'bar', :baz => true)
|
786
811
|
query.options.source.should eq({
|
787
|
-
:sort =>
|
788
|
-
:
|
812
|
+
:sort => {"foo" => 1},
|
813
|
+
:projection => {'foo' => 1, 'baz' => 1},
|
789
814
|
:limit => 10,
|
790
815
|
:skip => 10,
|
791
816
|
})
|
@@ -815,8 +840,14 @@ describe Plucky::Query do
|
|
815
840
|
|
816
841
|
it "works" do
|
817
842
|
explain = subject.where(:age.lt => 28).explain
|
818
|
-
|
819
|
-
explain['
|
843
|
+
|
844
|
+
if explain['cursor']
|
845
|
+
explain['cursor'].should == 'BasicCursor'
|
846
|
+
explain['nscanned'].should == 3
|
847
|
+
elsif explain['executionStats']
|
848
|
+
explain['executionStats']['executionSuccess'].should == true
|
849
|
+
explain['executionStats']['totalDocsExamined'].should == 3
|
850
|
+
end
|
820
851
|
end
|
821
852
|
end
|
822
853
|
|
@@ -838,5 +869,31 @@ describe Plucky::Query do
|
|
838
869
|
result.should be_instance_of(@user_class)
|
839
870
|
end
|
840
871
|
end
|
872
|
+
|
873
|
+
it "works with block form of find_each" do
|
874
|
+
results = []
|
875
|
+
@query.find_each do |doc|
|
876
|
+
results << doc
|
877
|
+
end
|
878
|
+
results.each do |result|
|
879
|
+
result.should be_instance_of(@user_class)
|
880
|
+
end
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
884
|
+
describe "insert" do
|
885
|
+
before { @query = described_class.new(@collection) }
|
886
|
+
subject { @query }
|
887
|
+
|
888
|
+
it "should be able to insert one doc" do
|
889
|
+
subject.insert({ foo: 'bar' })
|
890
|
+
subject.count({ foo: 'bar' }).should == 1
|
891
|
+
end
|
892
|
+
|
893
|
+
it "should be able to insert multiple" do
|
894
|
+
subject.insert([{ foo: 'bar' }, { baz: 'quxx' }])
|
895
|
+
subject.count({ foo: 'bar' }).should == 1
|
896
|
+
subject.count({ baz: 'quxx' }).should == 1
|
897
|
+
end
|
841
898
|
end
|
842
899
|
end
|
data/spec/plucky_spec.rb
CHANGED
@@ -56,7 +56,7 @@ describe Plucky do
|
|
56
56
|
:where, :filter,
|
57
57
|
:sort, :order, :reverse,
|
58
58
|
:paginate, :per_page, :limit, :skip, :offset,
|
59
|
-
:fields, :ignore, :only,
|
59
|
+
:fields, :projection, :ignore, :only,
|
60
60
|
:each, :find_each, :find_one, :find,
|
61
61
|
:count, :size, :distinct,
|
62
62
|
:last, :first, :all, :to_a,
|
metadata
CHANGED
@@ -1,40 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plucky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
|
-
|
8
|
+
- Chris Heald
|
9
|
+
- Scott Taylor
|
10
|
+
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
11
|
-
date:
|
13
|
+
date: 2020-09-15 00:00:00.000000000 Z
|
12
14
|
dependencies:
|
13
15
|
- !ruby/object:Gem::Dependency
|
14
16
|
name: mongo
|
15
17
|
requirement: !ruby/object:Gem::Requirement
|
16
18
|
requirements:
|
17
|
-
- - ~>
|
19
|
+
- - "~>"
|
18
20
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
21
|
+
version: '2.0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
23
25
|
requirements:
|
24
|
-
- - ~>
|
26
|
+
- - "~>"
|
25
27
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
-
description:
|
28
|
+
version: '2.0'
|
29
|
+
description:
|
28
30
|
email:
|
29
31
|
- nunemaker@gmail.com
|
32
|
+
- cheald@gmail.com
|
33
|
+
- scott@railsnewbie.com
|
30
34
|
executables: []
|
31
35
|
extensions: []
|
32
36
|
extra_rdoc_files: []
|
33
37
|
files:
|
34
|
-
- .gitignore
|
35
|
-
- .rspec
|
36
|
-
- .
|
38
|
+
- ".gitignore"
|
39
|
+
- ".rspec"
|
40
|
+
- ".ruby-version"
|
41
|
+
- ".travis.yml"
|
37
42
|
- Gemfile
|
43
|
+
- Gemfile.lock
|
38
44
|
- Guardfile
|
39
45
|
- LICENSE
|
40
46
|
- README.md
|
@@ -59,10 +65,10 @@ files:
|
|
59
65
|
- lib/plucky/pagination/collection.rb
|
60
66
|
- lib/plucky/pagination/paginator.rb
|
61
67
|
- lib/plucky/query.rb
|
68
|
+
- lib/plucky/transformer.rb
|
62
69
|
- lib/plucky/version.rb
|
63
70
|
- plucky.gemspec
|
64
71
|
- script/bootstrap
|
65
|
-
- script/criteria_hash.rb
|
66
72
|
- script/release
|
67
73
|
- script/test
|
68
74
|
- spec/functional/options_hash_spec.rb
|
@@ -83,27 +89,26 @@ files:
|
|
83
89
|
- spec/symbol_operator_spec.rb
|
84
90
|
- spec/symbol_spec.rb
|
85
91
|
- specs.watchr
|
86
|
-
homepage: http://
|
92
|
+
homepage: http://github.com/mongomapper/plucky
|
87
93
|
licenses: []
|
88
94
|
metadata: {}
|
89
|
-
post_install_message:
|
95
|
+
post_install_message:
|
90
96
|
rdoc_options: []
|
91
97
|
require_paths:
|
92
98
|
- lib
|
93
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
|
-
- -
|
101
|
+
- - ">="
|
96
102
|
- !ruby/object:Gem::Version
|
97
103
|
version: '0'
|
98
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
105
|
requirements:
|
100
|
-
- -
|
106
|
+
- - ">="
|
101
107
|
- !ruby/object:Gem::Version
|
102
108
|
version: '0'
|
103
109
|
requirements: []
|
104
|
-
|
105
|
-
|
106
|
-
signing_key:
|
110
|
+
rubygems_version: 3.1.4
|
111
|
+
signing_key:
|
107
112
|
specification_version: 4
|
108
113
|
summary: Thin layer over the ruby driver that allows you to quickly grab hold of your
|
109
114
|
data (pluck it!).
|
data/script/criteria_hash.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'pp'
|
2
|
-
require 'pathname'
|
3
|
-
require 'benchmark'
|
4
|
-
require 'rubygems'
|
5
|
-
require 'bundler'
|
6
|
-
|
7
|
-
Bundler.require :default, :performance
|
8
|
-
|
9
|
-
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
10
|
-
lib_path = root_path.join('lib')
|
11
|
-
$:.unshift(lib_path)
|
12
|
-
require 'plucky'
|
13
|
-
|
14
|
-
criteria = Plucky::CriteriaHash.new(:foo => 'bar')
|
15
|
-
|
16
|
-
PerfTools::CpuProfiler.start("/tmp/criteria_hash") do
|
17
|
-
1_000_000.times { criteria[:foo] = 'bar' }
|
18
|
-
end
|
19
|
-
|
20
|
-
puts system "pprof.rb --gif /tmp/criteria_hash > /tmp/criteria_hash.gif"
|
21
|
-
puts system "open /tmp/criteria_hash.gif"
|