mongo_db 0.1.4 → 0.1.5

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.
@@ -11,6 +11,9 @@ module Mongo::Ext::Collection
11
11
  end
12
12
 
13
13
  def update_with_ext selector, document, opts = {}
14
+ selector = convert_underscore_to_dollar_in_selector selector
15
+ document = convert_underscore_to_dollar_in_update document
16
+
14
17
  # because :multi works only with $ operators, we need to check it
15
18
  opts = if document.keys.any?{|k| k =~ /^\$/}
16
19
  reverse_merge_defaults(opts, :safe, :multi)
@@ -22,6 +25,7 @@ module Mongo::Ext::Collection
22
25
  end
23
26
 
24
27
  def remove_with_ext selector = {}, opts = {}
28
+ selector = convert_underscore_to_dollar_in_selector selector
25
29
  remove_without_ext selector, reverse_merge_defaults(opts, :safe, :multi)
26
30
  end
27
31
 
@@ -32,9 +36,12 @@ module Mongo::Ext::Collection
32
36
  #
33
37
  # Querying
34
38
  #
35
- def first *args
36
- o = find_one *args
37
- ::Mongo::Ext::HashHelper.unmarshal o
39
+ def first spec_or_object_id = nil, opts = {}
40
+ spec_or_object_id = convert_underscore_to_dollar_in_selector spec_or_object_id if spec_or_object_id.is_a? Hash
41
+
42
+ o = find_one spec_or_object_id, opts
43
+ o = ::Mongo::Ext::HashHelper.symbolize o if Mongo.defaults[:symbolize]
44
+ o
38
45
  end
39
46
 
40
47
  def all *args, &block
@@ -48,11 +55,13 @@ module Mongo::Ext::Collection
48
55
  end
49
56
 
50
57
  def each selector = {}, opts = {}, &block
58
+ selector = convert_underscore_to_dollar_in_selector selector
59
+
51
60
  cursor = nil
52
61
  begin
53
62
  cursor = find selector, reverse_merge_defaults(opts, :batch_size)
54
63
  cursor.each do |o|
55
- o = ::Mongo::Ext::HashHelper.unmarshal o
64
+ o = ::Mongo::Ext::HashHelper.symbolize o if Mongo.defaults[:symbolize]
56
65
  block.call o
57
66
  end
58
67
  nil
@@ -62,6 +71,20 @@ module Mongo::Ext::Collection
62
71
  end
63
72
 
64
73
  protected
74
+ def convert_underscore_to_dollar_in_selector selector
75
+ if Mongo.defaults[:convert_underscore_to_dollar]
76
+ selector = ::Mongo::Ext::HashHelper.convert_underscore_to_dollar_in_selector selector
77
+ end
78
+ selector
79
+ end
80
+
81
+ def convert_underscore_to_dollar_in_update update
82
+ if Mongo.defaults[:convert_underscore_to_dollar]
83
+ update = ::Mongo::Ext::HashHelper.convert_underscore_to_dollar_in_selector update
84
+ end
85
+ update
86
+ end
87
+
65
88
  def reverse_merge_defaults opts, *keys
66
89
  h = opts.clone
67
90
  keys.each do |k|
@@ -11,21 +11,54 @@ class Mongo::Ext::HashHelper
11
11
  # Date, DateTime,
12
12
  # BSON::ObjectId
13
13
  # ].to_set
14
+
15
+ QUERY_KEYWORDS = [
16
+ :_lt, :_lte, :_gt, :_gte,
17
+ :_all, :_exists, :_mod, :_ne, :_in, :_nin,
18
+ :_nor, :_or, :_and,
19
+ :_size, :_type
20
+ ].to_set
21
+
22
+ UPDATE_KEYWORDS = [
23
+ :_inc, :_set, :_unset, :_push, :_pushAll, :_addToSet, :_pop, :_pull, :_pullAll, :_rename, :_bit
24
+ ].to_set
14
25
 
15
26
  class << self
16
27
  # symbolizing hashes
