mongous 0.1.4 → 0.2.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +156 -37
  3. data/README.ja.adoc +155 -36
  4. data/lib/mongous/document.rb +66 -31
  5. data/lib/mongous/extention.rb +59 -46
  6. data/lib/mongous/filter.rb +82 -60
  7. data/lib/mongous/version.rb +1 -1
  8. data/sample/connect_auto_2.rb +2 -1
  9. data/sample/connect_default_2.rb +2 -1
  10. data/sample/connect_environ_2.rb +2 -1
  11. data/sample/connect_loadfile_2.rb +2 -1
  12. data/sample/declare_compact_1.rb +4 -3
  13. data/sample/declare_label_1.rb +5 -3
  14. data/sample/declare_ndex_1.rb +5 -3
  15. data/sample/declare_ndex_2.rb +5 -3
  16. data/sample/declare_strict_1.rb +14 -10
  17. data/sample/declare_strict_2.rb +5 -3
  18. data/sample/{multi_docs_1.rb → multi_collection_1.rb} +0 -0
  19. data/sample/multi_collection_2.rb +63 -0
  20. data/sample/query_basic_1.rb +3 -1
  21. data/sample/query_basic_2.rb +5 -3
  22. data/sample/query_basic_3.rb +2 -3
  23. data/sample/query_basic_4.rb +3 -4
  24. data/sample/query_basic_5.rb +2 -3
  25. data/sample/query_detail_1.rb +1 -0
  26. data/sample/query_detail_2.rb +1 -0
  27. data/sample/query_detail_3.rb +5 -3
  28. data/sample/{query_basic_6.rb → query_filter_1.rb} +8 -5
  29. data/sample/query_filter_2.rb +50 -0
  30. data/sample/query_find_1.rb +31 -0
  31. data/sample/query_projection_1.rb +5 -8
  32. data/sample/query_skip_limit_1.rb +47 -0
  33. data/sample/query_skip_limit_2.rb +49 -0
  34. data/sample/query_sort_order_1.rb +46 -0
  35. data/sample/save_basic_1.rb +1 -2
  36. data/sample/save_basic_2.rb +1 -2
  37. data/sample/save_basic_3.rb +1 -2
  38. data/sample/save_detail_1.rb +7 -4
  39. data/sample/save_detail_2.rb +7 -4
  40. data/sample/save_detail_3.rb +10 -7
  41. data/sample/save_verify_1.rb +7 -4
  42. data/sample/save_verify_3.rb +1 -1
  43. data/sample/save_verify_5.rb +3 -3
  44. data/sample/save_verify_6.rb +3 -3
  45. data/sample/save_verify_7.rb +23 -0
  46. data/sample/update_basic_1.rb +13 -0
  47. data/sample/zap_basic_2.rb +2 -2
  48. metadata +12 -11
  49. data/sample/multi_docs_2.rb +0 -58
  50. data/sample/query_limit_1.rb +0 -44
  51. data/sample/query_order_1.rb +0 -49
  52. data/sample/query_raw_1.rb +0 -33
  53. data/sample/template_article.rb +0 -5
  54. data/sample/template_person.rb +0 -12
  55. data/sample/zap_basic_3.rb +0 -11
@@ -26,33 +26,66 @@ module Mongous
26
26
  end
27
27
  end
28
28
 
29
- def having?( value )
30
- case value
29
+ def having?( label )
30
+ case label
31
31
  when NilClass
32
32
  false
33
33
  when String
34
- !value.strip.empty?
34
+ !label.strip.empty?
35
35
  else
36
36
  true
37
37
  end
38
38
  end
39
39
 
40
+ def getvalue_or_callproc( value_or_proc )
41
+ case value_or_proc
42
+ when Proc
43
+ value_or_proc.call
44
+ else
45
+ value_or_proc
46
+ end
47
+ end
48
+
40
49
  def save
50
+ if @doc["_id"].nil? || self.class.collection.find( { "_id"=> @doc["_id"] } ).count == 0
51
+ savemode = :create
52
+ else
53
+ savemode = :update
54
+ end
55
+
41
56
  self.class.fields.each do |label, field|
42
- _must = field[:_args].include?(:must)
57
+ default_value = getvalue_or_callproc( field[:default] )
58
+ _must = field[:_attrs].include?(:must)
43
59
  if @doc.has_key?(label)
