mongo-find_replace 0.18.3

Sign up to get free protection for your applications and to get access to all the features.
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