17
- def unmarshal o
18
- return o unless Mongo.defaults[:symbolize]
19
-
28
+ def symbolize o
29
+ convert o do |k, v, result|
30
+ k = k.to_sym if k.is_a? String
31
+ result[k] = v
32
+ end
33
+ end
34
+
35
+ # replaces :_lt to :$lt in query
36
+ def convert_underscore_to_dollar_in_selector selector
37
+ convert selector do |k, v, result|
38
+ k = "$#{k.to_s[1..-1]}".to_sym if QUERY_KEYWORDS.include?(k)
39
+ result[k] = v
40
+ end
41
+ end
42
+
43
+ # replaces :_set to :$set in query
44
+ def convert_underscore_to_dollar_in_update update
45
+ convert update do |k, v, result|
46
+ k = "$#{k.to_s[1..-1]}".to_sym if UPDATE_KEYWORDS.include?(k)
47
+ result[k] = v
48
+ end
49
+ end
50
+
51
+ # converts hashes (also works with nested & arrays)
52
+ def convert o, &block
20
53
  if o.is_a? Hash
21
- h = {}
54
+ result = {}
22
55
  o.each do |k, v|
23
- k = k.to_sym if k.is_a?(String)
24
- h[k] = unmarshal v
56
+ v = convert v, &block
57
+ block.call k, v, result
25
58
  end
26
- h
59
+ result
27
60
  elsif o.is_a? Array
28
- o.collect{|v| unmarshal v}
61
+ o.collect{|v| convert v, &block}
29
62
  else
30
63
  o
31
64
  end
@@ -12,6 +12,10 @@ module Mongo::Ext::Collection
12
12
  end
13
13
  alias_method :by_id!, :first_by_id!
14
14
 
15
+ def where &block
16
+ Mongo::Ext::Query.new self, &block
17
+ end
18
+
15
19
  protected
16
20
  #
17
21
  # first_by_field, all_by_field
@@ -4,10 +4,4 @@ class Mongo::NotFound < StandardError; end
4
4
 
