mongo-find_replace 0.18.3

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 (68) hide show
  1. data/LICENSE.txt +202 -0
  2. data/README.rdoc +358 -0
  3. data/Rakefile +133 -0
  4. data/bin/bson_benchmark.rb +59 -0
  5. data/bin/fail_if_no_c.rb +11 -0
  6. data/examples/admin.rb +42 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +88 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +70 -0
  13. data/examples/simple.rb +24 -0
  14. data/examples/strict.rb +35 -0
  15. data/examples/types.rb +36 -0
  16. data/lib/mongo.rb +61 -0
  17. data/lib/mongo/admin.rb +95 -0
  18. data/lib/mongo/collection.rb +664 -0
  19. data/lib/mongo/connection.rb +555 -0
  20. data/lib/mongo/cursor.rb +393 -0
  21. data/lib/mongo/db.rb +527 -0
  22. data/lib/mongo/exceptions.rb +60 -0
  23. data/lib/mongo/gridfs.rb +22 -0
  24. data/lib/mongo/gridfs/chunk.rb +90 -0
  25. data/lib/mongo/gridfs/grid_store.rb +555 -0
  26. data/lib/mongo/types/binary.rb +48 -0
  27. data/lib/mongo/types/code.rb +36 -0
  28. data/lib/mongo/types/dbref.rb +38 -0
  29. data/lib/mongo/types/min_max_keys.rb +58 -0
  30. data/lib/mongo/types/objectid.rb +219 -0
  31. data/lib/mongo/types/regexp_of_holding.rb +45 -0
  32. data/lib/mongo/util/bson_c.rb +18 -0
  33. data/lib/mongo/util/bson_ruby.rb +595 -0
  34. data/lib/mongo/util/byte_buffer.rb +222 -0
  35. data/lib/mongo/util/conversions.rb +97 -0
  36. data/lib/mongo/util/ordered_hash.rb +135 -0
  37. data/lib/mongo/util/server_version.rb +69 -0
  38. data/lib/mongo/util/support.rb +26 -0
  39. data/lib/mongo/util/xml_to_ruby.rb +112 -0
  40. data/mongo-ruby-driver.gemspec +28 -0
  41. data/test/replica/count_test.rb +34 -0
  42. data/test/replica/insert_test.rb +50 -0
  43. data/test/replica/pooled_insert_test.rb +54 -0
  44. data/test/replica/query_test.rb +39 -0
  45. data/test/test_admin.rb +67 -0
  46. data/test/test_bson.rb +397 -0
  47. data/test/test_byte_buffer.rb +81 -0
  48. data/test/test_chunk.rb +82 -0
  49. data/test/test_collection.rb +534 -0
  50. data/test/test_connection.rb +160 -0
  51. data/test/test_conversions.rb +120 -0
  52. data/test/test_cursor.rb +386 -0
  53. data/test/test_db.rb +254 -0
  54. data/test/test_db_api.rb +783 -0
  55. data/test/test_db_connection.rb +16 -0
  56. data/test/test_grid_store.rb +306 -0
  57. data/test/test_helper.rb +42 -0
  58. data/test/test_objectid.rb +156 -0
  59. data/test/test_ordered_hash.rb +168 -0
  60. data/test/test_round_trip.rb +114 -0
  61. data/test/test_slave_connection.rb +36 -0
  62. data/test/test_threading.rb +87 -0
  63. data/test/threading/test_threading_large_pool.rb +90 -0
  64. data/test/unit/collection_test.rb +52 -0
  65. data/test/unit/connection_test.rb +59 -0
  66. data/test/unit/cursor_test.rb +94 -0
  67. data/test/unit/db_test.rb +97 -0
  68. metadata +123 -0
