mongous 0.1.3 → 0.2.0

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