5
5
  %w(
6
6
  collection
7
- ).each{|f| require "mongo_db/driver/more/#{f}"}
8
-
9
- Mongo.defaults.merge! \
10
- symbolize: true,
11
- batch_size: 50,
12
- multi: true,
13
- safe: true
7
+ ).each{|f| require "mongo_db/driver/more/#{f}"}
File without changes
data/lib/old/query.rb ADDED
@@ -0,0 +1,91 @@
1
+ class Mongo::Ext::Query
2
+ class Dsl < BasicObject
3
+ class Statement < ::Array
4
+ def add_to hash
5
+ operator, value = self[-2, -1]
6
+ path = self[0..-3]
7
+
8
+ current = hash
9
+ path.each_with_index do |key, index|
10
+ if index == path.size - 1
11
+ raise "dupliate key :#{key}!" if current.include? key
12
+ current[key] = value
13
+ else
14
+ raise "dupliate key :#{key}!" if current.include?(key) and !current[key].is_a?(Hash)
15
+ current[key] ||= {}
16
+ current = current[key]
17
+ end
18
+ end
19
+ nil
20
+ end
21
+ end
22
+
23
+ def initialize &block
24
+ @statements = [Statement.new]
25
+ block.call self
26
+ statements.pop if statements.last.empty?
27
+ end
28
+
29
+ {
30
+ :== => :==,
31
+ :!= => :$ne,
32
+ :< => :$lt,
33
+ :<= => :$lte,
34
+ :> => :$gt,
35
+ :>= => :$gte,
36
+ }.each do |ruby, mongo|
37
+ define_method ruby do |arg|
38
+ emit mongo
39
+ emit arg, true
40
+ end
41
+ end
42
+
43
+ def to_hash
44
+ h = {}
45
+ statements.each{|s| h.add_to h}
46
+ h
47
+ end
48
+
49
+ protected
50
+ attr_reader :statements
51
+
52
+ def emit statement = nil, terminate = false
53
+ statements.last << statement if statement
54
+ statements << Statement.new if terminate
55
+ nil
56
+ end
57
+
58
+ def method_missing m, *args, &block
59
+ raise "invalid usage, there can be only one argument (#{args})!" if args.size > 1
60
+
61
+ if args.empty?
62
+ emit m
63
+ self
64
+ else
65
+ emit m
66
+ emit args.first, true
67
+ end
68
+ end
69
+
70
+ def p *args
71
+ ::Kernel.p *args
72
+ end
73
+ end
74
+
75
+ def initialize collection, &block
76
+ @collection = collection
77
+ @hash_query = Dsl.new(&block).to_hash
78
+ end
79
+
80
+ def first
81
+ collection.first to_hash
82
+ end
83
+
84
+ def all &block
85
+ collection.first to_hash, &block
86
+ end
87
+ alias_method :each, :all
88
+
89
+ protected
90
+ attr_reader :collection, :hash_query
91
+ end
@@ -0,0 +1,77 @@
1
+ require 'driver/spec_helper'
2
+
3
+ describe "Query" do
4
+ dsl_class = Mongo::Ext::Query::Dsl
5
+ dsl_class.class_eval do
6
+ public :statements
7
+ end
8
+
9
+ it "operators" do
10
+ value = :value
11
+ dsl_class.new do |o|
12
+ o.key == value
13
+ o.key != value
14
+ o.key < value
15
+ o.key <= value
16
+ o.key > value
17
+ o.key >= value
18
+ o.key.all value
19
+ o.key.exists true
20
+ o.key.mod value
21
+ o.key.in value
22
+ o.key.nin value
23
+ o.key.size value
24
+ o.key.type value
25
+ end.statements.should == [
26
+ [:key, :==, :value],
27
+ [:key, :$ne, :value],
28
+ [:key, :$lt, :value],
29
+ [:key, :$lte, :value],
30
+ [:key, :$gt, :value],
31
+ [:key, :$gte, :value],
32
+ [:key, :all, :value],
33
+ [:key, :exists, true],
34
+ [:key, :mod, :value],
35
+ [:key, :in, :value],
36
+ [:key, :nin, :value],
37
+ [:key, :size, :value],
38
+ [:key, :type, :value]
39
+ ]
40
+ end
41
+
42
+ it ":nor, :or, :and"
43
+
44
+ describe "statement" do
45
+ def process_statement *args
46
+ s = Mongo::Ext::Query::Dsl::Statement.new
47
+ s.push *args
48
+ result = {}
49
+ s.add_to result
50
+ result
51
+ end
52
+
53
+ it "basics", focus: true do
54
+ p process_statement(:age, :$gt, 34)
55
+ end
56
+ end
57
+
58
+ # it "to_hash" do
59
+ # dsl.new do |o|
60
+ # # o.name == 'Jim'
61
+ # o.age > 34
62
+ # end.to_hash.should == {
63
+ # # name: 'Jim',
64
+ # :$gt => {age: 34}
65
+ # }
66
+ # end
67
+ #
68
+ # it do
69
+ # dsl.new do |unit|
70
+ # unit.name == 'Zeratul'
71
+ # unit.stats.life > 100
72
+ # unit.stats.attack != 0
73
+ # end.statement.should == {
74
+ # name: 1
75
+ # }
76
+ # end
77
+ end
data/readme.md CHANGED
@@ -14,6 +14,9 @@ Note: By default it also adds a little magic and alters some default values of s
14
14
  ``` ruby
15
15
  require 'mongo_db/driver'
16
16
 
17
+ # changing some defaults
18
+ Mongo.defaults.merge! symbolize: true, multi: true, safe: true
19
+
17
20
  # connection & db
18
21
  connection = Mongo::Connection.new
19
22
  db = connection.db 'default_test'
@@ -41,9 +44,19 @@ Optionall stuff:
41
44
 
42
45
  ``` ruby
43
46
  # simple finders (bang versions also availiable)
