mongo 0.19.1 → 0.19.2
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/README.rdoc +14 -14
- data/Rakefile +5 -0
- data/bin/gr.rb +14 -0
- data/lib/bson.rb +46 -0
- data/lib/bson/bson_c.rb +20 -0
- data/lib/bson/bson_ruby.rb +601 -0
- data/lib/bson/byte_buffer.rb +224 -0
- data/lib/bson/exceptions.rb +39 -0
- data/lib/bson/ordered_hash.rb +140 -0
- data/lib/bson/types/binary.rb +54 -0
- data/lib/bson/types/code.rb +36 -0
- data/lib/bson/types/dbref.rb +40 -0
- data/lib/bson/types/min_max_keys.rb +58 -0
- data/lib/bson/types/objectid.rb +180 -0
- data/lib/bson/types/regexp_of_holding.rb +45 -0
- data/lib/mongo.rb +4 -2
- data/lib/mongo/collection.rb +61 -20
- data/lib/mongo/connection.rb +18 -4
- data/lib/mongo/cursor.rb +13 -12
- data/lib/mongo/db.rb +11 -29
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_io.rb +4 -0
- data/lib/mongo/util/core_ext.rb +37 -0
- data/lib/mongo/util/support.rb +40 -7
- data/test/auxillary/1.4_features.rb +166 -0
- data/test/collection_test.rb +30 -1
- data/test/connection_test.rb +18 -1
- data/test/cursor_test.rb +14 -0
- data/test/db_api_test.rb +4 -10
- data/test/grid_test.rb +13 -0
- data/test/unit/collection_test.rb +14 -4
- metadata +27 -5
@@ -0,0 +1,36 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2010 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
|
+
module BSON
|
18
|
+
|
19
|
+
# JavaScript code to be evaluated by MongoDB.
|
20
|
+
class Code < String
|
21
|
+
|
22
|
+
# Hash mapping identifiers to their values
|
23
|
+
attr_accessor :scope
|
24
|
+
|
25
|
+
# Wrap code to be evaluated by MongoDB.
|
26
|
+
#
|
27
|
+
# @param [String] code the JavaScript code.
|
28
|
+
# @param [Hash] a document mapping identifiers to values, which
|
29
|
+
# represent the scope in which the code is to be executed.
|
30
|
+
def initialize(code, scope={})
|
31
|
+
super(code)
|
32
|
+
@scope = scope
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2010 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
|
+
module BSON
|
18
|
+
|
19
|
+
# A reference to another object in a MongoDB database.
|
20
|
+
class DBRef
|
21
|
+
|
22
|
+
attr_reader :namespace, :object_id
|
23
|
+
|
24
|
+
# Create a DBRef. Use this class in conjunction with DB#dereference.
|
25
|
+
#
|
26
|
+
# @param [String] a collection name
|
27
|
+
# @param [ObjectID] an object id
|
28
|
+
#
|
29
|
+
# @core dbrefs constructor_details
|
30
|
+
def initialize(namespace, object_id)
|
31
|
+
@namespace = namespace
|
32
|
+
@object_id = object_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"ns: #{namespace}, id: #{object_id}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2010 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
|
+
module BSON
|
18
|
+
|
19
|
+
# A class representing the BSON MaxKey type. MaxKey will always compare greater than
|
20
|
+
# all other BSON types and values.
|
21
|
+
#
|
22
|
+
# @example Sorting (assume @numbers is a collection):
|
23
|
+
#
|
24
|
+
# >> @numbers.save({"n" => Mongo::MaxKey.new})
|
25
|
+
# >> @numbers.save({"n" => 0})
|
26
|
+
# >> @numbers.save({"n" => 5_000_000})
|
27
|
+
# >> @numbers.find.sort("n").to_a
|
28
|
+
# => [{"_id"=>4b5a050c238d3bace2000004, "n"=>0},
|
29
|
+
# {"_id"=>4b5a04e6238d3bace2000002, "n"=>5_000_000},
|
30
|
+
# {"_id"=>4b5a04ea238d3bace2000003, "n"=>#<Mongo::MaxKey:0x1014ef410>},
|
31
|
+
# ]
|
32
|
+
class MaxKey
|
33
|
+
|
34
|
+
def ==(obj)
|
35
|
+
obj.class == MaxKey
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# A class representing the BSON MinKey type. MinKey will always compare less than
|
40
|
+
# all other BSON types and values.
|
41
|
+
#
|
42
|
+
# @example Sorting (assume @numbers is a collection):
|
43
|
+
#
|
44
|
+
# >> @numbers.save({"n" => Mongo::MinKey.new})
|
45
|
+
# >> @numbers.save({"n" => -1_000_000})
|
46
|
+
# >> @numbers.save({"n" => 1_000_000})
|
47
|
+
# >> @numbers.find.sort("n").to_a
|
48
|
+
# => [{"_id"=>4b5a050c238d3bace2000004, "n"=>#<Mongo::MinKey:0x1014ef410>},
|
49
|
+
# {"_id"=>4b5a04e6238d3bace2000002, "n"=>-1_000_000},
|
50
|
+
# {"_id"=>4b5a04ea238d3bace2000003, "n"=>1_000_000},
|
51
|
+
# ]
|
52
|
+
class MinKey
|
53
|
+
|
54
|
+
def ==(obj)
|
55
|
+
obj.class == MinKey
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2010 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
|
+
require 'thread'
|
18
|
+
require 'socket'
|
19
|
+
require 'digest/md5'
|
20
|
+
|
21
|
+
module BSON
|
22
|
+
|
23
|
+
# Generates MongoDB object ids.
|
24
|
+
#
|
25
|
+
# @core objectids
|
26
|
+
class ObjectID
|
27
|
+
@@lock = Mutex.new
|
28
|
+
@@index = 0
|
29
|
+
|
30
|
+
# Create a new object id. If no parameter is given, an id corresponding
|
31
|
+
# to the ObjectID BSON data type will be created. This is a 12-byte value
|
32
|
+
# consisting of a 4-byte timestamp, a 3-byte machine id, a 2-byte process id,
|
33
|
+
# and a 3-byte counter.
|
34
|
+
#
|
35
|
+
# @param [Array] data should be an array of bytes. If you want
|
36
|
+
# to generate a standard MongoDB object id, leave this argument blank.
|
37
|
+
def initialize(data=nil)
|
38
|
+
@data = data || generate
|
39
|
+
end
|
40
|
+
|
41
|
+
# Determine if the supplied string is legal. Legal strings will
|
42
|
+
# consist of 24 hexadecimal characters.
|
43
|
+
#
|
44
|
+
# @param [String] str
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
47
|
+
def self.legal?(str)
|
48
|
+
len = 24
|
49
|
+
str =~ /([0-9a-f]+)/i
|
50
|
+
match = $1
|
51
|
+
str && str.length == len && match == str
|
52
|
+
end
|
53
|
+
|
54
|
+
# Create an object id from the given time. This is useful for doing range
|
55
|
+
# queries; it works because MongoDB's object ids begin
|
56
|
+
# with a timestamp.
|
57
|
+
#
|
58
|
+
# @param [Time] time a utc time to encode as an object id.
|
59
|
+
#
|
60
|
+
# @return [Mongo::ObjectID]
|
61
|
+
#
|
62
|
+
# @example Return all document created before Jan 1, 2010.
|
63
|
+
# time = Time.utc(2010, 1, 1)
|
64
|
+
# time_id = ObjectID.from_time(time)
|
65
|
+
# collection.find({'_id' => {'$lt' => time_id}})
|
66
|
+
def self.from_time(time)
|
67
|
+
self.new([time.to_i,0,0].pack("NNN").unpack("C12"))
|
68
|
+
end
|
69
|
+
|
70
|
+
# Adds a primary key to the given document if needed.
|
71
|
+
#
|
72
|
+
# @param [Hash] doc a document requiring an _id.
|
73
|
+
#
|
74
|
+
# @return [Mongo::ObjectID, Object] returns a newly-created or
|
75
|
+
# current _id for the given document.
|
76
|
+
def self.create_pk(doc)
|
77
|
+
doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!(:_id => self.new)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Check equality of this object id with another.
|
81
|
+
#
|
82
|
+
# @param [Mongo::ObjectID] object_id
|
83
|
+
def eql?(object_id)
|
84
|
+
@data == object_id.instance_variable_get("@data")
|
85
|
+
end
|
86
|
+
alias_method :==, :eql?
|
87
|
+
|
88
|
+
# Get a unique hashcode for this object.
|
89
|
+
# This is required since we've defined an #eql? method.
|
90
|
+
#
|
91
|
+
# @return [Integer]
|
92
|
+
def hash
|
93
|
+
@data.hash
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get an array representation of the object id.
|
97
|
+
#
|
98
|
+
# @return [Array]
|
99
|
+
def to_a
|
100
|
+
@data.dup
|
101
|
+
end
|
102
|
+
|
103
|
+
# Given a string representation of an ObjectID, return a new ObjectID
|
104
|
+
# with that value.
|
105
|
+
#
|
106
|
+
# @param [String] str
|
107
|
+
#
|
108
|
+
# @return [Mongo::ObjectID]
|
109
|
+
def self.from_string(str)
|
110
|
+
raise InvalidObjectID, "illegal ObjectID format" unless legal?(str)
|
111
|
+
data = []
|
112
|
+
12.times do |i|
|
113
|
+
data[i] = str[i * 2, 2].to_i(16)
|
114
|
+
end
|
115
|
+
self.new(data)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get a string representation of this object id.
|
119
|
+
#
|
120
|
+
# @return [String]
|
121
|
+
def to_s
|
122
|
+
str = ' ' * 24
|
123
|
+
12.times do |i|
|
124
|
+
str[i * 2, 2] = '%02x' % @data[i]
|
125
|
+
end
|
126
|
+
str
|
127
|
+
end
|
128
|
+
|
129
|
+
def inspect
|
130
|
+
"ObjectID('#{to_s}')"
|
131
|
+
end
|
132
|
+
|
133
|
+
# Convert to MongoDB extended JSON format. Since JSON includes type information,
|
134
|
+
# but lacks an ObjectID type, this JSON format encodes the type using an $id key.
|
135
|
+
#
|
136
|
+
# @return [String] the object id represented as MongoDB extended JSON.
|
137
|
+
def to_json(escaped=false)
|
138
|
+
"{\"$oid\": \"#{to_s}\"}"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Return the UTC time at which this ObjectID was generated. This may
|
142
|
+
# be used in lieu of a created_at timestamp since this information
|
143
|
+
# is always encoded in the object id.
|
144
|
+
#
|
145
|
+
# @return [Time] the time at which this object was created.
|
146
|
+
def generation_time
|
147
|
+
Time.at(@data.pack("C4").unpack("N")[0]).utc
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
# We need to define this method only if CBson isn't loaded.
|
153
|
+
unless defined? CBson
|
154
|
+
def generate
|
155
|
+
oid = ''
|
156
|
+
|
157
|
+
# 4 bytes current time
|
158
|
+
time = Time.new.to_i
|
159
|
+
oid += [time].pack("N")
|
160
|
+
|
161
|
+
# 3 bytes machine
|
162
|
+
oid += Digest::MD5.digest(Socket.gethostname)[0, 3]
|
163
|
+
|
164
|
+
# 2 bytes pid
|
165
|
+
oid += [Process.pid % 0xFFFF].pack("n")
|
166
|
+
|
167
|
+
# 3 bytes inc
|
168
|
+
oid += [get_inc].pack("N")[1, 3]
|
169
|
+
|
170
|
+
oid.unpack("C12")
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_inc
|
175
|
+
@@lock.synchronize do
|
176
|
+
@@index = (@@index + 1) % 0xFFFFFF
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2010 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
|
+
module BSON
|
18
|
+
|
19
|
+
# A Regexp that can hold on to extra options and ignore them. Mongo
|
20
|
+
# regexes may contain option characters beyond 'i', 'm', and 'x'. (Note
|
21
|
+
# that Mongo only uses those three, but that regexes coming from other
|
22
|
+
# languages may store different option characters.)
|
23
|
+
#
|
24
|
+
# Note that you do not have to use this class at all if you wish to
|
25
|
+
# store regular expressions in Mongo. The Mongo and Ruby regex option
|
26
|
+
# flags are the same. Storing regexes is discouraged, in any case.
|
27
|
+
#
|
28
|
+
# @deprecated
|
29
|
+
class RegexpOfHolding < Regexp
|
30
|
+
|
31
|
+
attr_accessor :extra_options_str
|
32
|
+
|
33
|
+
# @deprecated we're no longer supporting this.
|
34
|
+
# +str+ and +options+ are the same as Regexp. +extra_options_str+
|
35
|
+
# contains all the other flags that were in Mongo but we do not use or
|
36
|
+
# understand.
|
37
|
+
def initialize(str, options, extra_options_str)
|
38
|
+
warn "RegexpOfHolding is deprecated; the modifiers i, m, and x will be stored automatically as BSON." +
|
39
|
+
"If you're only storing the options i, m, and x, you can safely ignore this message."
|
40
|
+
super(str, options)
|
41
|
+
@extra_options_str = extra_options_str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/mongo.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
|
3
3
|
module Mongo
|
4
|
-
VERSION = "0.19.
|
4
|
+
VERSION = "0.19.2"
|
5
5
|
end
|
6
6
|
|
7
7
|
begin
|
@@ -21,8 +21,9 @@ begin
|
|
21
21
|
end
|
22
22
|
|
23
23
|
module Mongo
|
24
|
-
ASCENDING
|
24
|
+
ASCENDING = 1
|
25
25
|
DESCENDING = -1
|
26
|
+
GEO2D = '2d'
|
26
27
|
|
27
28
|
module Constants
|
28
29
|
OP_REPLY = 1
|
@@ -48,6 +49,7 @@ require 'mongo/types/regexp_of_holding'
|
|
48
49
|
require 'mongo/types/min_max_keys'
|
49
50
|
|
50
51
|
require 'mongo/util/support'
|
52
|
+
require 'mongo/util/core_ext'
|
51
53
|
require 'mongo/util/conversions'
|
52
54
|
require 'mongo/util/server_version'
|
53
55
|
require 'mongo/util/bson_ruby'
|
data/lib/mongo/collection.rb
CHANGED
@@ -265,13 +265,13 @@ module Mongo
|
|
265
265
|
|
266
266
|
if opts[:safe]
|
267
267
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_DELETE, message, @db.name,
|
268
|
-
"
|
268
|
+
"#{@db.name}['#{@name}'].remove(#{selector.inspect})")
|
269
269
|
# the return value of send_message_with_safe_check isn't actually meaningful --
|
270
270
|
# only the fact that it didn't raise an error is -- so just return true
|
271
271
|
true
|
272
272
|
else
|
273
273
|
@connection.send_message(Mongo::Constants::OP_DELETE, message,
|
274
|
-
"
|
274
|
+
"#{@db.name}['#{@name}'].remove(#{selector.inspect})")
|
275
275
|
end
|
276
276
|
end
|
277
277
|
|
@@ -307,41 +307,82 @@ module Mongo
|
|
307
307
|
message.put_array(BSON.serialize(document, false, true).to_a)
|
308
308
|
if options[:safe]
|
309
309
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message, @db.name,
|
310
|
-
"db
|
310
|
+
"#{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})")
|
311
311
|
else
|
312
312
|
@connection.send_message(Mongo::Constants::OP_UPDATE, message,
|
313
|
-
"db
|
313
|
+
"#{@db.name}['#{@name}'].update(#{selector.inspect}, #{document.inspect})")
|
314
314
|
end
|
315
315
|
end
|
316
316
|
|
317
317
|
# Create a new index.
|
318
318
|
#
|
319
|
-
# @param [String, Array]
|
319
|
+
# @param [String, Array] spec
|
320
320
|
# should be either a single field name or an array of
|
321
|
-
# [field name, direction] pairs. Directions should be specified
|
321
|
+
# [field name, direction] pairs. Directions should be specified
|
322
|
+
# as Mongo::ASCENDING, Mongo::DESCENDING, or Mongo::GEO2D.
|
322
323
|
#
|
323
|
-
#
|
324
|
+
# Note that geospatial indexing only works with versions of MongoDB >= 1.3.3+. Keep in mind, too,
|
325
|
+
# that in order to geo-index a given field, that field must reference either an array or a sub-object
|
326
|
+
# where the first two values represent x- and y-coordinates. Examples can be seen below.
|
327
|
+
#
|
328
|
+
# Also note that it is permissible to create compound indexes that include a geospatial index as
|
329
|
+
# long as the geospatial index comes first.
|
330
|
+
#
|
331
|
+
# @param [Boolean] unique if true, this index will enforce a uniqueness constraint. DEPRECATED. Future
|
332
|
+
# versions of this driver will specify the uniqueness constraint using a hash param.
|
333
|
+
#
|
334
|
+
# @option opts [Boolean] :unique (false) if true, this index will enforce a uniqueness constraint.
|
335
|
+
# @option opts [Boolean] :background (false) indicate that the index should be built in the background. This
|
336
|
+
# feature is only available in MongoDB >= 1.3.2.
|
337
|
+
# @option opts [Boolean] :dropDups If creating a unique index on a collection with pre-existing records,
|
338
|
+
# this option will keep the first document the database indexes and drop all subsequent with duplicate values.
|
339
|
+
# @option opts [Integer] :min specify the minimum longitude and latitude for a geo index.
|
340
|
+
# @option opts [Integer] :max specify the maximum longitude and latitude for a geo index.
|
341
|
+
#
|
342
|
+
# @example Creating a compound index:
|
343
|
+
# @posts.create_index([['subject', Mongo::ASCENDING], ['created_at', Mongo::DESCENDING]])
|
344
|
+
#
|
345
|
+
# @example Creating a geospatial index:
|
346
|
+
# @restaurants.create_index([['location', Mongo::GEO2D]])
|
347
|
+
#
|
348
|
+
# # Note that this will work only if 'location' represents x,y coordinates:
|
349
|
+
# {'location': [0, 50]}
|
350
|
+
# {'location': {'x' => 0, 'y' => 50}}
|
351
|
+
# {'location': {'latitude' => 0, 'longitude' => 50}}
|
352
|
+
#
|
353
|
+
# @example A geospatial index with alternate longitude and latitude:
|
354
|
+
# @restaurants.create_index([['location', Mongo::GEO2D]], :min => 500, :max => 500)
|
324
355
|
#
|
325
356
|
# @return [String] the name of the index created.
|
326
357
|
#
|
327
358
|
# @core indexes create_index-instance_method
|
328
|
-
def create_index(
|
329
|
-
|
330
|
-
|
331
|
-
|
359
|
+
def create_index(spec, opts={})
|
360
|
+
opts.assert_valid_keys(:min, :max, :background, :unique, :dropDups) if opts.is_a?(Hash)
|
361
|
+
field_spec = OrderedHash.new
|
362
|
+
if spec.is_a?(String) || spec.is_a?(Symbol)
|
363
|
+
field_spec[spec.to_s] = 1
|
364
|
+
elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
|
365
|
+
spec.each { |f| field_spec[f[0].to_s] = f[1] }
|
332
366
|
else
|
333
|
-
|
367
|
+
raise MongoArgumentError, "Invalid index specification #{spec.inspect}; " +
|
368
|
+
"should be either a string, symbol, or an array of arrays."
|
369
|
+
end
|
370
|
+
|
371
|
+
name = generate_index_name(field_spec)
|
372
|
+
if opts == true || opts == false
|
373
|
+
warn "For Collection#create_index, the method for specifying a unique index has changed." +
|
374
|
+
"Please pass :unique => true to the method instead."
|
334
375
|
end
|
335
|
-
name = generate_index_names(field_h)
|
336
376
|
sel = {
|
337
377
|
:name => name,
|
338
378
|
:ns => "#{@db.name}.#{@name}",
|
339
|
-
:key =>
|
340
|
-
:unique =>
|
379
|
+
:key => field_spec,
|
380
|
+
:unique => (opts == true ? true : false) }
|
381
|
+
sel.merge!(opts) if opts.is_a?(Hash)
|
341
382
|
begin
|
342
|
-
insert_documents([sel], Mongo::DB::SYSTEM_INDEX_COLLECTION, false, true)
|
383
|
+
response = insert_documents([sel], Mongo::DB::SYSTEM_INDEX_COLLECTION, false, true)
|
343
384
|
rescue Mongo::OperationFailure
|
344
|
-
raise Mongo::OperationFailure, "Failed to create index #{sel.inspect}
|
385
|
+
raise Mongo::OperationFailure, "Failed to create index #{sel.inspect} with the following errors: #{response}"
|
345
386
|
end
|
346
387
|
name
|
347
388
|
end
|
@@ -593,15 +634,15 @@ module Mongo
|
|
593
634
|
documents.each { |doc| message.put_array(BSON.serialize(doc, check_keys, true).to_a) }
|
594
635
|
if safe
|
595
636
|
@connection.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message, @db.name,
|
596
|
-
"db
|
637
|
+
"#{@db.name}['#{collection_name}'].insert(#{documents.inspect})")
|
597
638
|
else
|
598
639
|
@connection.send_message(Mongo::Constants::OP_INSERT, message,
|
599
|
-
"db
|
640
|
+
"#{@db.name}['#{collection_name}'].insert(#{documents.inspect})")
|
600
641
|
end
|
601
642
|
documents.collect { |o| o[:_id] || o['_id'] }
|
602
643
|
end
|
603
644
|
|
604
|
-
def
|
645
|
+
def generate_index_name(spec)
|
605
646
|
indexes = []
|
606
647
|
spec.each_pair do |field, direction|
|
607
648
|
indexes.push("#{field}_#{direction}")
|