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.
- data/LICENSE.txt +202 -0
- data/README.rdoc +358 -0
- data/Rakefile +133 -0
- data/bin/bson_benchmark.rb +59 -0
- data/bin/fail_if_no_c.rb +11 -0
- data/examples/admin.rb +42 -0
- data/examples/capped.rb +22 -0
- data/examples/cursor.rb +48 -0
- data/examples/gridfs.rb +88 -0
- data/examples/index_test.rb +126 -0
- data/examples/info.rb +31 -0
- data/examples/queries.rb +70 -0
- data/examples/simple.rb +24 -0
- data/examples/strict.rb +35 -0
- data/examples/types.rb +36 -0
- data/lib/mongo.rb +61 -0
- data/lib/mongo/admin.rb +95 -0
- data/lib/mongo/collection.rb +664 -0
- data/lib/mongo/connection.rb +555 -0
- data/lib/mongo/cursor.rb +393 -0
- data/lib/mongo/db.rb +527 -0
- data/lib/mongo/exceptions.rb +60 -0
- data/lib/mongo/gridfs.rb +22 -0
- data/lib/mongo/gridfs/chunk.rb +90 -0
- data/lib/mongo/gridfs/grid_store.rb +555 -0
- data/lib/mongo/types/binary.rb +48 -0
- data/lib/mongo/types/code.rb +36 -0
- data/lib/mongo/types/dbref.rb +38 -0
- data/lib/mongo/types/min_max_keys.rb +58 -0
- data/lib/mongo/types/objectid.rb +219 -0
- data/lib/mongo/types/regexp_of_holding.rb +45 -0
- data/lib/mongo/util/bson_c.rb +18 -0
- data/lib/mongo/util/bson_ruby.rb +595 -0
- data/lib/mongo/util/byte_buffer.rb +222 -0
- data/lib/mongo/util/conversions.rb +97 -0
- data/lib/mongo/util/ordered_hash.rb +135 -0
- data/lib/mongo/util/server_version.rb +69 -0
- data/lib/mongo/util/support.rb +26 -0
- data/lib/mongo/util/xml_to_ruby.rb +112 -0
- data/mongo-ruby-driver.gemspec +28 -0
- data/test/replica/count_test.rb +34 -0
- data/test/replica/insert_test.rb +50 -0
- data/test/replica/pooled_insert_test.rb +54 -0
- data/test/replica/query_test.rb +39 -0
- data/test/test_admin.rb +67 -0
- data/test/test_bson.rb +397 -0
- data/test/test_byte_buffer.rb +81 -0
- data/test/test_chunk.rb +82 -0
- data/test/test_collection.rb +534 -0
- data/test/test_connection.rb +160 -0
- data/test/test_conversions.rb +120 -0
- data/test/test_cursor.rb +386 -0
- data/test/test_db.rb +254 -0
- data/test/test_db_api.rb +783 -0
- data/test/test_db_connection.rb +16 -0
- data/test/test_grid_store.rb +306 -0
- data/test/test_helper.rb +42 -0
- data/test/test_objectid.rb +156 -0
- data/test/test_ordered_hash.rb +168 -0
- data/test/test_round_trip.rb +114 -0
- data/test/test_slave_connection.rb +36 -0
- data/test/test_threading.rb +87 -0
- data/test/threading/test_threading_large_pool.rb +90 -0
- data/test/unit/collection_test.rb +52 -0
- data/test/unit/connection_test.rb +59 -0
- data/test/unit/cursor_test.rb +94 -0
- data/test/unit/db_test.rb +97 -0
- 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
|