44
- db.units.by_name 'Zeratul' # => zeratul
45
- db.units.first_by_name 'Zeratul' # => zeratul
46
- db.units.all_by_name 'Zeratul' # => [zeratul]
47
+ db.units.by_name 'Zeratul' # => zeratul
48
+ db.units.first_by_name 'Zeratul' # => zeratul
49
+ db.units.all_by_name 'Zeratul' # => [zeratul]
50
+
51
+ # query sugar, use {life: {_lt: 100}} instead of {life: {:$lt => 100}}
52
+ # it will affect olny small set of keywords (:_lt, :_inc),
53
+ # other underscored keys will be intact.
54
+ Mongo.defaults.merge! convert_underscore_to_dollar: true
55
+ db.units.all life: {_lt: 100} # => [tassadar]
56
+
57
+ # it's also trivial to add support for {:life.lt => 100} notion, but
58
+ # it uses ugly '=>' hash notation instead of ':' and it differs from
59
+ # how it looks in native MongoDB JSON query.
47
60
  ```
48
61
 
49
62
  More docs - there's no need for more docs, the whole point of this extension is to be small, intuitive, 100% compatible with official driver (at least should be), and require no extra knowledge.
@@ -0,0 +1,19 @@
1
+ require 'driver/spec_helper'
2
+
3
+ describe "HashHelper" do
4
+ it "symbolize" do
5
+ Mongo::Ext::HashHelper.symbolize({
6
+ 'a' => 1,
7
+ 'b' => {
8
+ 'c' => 2,
9
+ 'd' => [{'e' => 3}]
10
+ }
11
+ }).should == {
12
+ a: 1,
13
+ b: {
14
+ c: 2,
15
+ d: [{e: 3}]
16
+ }
17
+ }
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require 'driver/spec_helper'
2
+
3
+ describe "Querying" do
4
+ with_mongo
5
+
6
+ before do
7
+ @jim = {name: 'Jim', age: 34}
8
+ @units = db.units
9
+ end
10
+
11
+ describe "dynamic finders" do
12
+ it "find, first, by" do
13
+ @units.first_by_name('Jim').should be_nil
14
+ -> {@units.first_by_name!('Jim')}.should raise_error(Mongo::NotFound)
15
+ @units.by_name('Jim').should be_nil
16
+ -> {@units.by_name!('Jim')}.should raise_error(Mongo::NotFound)
17
+ @units.first_by_name('Jim').should be_nil
18
+ -> {@units.first_by_name!('Jim')}.should raise_error(Mongo::NotFound)
19
+
20
+ @units.save @jim
21
+
22
+ @units.first_by_name('Jim').should == @jim
23
+ @units.first_by_name!('Jim').should == @jim
24
+ @units.by_name('Jim').should == @jim
25
+ @units.by_name!('Jim').should == @jim
26
+ @units.first_by_name('Jim').should == @jim
27
+ @units.first_by_name!('Jim').should == @jim
28
+ end
29
+
30
+ it "all" do
31
+ @units.all_by_name('Jim').should == []
32
+ @units.save @jim
33
+ @units.all_by_name('Jim').should == [@jim]
34
+ end
35
+
36
+ it "should allow to use bang version only with :first" do
37
+ -> {@units.all_by_name!('Jim')}.should raise_error(/can't use bang/)
38
+ end
39
+
40
+ it "by_id (special case)" do
41
+ @units.method(:by_id).should == @units.method(:first_by_id)
42
+ @units.method(:by_id!).should == @units.method(:first_by_id!)
43
+
44
+ @units.by_id('4de81858cf26bde569000009').should be_nil
45
+ -> {@units.by_id!('4de81858cf26bde569000009')}.should raise_error(Mongo::NotFound)
46
+
47
+ @units.save @jim
48
+
49
+ @units.by_id(@jim[:_id]).should == @jim
50
+ @units.by_id!(@jim[:_id]).should == @jim
51
+ end
52
+ end
53
+
54
+ it "underscore to dollar" do
55
+ @units.save @jim
56
+ @units.save name: 'Zeratul', age: 600
57
+ @units.all(age: {_lt: 100}).should == [@jim]
58
+ end
59
+ end
@@ -1,5 +1,12 @@
1
1
  require 'mongo_db/driver'
2
2
 
3
+ Mongo.defaults.merge! \
4
+ symbolize: true,
5
+ convert_underscore_to_dollar: true,
6
+ batch_size: 50,
7
+ multi: true,
8
+ safe: true
9
+
3
10
  require 'ruby_ext'
4
11
  require 'rspec_ext'
5
12
  require 'mongo_db/driver/spec'
@@ -10,6 +10,9 @@ describe "Example" do
10
10
  it "core" do
11
11
  require 'mongo_db/driver'
12
12
 
13
+ # changing some defaults
14
+ Mongo.defaults.merge! symbolize: true, multi: true, safe: true
15
+
13
16
  # connection & db
14
17
  connection = Mongo::Connection.new
15
18
  db = connection.db 'default_test'
@@ -36,10 +39,20 @@ describe "Example" do
36
39
  end
37
40
  end
38
41
 
39
- it "optional" do
42
+ it "optional" do
40
43
  # simple finders (bang versions also availiable)
41
44
  db.units.by_name 'Zeratul' # => zeratul
42
45
  db.units.first_by_name 'Zeratul' # => zeratul
43
46
  db.units.all_by_name 'Zeratul' # => [zeratul]
47
+
48
+ # query sugar, use {life: {_lt: 100}} instead of {life: {:$lt => 100}}
49
+ # it will affect olny small set of keywords (:_lt, :_inc),
50
+ # other underscored keys will be intact.
51
+ Mongo.defaults.merge! convert_underscore_to_dollar: true
52
+ db.units.all life: {_lt: 100} # => [tassadar]
53
+
54
+ # it's also trivial to add support for {:life.lt => 100} notion, but
55
+ # it uses ugly '=>' hash notation instead of ':' and it differs from
56
+ # how it looks in native MongoDB JSON query.
44
57
  end
45
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-08-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongo
16
- requirement: &2844700 !ruby/object:Gem::Requirement
16
+ requirement: &366240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '1.3'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2844700
24
+ version_requirements: *366240
25
25
  description:
26
26
  email:
27
27
  executables: []
@@ -41,11 +41,14 @@ files:
41
41
  - lib/mongo_db/gems.rb
42
42
  - lib/mongo_db/model.rb
43
43
  - lib/mongo_db/support.rb
44
+ - lib/old/advanced_finders.rb
45
+ - lib/old/query.rb
46
+ - lib/old/query_spec.rb
44
47
  - spec/driver/core/collection_spec.rb
45
48
  - spec/driver/core/crud_spec.rb
46
49
  - spec/driver/core/database_spec.rb
47
- - spec/driver/more/advanced_finders.rb
48
- - spec/driver/more/simple_finders_spec.rb
50
+ - spec/driver/core/hash_helper_spec.rb
51
+ - spec/driver/more/querying_spec.rb
49
52
  - spec/driver/spec_helper.rb
50
53
  - spec/driver_example_spec.rb
51
54
  - spec/migration/migration_spec.rb
@@ -1,51 +0,0 @@
1
- require 'driver/spec_helper'
2
-
3
- describe "Querying" do
4
- with_mongo
5
-
6
- before do
7
- @jim = {name: 'Jim'}
8
- @units = db.units
9
- end
10
-
11
- it "find, first, by" do
12
- @units.first_by_name('Jim').should be_nil
13
- -> {@units.first_by_name!('Jim')}.should raise_error(Mongo::NotFound)
14
- @units.by_name('Jim').should be_nil
15
- -> {@units.by_name!('Jim')}.should raise_error(Mongo::NotFound)
16
- @units.first_by_name('Jim').should be_nil
17
- -> {@units.first_by_name!('Jim')}.should raise_error(Mongo::NotFound)
18
-
19
- @units.save @jim
20
-
21
- @units.first_by_name('Jim').should == @jim
22
- @units.first_by_name!('Jim').should == @jim
23
- @units.by_name('Jim').should == @jim
24
- @units.by_name!('Jim').should == @jim
25
- @units.first_by_name('Jim').should == @jim
26
- @units.first_by_name!('Jim').should == @jim
27
- end
28
-
29
- it "all" do
30
- @units.all_by_name('Jim').should == []
31
- @units.save @jim
32
- @units.all_by_name('Jim').should == [@jim]
33
- end
34
-
35
- it "should allow to use bang version only with :first" do
36
- -> {@units.all_by_name!('Jim')}.should raise_error(/can't use bang/)
37
- end
38
-
39
- it "by_id (special case)" do
40
- @units.method(:by_id).should == @units.method(:first_by_id)
41
- @units.method(:by_id!).should == @units.method(:first_by_id!)
42
-
43
- @units.by_id('4de81858cf26bde569000009').should be_nil
44
- -> {@units.by_id!('4de81858cf26bde569000009')}.should raise_error(Mongo::NotFound)
45
-
46
- @units.save @jim
47
-
48
- @units.by_id(@jim[:_id]).should == @jim
49
- @units.by_id!(@jim[:_id]).should == @jim
50
- end
51
- end