44
- if _must && !having?( @doc[label] )
45
- raise Mongous::Error, "must and not having field. : #{ label }"
60
+ if !having?( @doc[label] )
61
+ if default_value
62
+ self[label] = default_value
63
+ elsif _must
64
+ raise Mongous::Error, "must but unassigned field. : #{ label }"
65
+ elsif self.class.symbols[:strict]
66
+ self[label] = nil
67
+ end
46
68
  end
47
69
  else
48
- if block = field[:_block]
49
- self[label] = block.call
70
+ if default_value
71
+ self[label] = default_value
50
72
  elsif _must
51
- raise Mongous::Error, "must and unassigned field. : #{ label }"
73
+ raise Mongous::Error, "must but unassigned field. : #{ label }"
52
74
  elsif self.class.symbols[:strict]
53
75
  self[label] = nil
54
76
  end
55
77
  end
78
+
79
+ case savemode
80
+ when :create
81
+ if create_value = getvalue_or_callproc( field[:create] )
82
+ self[label] = create_value
83
+ end
84
+ when :update
85
+ if update_value = getvalue_or_callproc( field[:update] )
86
+ self[label] = update_value
87
+ end
88
+ end
56
89
  end
57
90
 
58
91
  self.class.blocks.each do |call_from, block|
@@ -61,15 +94,13 @@ module Mongous
61
94
  end
62
95
  end
63
96
 
64
- if @doc["_id"]
65
- _filter = { "_id"=> @doc["_id"] }
66
- if self.class.collection.find( _filter ).first
67
- self.class.collection.update_one( _filter, { '$set' => @doc } )
68
- return self
69
- end
97
+ case savemode
98
+ when :create
99
+ self.class.collection.insert_one( @doc )
100
+ when :update
101
+ self.class.collection.update_one( { "_id"=> @doc["_id"] }, { '$set' => @doc } )
70
102
  end
71
103
 
72
- self.class.collection.insert_one( @doc )
73
104
  self
74
105
  end
75
106
 
@@ -77,7 +108,7 @@ module Mongous
77
108
  label = label.to_s
78
109
 
79
110
  if self.class.symbols[:strict]
80
- if !self.class.fields.keys.include?(label)
111
+ if !(self.class.fields.keys.include?(label) || (label == "_id"))
81
112
  raise Mongous::Error, "undefined field. : #{ label }"
82
113
  end
83
114
  end
@@ -108,18 +139,18 @@ module Mongous
108
139
  return @doc[label] = value if field.nil?
109
140
 
110
141
  types = []
111
- if args = field[:_args] || []
112
- args.each do |arg|
113
- if arg.class == Class
114
- types << arg
115
- args -= [arg]
142
+ if attrs = field[:_attrs] || []
143
+ attrs.each do |attr|
144
+ if attr.class == Class
145
+ types << attr
146
+ attrs -= [attr]
116
147
  break
117
148
  end
118
149
  end
119
150
  end
120
151
 
121
152
  if !types.empty?
122
- if !(args & [:must, :not_null]).empty?
153
+ if !(attrs & [:must, :not_null]).empty?
123
154
  if !types.include?( value.class )
124
155
  raise Mongous::Error, "invalid type. : #{ label } : #{ value.class }"
125
156
  end
@@ -129,7 +160,7 @@ module Mongous
129
160
  end
130
161
  end
131
162
  else
132
- if !(args & [:must, :not_null]).empty?
163
+ if !(attrs & [:must, :not_null]).empty?
133
164
  if [NilClass].include?( value.class )
134
165
  raise Mongous::Error, "invalid type. : #{ label } : #{ value.class }"
135
166
  end
@@ -138,19 +169,23 @@ module Mongous
138
169
 
139
170
  @doc[label] = value
140
171
 
141
- args.each do |arg|
142
- case arg
172
+ attrs.each do |attr|
173
+ case attr
143
174
  when Proc
144
- if !self.instance_eval( &arg )
175
+ if !self.instance_eval( &attr )
145
176
  raise Mongous::Error, "violation detected. : #{ label } : #{ value }"
146
177
  end
147
178
  when Array
148
- if !arg.include?( value )
149
- raise Mongous::Error, "not include. : #{ label } :#{ value }"
179
+ if !attr.include?( value )
180
+ raise Mongous::Error, "not include. : #{ label } : #{ value }"
150
181
  end
151
182
  when Range
152
- if !arg.cover?( value )
153
- raise Mongous::Error, "out of range. : #{ label } :#{ value }"
183
+ if !attr.cover?( value )
184
+ raise Mongous::Error, "out of range. : #{ label } : #{ value }"
185
+ end
186
+ when Regexp
187
+ if !attr.match( value )
188
+ raise Mongous::Error, "unmatch regexp. : #{ label } : #{ value }"
154
189
  end