@@ -0,0 +1,222 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
17
+ # A byte buffer.
18
+ class ByteBuffer
19
+
20
+ # Commonly-used integers.
21
+ INT_LOOKUP = {
22
+ 0 => [0, 0, 0, 0],
23
+ 1 => [1, 0, 0, 0],
24
+ 2 => [2, 0, 0, 0],
25
+ 3 => [3, 0, 0, 0],
26
+ 4 => [4, 0, 0, 0],
27
+ 2001 => [209, 7, 0, 0],
28
+ 2002 => [210, 7, 0, 0],
29
+ 2004 => [212, 7, 0, 0],
30
+ 2005 => [213, 7, 0, 0],
31
+ 2006 => [214, 7, 0, 0]
32
+ }
33
+
34
+ attr_reader :order
35
+
36
+ def initialize(initial_data=[])
37
+ @buf = initial_data
38
+ @cursor = @buf.length
39
+ @order = :little_endian
40
+ @int_pack_order = 'V'
41
+ @double_pack_order = 'E'
42
+ end
43
+
44
+ if RUBY_VERSION >= '1.9'
45
+ def self.to_utf8(str)
46
+ str.encode("utf-8")
47
+ end
48
+ else
49
+ def self.to_utf8(str)
50
+ begin
51
+ str.unpack("U*")
52
+ rescue => ex
53
+ raise InvalidStringEncoding, "String not valid utf-8: #{str}"
54
+ end
55
+ str
56
+ end
57
+ end
58
+
59
+ def self.serialize_cstr(buf, val)
60
+ buf.put_array(to_utf8(val.to_s).unpack("C*") + [0])
61
+ end
62
+
63
+ # +endianness+ should be :little_endian or :big_endian. Default is :little_endian
64
+ def order=(endianness)
65
+ @order = endianness
66
+ @int_pack_order = endianness == :little_endian ? 'V' : 'N'
67
+ @double_pack_order = endianness == :little_endian ? 'E' : 'G'
68
+ end
69
+
70
+ def rewind
71
+ @cursor = 0
72
+ end
73
+
74
+ def position
75
+ @cursor
76
+ end
77
+
78
+ def position=(val)
79
+ @cursor = val
80
+ end
81
+
82
+ def clear
83
+ @buf = []
84
+ rewind
85
+ end
86
+
87
+ def size
88
+ @buf.size
89
+ end
90
+ alias_method :length, :size
91
+
92
+ # Appends a second ByteBuffer object, +buffer+, to the current buffer.
93
+ def append!(buffer)
94
+ @buf = @buf + buffer.to_a
95
+ self
96
+ end
97
+
98
+ # Prepends a second ByteBuffer object, +buffer+, to the current buffer.
99
+ def prepend!(buffer)
100
+ @buf = buffer.to_a + @buf
101
+ self
102
+ end
103
+
104
+ def put(byte, offset=nil)
105
+ @cursor = offset if offset
106
+ @buf[@cursor] = byte
107
+ @cursor += 1
108
+ end
109
+
110
+ def put_array(array, offset=nil)
111
+ @cursor = offset if offset
112
+ @buf[@cursor, array.length] = array
113
+ @cursor += array.length
114
+ end
115
+
116
+ def put_int(i, offset=nil)
117
+ unless a = INT_LOOKUP[i]
118
+ a = []
119
+ [i].pack(@int_pack_order).each_byte { |b| a << b }
120
+ end
121
+ put_array(a, offset)
122
+ end
123
+
124
+ def put_long(i, offset=nil)
125
+ offset = @cursor unless offset
126
+ if @int_pack_order == 'N'
127
+ put_int(i >> 32, offset)
128
+ put_int(i & 0xffffffff, offset + 4)
129
+ else
130
+ put_int(i & 0xffffffff, offset)
131
+ put_int(i >> 32, offset + 4)
132
+ end
133
+ end
134
+
135
+ def put_double(d, offset=nil)
136
+ a = []
137
+ [d].pack(@double_pack_order).each_byte { |b| a << b }
138
+ put_array(a, offset)
139
+ end
140
+
141
+ # If +size+ == nil, returns one byte. Else returns array of bytes of length
142
+ # # +size+.
143
+ def get(len=nil)
144
+ one_byte = len.nil?
145
+ len ||= 1
146
+ check_read_length(len)
147
+ start = @cursor
148
+ @cursor += len
149
+ if one_byte
150
+ @buf[start]
151
+ else
152
+ if @buf.respond_to? "unpack"
153
+ @buf[start, len].unpack("C*")
154
+ else
155
+ @buf[start, len]
156
+ end
157
+ end
158
+ end
159
+
160
+ def get_int
161
+ check_read_length(4)
162
+ vals = ""
163
+ (@cursor..@cursor+3).each { |i| vals << @buf[i].chr }
164
+ @cursor += 4
165
+ vals.unpack(@int_pack_order)[0]
166
+ end
167
+
168
+ def get_long
169
+ i1 = get_int
170
+ i2 = get_int
171
+ if @int_pack_order == 'N'
172
+ (i1 << 32) + i2
173
+ else
174
+ (i2 << 32) + i1
175
+ end
176
+ end
177
+
178
+ def get_double
179
+ check_read_length(8)
180
+ vals = ""
181
+ (@cursor..@cursor+7).each { |i| vals << @buf[i].chr }
182
+ @cursor += 8
183
+ vals.unpack(@double_pack_order)[0]
184
+ end
185
+
186
+ def more?
187
+ @cursor < @buf.size
188
+ end
189
+
190
+ def to_a
191
+ if @buf.respond_to? "unpack"
192
+ @buf.unpack("C*")
193
+ else
194
+ @buf
195
+ end
196
+ end
197
+
198
+ def unpack(args)
199
+ to_a
200
+ end
201
+
202
+ def to_s
203
+ if @buf.respond_to? :fast_pack
204
+ @buf.fast_pack
205
+ elsif @buf.respond_to? "pack"
206
+ @buf.pack("C*")
207
+ else
208
+ @buf
209
+ end
210
+ end
211
+
212
+ def dump
213
+ @buf.each_with_index { |c, i| $stderr.puts "#{'%04d' % i}: #{'%02x' % c} #{'%03o' % c} #{'%s' % c.chr} #{'%3d' % c}" }
214
+ end
215
+
216
+ private
217
+
218
+ def check_read_length(len)
219
+ raise "attempt to read past end of buffer" if @cursor + len > @buf.length
220
+ end
221
+
222
+ end
@@ -0,0 +1,97 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+ module Mongo #:nodoc:
17
+
18
+ # Utility module to include when needing to convert certain types of
19
+ # objects to mongo-friendly parameters.
20
+ module Conversions
21
+
22
+ ASCENDING_CONVERSION = ["ascending", "asc", "1"]
23
+ DESCENDING_CONVERSION = ["descending", "desc", "-1"]
24
+
25
+ def formatted_sort_clause(sort)
26
+ case sort
27
+ when String, Symbol then string_as_sort_parameters(sort)
28
+ when Array then array_as_sort_parameters(sort)
29
+ else
30
+ raise InvalidSortValueError, "Illegal sort clause, '#{sort}'; must be of the form " +
31
+ "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"
32
+ end
33
+ end
34
+
35
+ # Converts the supplied +Array+ to a +Hash+ to pass to mongo as
36
+ # sorting parameters. The returned +Hash+ will vary depending
37
+ # on whether the passed +Array+ is one or two dimensional.
38
+ #
39
+ # Example:
40
+ #
41
+ # <tt>array_as_sort_parameters([["field1", :asc], ["field2", :desc]])</tt> =>
42
+ # <tt>{ "field1" => 1, "field2" => -1}</tt>
43
+ def array_as_sort_parameters(value)
44
+ order_by = OrderedHash.new
45
+ if value.first.is_a? Array
46
+ value.each do |param|
47
+ if (param.class.name == "String")
48
+ order_by[param] = 1
49
+ else
50
+ order_by[param[0]] = sort_value(param[1]) unless param[1].nil?
51
+ end
52
+ end
53
+ elsif !value.empty?
54
+ if order_by.size == 1
55
+ order_by[value.first] = 1
56
+ else
57
+ order_by[value.first] = sort_value(value[1])
58
+ end
59
+ end
60
+ order_by
61
+ end
62
+
63
+ # Converts the supplied +String+ or +Symbol+ to a +Hash+ to pass to mongo as
64
+ # a sorting parameter with ascending order. If the +String+
65
+ # is empty then an empty +Hash+ will be returned.
66
+ #
67
+ # Example:
68
+ #
69
+ # *DEPRECATED
70
+ #
71
+ # <tt>string_as_sort_parameters("field")</tt> => <tt>{ "field" => 1 }</tt>
72
+ # <tt>string_as_sort_parameters("")</tt> => <tt>{}</tt>
73
+ def string_as_sort_parameters(value)
74
+ return {} if (str = value.to_s).empty?
75
+ { str => 1 }
76
+ end
77
+
78
+ # Converts the +String+, +Symbol+, or +Integer+ to the
79
+ # corresponding sort value in MongoDB.
80
+ #
81
+ # Valid conversions (case-insensitive):
82
+ #
83
+ # <tt>ascending, asc, :ascending, :asc, 1</tt> => <tt>1</tt>
84
+ # <tt>descending, desc, :descending, :desc, -1</tt> => <tt>-1</tt>
85
+ #
86
+ # If the value is invalid then an error will be raised.
87
+ def sort_value(value)
88
+ val = value.to_s.downcase
89
+ return 1 if ASCENDING_CONVERSION.include?(val)
90
+ return -1 if DESCENDING_CONVERSION.include?(val)
91
+ raise InvalidSortValueError.new(
92
+ "#{self} was supplied as a sort direction when acceptable values are: " +
93
+ "Mongo::ASCENDING, 'ascending', 'asc', :ascending, :asc, 1, Mongo::DESCENDING, " +
94
+ "'descending', 'desc', :descending, :desc, -1.")
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,135 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
17
+ # A hash in which the order of keys are preserved.
18
+ #
19
+ # Under Ruby 1.9 and greater, this class has no added methods because Ruby's
20
+ # Hash already keeps its keys ordered by order of insertion.
21
+ class OrderedHash < Hash
22
+
23
+ def ==(other)
24
+ begin
25
+ !other.nil? &&
26
+ keys == other.keys &&
27
+ values == other.values
28
+ rescue
29
+ false
30
+ end
31
+ end
32
+
33
+ # We only need the body of this class if the RUBY_VERSION is before 1.9
34
+ if RUBY_VERSION < '1.9'
35
+ attr_accessor :ordered_keys
36
+
37
+ def self.[] *args
38
+ oh = OrderedHash.new
39
+ if Hash === args[0]
40
+ oh.merge! args[0]
41
+ elsif (args.size % 2) != 0
42
+ raise ArgumentError, "odd number of elements for Hash"
43
+ else
44
+ 0.step(args.size - 1, 2) do |key|
45
+ value = key + 1
46
+ oh[args[key]] = args[value]
47
+ end
48
+ end
49
+ oh
50
+ end
51
+
52
+ def initialize(*a, &b)
53
+ super
54
+ @ordered_keys = []
55
+ end
56
+
57
+ def keys
58
+ @ordered_keys || []
59
+ end
60
+
61
+ def []=(key, value)
62
+ @ordered_keys ||= []
63
+ @ordered_keys << key unless @ordered_keys.include?(key)
64
+ super(key, value)
65
+ end
66
+
67
+ def each
68
+ @ordered_keys ||= []
69
+ @ordered_keys.each { |k| yield k, self[k] }
70
+ self
71
+ end
72
+ alias :each_pair :each
73
+
74
+ def values
75
+ collect { |k, v| v }
76
+ end
77
+
78
+ def merge(other)
79
+ oh = self.dup
80
+ oh.merge!(other)
81
+ oh
82
+ end
83
+
84
+ def merge!(other)
85
+ @ordered_keys ||= []
86
+ @ordered_keys += other.keys # unordered if not an OrderedHash
87
+ @ordered_keys.uniq!
88
+ super(other)
89
+ end
90
+
91
+ alias :update :merge!
92
+
93
+ def inspect
94
+ str = '{'
95
+ str << (@ordered_keys || []).collect { |k| "\"#{k}\"=>#{self.[](k).inspect}" }.join(", ")
96
+ str << '}'
97
+ end
98
+
99
+ def delete(key, &block)
100
+ @ordered_keys.delete(key) if @ordered_keys
101
+ super
102
+ end
103
+
104
+ def delete_if(&block)
105
+ self.each { |k,v|
106
+ if yield k, v
107
+ delete(k)
108
+ end
109
+ }
110
+ end
111
+
112
+ def clear
113
+ super
114
+ @ordered_keys = []
115
+ end
116
+
117
+ def hash
118
+ code = 17
119
+ each_pair do |key, value|
120
+ code = 37 * code + key.hash
121
+ code = 37 * code + value.hash
122
+ end
123
+ code & 0x7fffffff
124
+ end
125
+
126
+ def eql?(o)
127
+ if o.instance_of? OrderedHash
128
+ self.hash == o.hash
129
+ else
130
+ false
131
+ end
132
+ end
133
+
134
+ end
135
+ end