155
190
  end
156
191
  end
@@ -10,7 +10,7 @@ module Mongous
10
10
  end
11
11
  end
12
12
 
13
- def set_client( _client )
13
+ def client=( _client )
14
14
  m = /(.*?):(\d+)/.match( caller()[0] )
15
15
  call_from = [ m[1], m[2] ].join(":")
16
16
  if !_client.is_a?( Mongo::Client )
@@ -28,7 +28,7 @@ module Mongous
28
28
  end
29
29
  end
30
30
 
31
- def set_collection_name( _collection_name )
31
+ def collection_name=( _collection_name )
32
32
  self.class_variable_set( :@@collection_name, _collection_name )
33
33
  if self.class_variable_defined?( :@@collection )
34
34
  self.remove_class_variable( :@@collection )
@@ -60,34 +60,34 @@ module Mongous
60
60
  end
61
61
 
62
62
  def fields
63
- if self.class_variable_defined?( :@@fields )
64
- self.class_variable_get( :@@fields )
65
- else
66
- self.class_variable_set( :@@fields, {} )
67
- end
63
+ self_class_variable( :@@fields, {} )
68
64
  end
69
65
 
70
66
  def symbols
71
- if self.class_variable_defined?( :@@symbols )
72
- self.class_variable_get( :@@symbols )
73
- else
74
- self.class_variable_set( :@@symbols, {} )
75
- end
67
+ self_class_variable( :@@symbols, {} )
76
68
  end
77
69
 
78
70
  def blocks
79
- if self.class_variable_defined?( :@@blocks )
80
- self.class_variable_get( :@@blocks )
81
- else
82
- self.class_variable_set( :@@blocks, {} )
83
- end
71
+ self_class_variable( :@@blocks, {} )
84
72
  end
85
73
 
86
74
  def indexes
87
- if self.class_variable_defined?( :@@indexes )
88
- self.class_variable_get( :@@indexes )
75
+ self_class_variable( :@@indexes, [] )
76
+ end
77
+
78
+ def filters
79
+ self_class_variable( :@@filters, {} )
80
+ end
81
+
82
+ def defaults
83
+ self_class_variable( :@@defaults, {} )
84
+ end
85
+
86
+ def self_class_variable( symbol, default )
87
+ if self.class_variable_defined?( symbol )
88
+ self.class_variable_get( symbol )
89
89
  else
90
- self.class_variable_set( :@@indexes, [] )
90
+ self.class_variable_set( symbol, default )
91
91
  end
92
92
  end
93
93
 
@@ -95,53 +95,66 @@ module Mongous
95
95
  self.new( **doc ).save
96
96
  end
97
97
 
98
- def field( label, *args, **opts, &block )
98
+ def find( conditios = {}, options = {} )
99
+ self.collection.find( conditios, options )
100
+ end
101
+
102
+ def field( symbol, *attrs, **items )
99
103
  m = /(.*?):(\d+)/.match( caller()[0] )
100
104
  call_from = [ m[1], m[2] ].join(":")
101
105
 
102
- args.each do |arg|
103
- if klass = arg.class
104
- if ![Class, Range, Array, Proc, Symbol].include?(klass)
105
- raise Mongous::Error, "field error. : #{arg} on #{ label } at #{ call_from }"
106
+ attrs.each do |attr|
107
+ if klass = attr.class
108
+ if ![Class, Range, Array, Regexp, Proc, Symbol].include?(klass)
109
+ raise Mongous::Error, "'field' arguments error. : #{ attr } on #{ symbol } at #{ call_from }"
106
110
  end
107
111
  end
108
112
  end
109
113
 
110
- opts.each do |key, value|
111
- case key
112
- when :default
113
- case value
114
- when Proc, String, Numeric
115
- else
116
- raise Mongous::Error, "field error. : #{key} on #{ label } at #{ call_from }"
117
- end
118
- end
114
+ items.each do |key, value|
115
+ next if [:default, :create, :update].include?(key) && [Proc, String, Numeric].include?(value.class)
116
+
117
+ raise Mongous::Error, "'field' options error. : #{key} on #{ symbol } at #{ call_from }"
119
118
  end
120
119
 
121
- opts[:_args] = args
122
- opts[:_block] = block
123
- fields[label.to_s] = opts
120
+ items[:_attrs] = attrs
121
+ fields[symbol.to_s] = items
124
122
  end
125
123
 
126
- def verify( *syms, &block )
127
- if !syms.empty?
128
- syms.each do |sym|
129
- symbols[sym] = true
124
+ def verify( *directives, &block )
125
+ if !directives.empty?
126
+ directives.each do |directive|
127
+ symbols[directive] = true
130
128
  end
131
129
  elsif block
132
130
  m = /(.*?):(\d+)/.match( caller()[0] )
133
131
  call_from = [ m[1], m[2] ].join(":")
134
132
  blocks[call_from] = block
133
+ else
134
+ raise Mongous::Error, "'verify' arguments error. need directives or block."
135
135
  end
136
136
  end
137
137
 
138
- def index( *syms, **opts )
139
- opts[:background] = true unless opts.has_key?(:background)
138
+ def index( *symbols, **options )
139
+ options[:background] = true unless options.has_key?(:background)
140
140
  keys = {}
141
- syms.each do |sym|
142
- keys[sym] = 1
141
+ symbols.each do |symbol|
142
+ keys[symbol] = 1
143
+ end
144
+ indexes.push << [keys, options]
145
+ end
146
+
147
+ def filter( symbol, filter_or_condition )
148
+ case filter_or_condition
149
+ when Filter
150
+ filters[symbol] = filter_or_condition.to_condition
151
+ when Hash
152
+ filters[symbol] = filter_or_condition
153
+ else
154
+ m = /(.*?):(\d+)/.match( caller()[0] )
155
+ call_from = [ m[1], m[2] ].join(":")
156
+ raise Mongous::Error, "'filter' arguments error. : #{symbol}, #{filter_or_condition} at #{ call_from }"
143
157
  end
144
- indexes.push << [keys, opts]
145
158
  end
146
159
  end
147
160
  end
@@ -1,6 +1,11 @@
1
1
 
2
2
  module Mongous
3
3
  module Extention
4
+ def count
5
+ # self.collection.find.count
6
+ self.collection.estimated_document_count
7
+ end
8
+
4
9
  def first
5
10
  doc = self.collection.find.first
6
11
  self.new( **doc ) if doc
@@ -20,55 +25,53 @@ module Mongous
20
25
  self.collection.delete_many({})
21
26
  end
22
27
 
23
- def filter( **conditions )
24
- Filter.new( self ).filter( conditions )
28
+ def where( filter = nil, **conditions )
29
+ condition = normalize( filter, conditions )
30
+ Filter.new( self ).where( condition )
25
31
  end
26
32
 
27
33
  def not( filter = nil, **conditions )
28
34
  raise Mongous::Error, "Unset args for #{self}.not." if filter.nil? && conditions.empty?
29
35
 
30
- filter ||= conditions
31
- condition = case filter
32
- when Hash
33
- filter
34
- when Filter
35
- filter.to_condition
36
- else
37
- raise Mongous::Error, "Invalid args for #{self}.not. : #{filter}"
38
- end
39
- Filter.new( self ).filter({"$nor" => [condition]})
36
+ condition = normalize( filter, conditions )
37
+ Filter.new( self ).where({"$nor" => [condition]})
40
38
  end
41
39
 
42
40
  def and( *filters )
43
41
  raise Mongous::Error, "Unset args for #{self}.and." if filters.empty?
44
42
 
45
43
  conditions = filters.map do |filter|
46
- case filter
47
- when Hash
48
- filter
49
- when Filter
50
- filter.to_condition
51
- else
52
- raise Mongous::Error, "Invalid args for #{self}.and. : #{filter}"
53
- end
44
+ normalize( filter, {} )
54
45
  end
55
- Filter.new( self ).filter({"$and" => conditions})
46
+ Filter.new( self ).where({"$and" => conditions})
56
47
  end
57
48
 
58
49
  def or( *filters )
59
50
  raise Mongous::Error, "Unset args for #{self}.or." if filters.empty?
60
51
 
61
52
  conditions = filters.map do |filter|
62
- case filter
63
- when Hash
64
- filter
53
+ normalize( filter, {} )
54
+ end
55
+ Filter.new( self ).where({"$or" => conditions})
56
+ end
57
+
58
+ def normalize( filter, conditions )
59
+ condition = case filter
60
+ when Filter
61
+ filter.to_condition
62
+ when Symbol
63
+ case _filter = filters[filter]
65
64
  when Filter
66
- filter.to_condition
67
- else
68
- raise Mongous::Error, "Invalid args for #{self}.or. : #{filter}"
65
+ _filter.to_condition
66
+ when Hash
67
+ _filter
69
68
  end
69
+ when NilClass
70
+ Filter.new( self ).where( **conditions ).to_condition
71
+ else
72
+ caller_method = /`(.*?)'/.match( caller()[0] )[1]
73
+ raise Mongous::Error, "Invalid args for #{self}.#{ caller_method }. : #{filter}, #{conditions}"
70
74
  end
71
- Filter.new( self ).filter({"$or" => conditions})
72
75
  end
73
76
  end
74
77
  end
@@ -81,7 +84,7 @@ module Mongous
81
84
  @option = {}
82
85
  end
83
86
 
84
- def filter( conditions )
87
+ def where( conditions )
85
88
  hash = {}
86
89
  conditions.each do |key, item|
87
90
  case key
@@ -126,56 +129,54 @@ module Mongous
126
129
  end
127
130
 
128
131
  def option( _option )
129
- self.option!( _option )
130
- self.dup
131
- end
132
-
133
- def option!( _option )
134
132
  @option.merge!( _option )
133
+ self.dup
135
134
  end
136
135
 
137
136
  def projection( _projection )
138
- self.projection!( _projection )
137
+ @projection = _projection
139
138
  self.dup
140
139
  end
141
140
  alias :select :projection
142
141
 
143
- def projection!( _projection )
144
- @projection = _projection
145
- end
146
-
147
142
  def sort( _sort )
148
- self.sort!( _sort )
143
+ @sort = _sort
149
144
  self.dup
150
145
  end
151
146
  alias :order :sort
152
147
 
153
- def sort!( _sort )
154
- @sort = _sort
155
- end
148
+ def []( nth_or_range, len = nil )
149
+ case nth_or_range
150
+ when Integer
151
+ @skip = nth_or_range
156
152
 
157
- def skip( _skip )
158
- self.skip!( _skip )
159
- self.dup
160
- end
161
- alias :offset :skip
153
+ if len
154
+ raise Mongous::Error, "invalid len. : #{ len }" if !len.is_a? Integer || len <= 0
155
+ @limit = len
156
+ end
162
157
 
163
- def skip!( _skip )
164
- @skip = _skip
165
- end
158
+ when Range
159
+ from = nth_or_range.begin
160
+ raise Mongous::Error, "invalid range. : #{ nth_or_range }" unless from.is_a? Integer
166
161
 
167
- def limit( _limit )
168
- self.limit!( _limit )
169
- self.dup
170
- end
162
+ to = nth_or_range.end
163
+ raise Mongous::Error, "invalid range. : #{ nth_or_range }" unless to.is_a? Integer
164
+
165
+ to -= 1 if nth_or_range.exclude_end?
166
+ @skip = from
167
+ @limit = to - from + 1
168
+
169
+ else
170
+ raise Mongous::Error, "invalid class. : #{ nth_or_range }"
171
+
172
+ end
171
173
 
172
- def limit!( _limit )
173
- @limit = _limit
174
+ self.dup
174
175
  end
175
176
 
176
177
  def do_find
177
178
  _filter = @filter
178
- _option = @option
179
+ _option = @option.dup
179
180
  _option[:projection] = @projection if @projection
180
181
  found = @klass.collection.find( _filter, _option )
181
182
  found = found.sort( @sort ) if @sort
@@ -184,6 +185,28 @@ module Mongous
184
185
  found
185
186
  end
186
187
 
188
+ def count
189
+ found = @klass.collection.find( @filter )
190
+ found = found.skip( @skip ) if @skip
191
+ found = found.limit( @limit ) if @limit
192
+ _count = found.count_documents
193
+ if @skip
194
+ if @skip > _count
195
+ 0
196
+ elsif @limit
197
+ [_count - @skip, @limit].min
198
+ else
199
+ _count - @skip
200
+ end
201
+ else
202
+ if @limit
203
+ [_count, @limit].min
204
+ else
205
+ _count
206
+ end
207
+ end
208
+ end
209
+
187
210
  def first
188
211
  doc = do_find.first
189
212
  @klass.new( **doc ) if doc
@@ -200,8 +223,7 @@ module Mongous
200
223
  end
201
224
 
202
225
  def delete
203
- _filter = @filter
204
- @klass.collection.delete_many( _filter )
226
+ @klass.collection.delete_many( @filter )
205
227
  end
206
228
  end
207
229
  end