mongo 0.1.0 → 0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +268 -71
- data/Rakefile +27 -62
- data/bin/bson_benchmark.rb +59 -0
- data/bin/mongo_console +3 -3
- data/bin/run_test_script +19 -0
- data/bin/standard_benchmark +109 -0
- data/examples/admin.rb +41 -0
- data/examples/benchmarks.rb +42 -0
- data/examples/blog.rb +76 -0
- data/examples/capped.rb +23 -0
- data/examples/cursor.rb +47 -0
- data/examples/gridfs.rb +87 -0
- data/examples/index_test.rb +125 -0
- data/examples/info.rb +30 -0
- data/examples/queries.rb +69 -0
- data/examples/simple.rb +23 -0
- data/examples/strict.rb +34 -0
- data/examples/types.rb +35 -0
- data/lib/mongo.rb +9 -2
- data/lib/mongo/admin.rb +65 -68
- data/lib/mongo/collection.rb +379 -117
- data/lib/mongo/connection.rb +151 -0
- data/lib/mongo/cursor.rb +271 -216
- data/lib/mongo/db.rb +500 -315
- data/lib/mongo/errors.rb +26 -0
- data/lib/mongo/gridfs.rb +16 -0
- data/lib/mongo/gridfs/chunk.rb +92 -0
- data/lib/mongo/gridfs/grid_store.rb +464 -0
- data/lib/mongo/message.rb +16 -0
- data/lib/mongo/message/get_more_message.rb +24 -13
- data/lib/mongo/message/insert_message.rb +29 -11
- data/lib/mongo/message/kill_cursors_message.rb +23 -12
- data/lib/mongo/message/message.rb +74 -62
- data/lib/mongo/message/message_header.rb +35 -24
- data/lib/mongo/message/msg_message.rb +21 -9
- data/lib/mongo/message/opcodes.rb +26 -15
- data/lib/mongo/message/query_message.rb +63 -43
- data/lib/mongo/message/remove_message.rb +29 -12
- data/lib/mongo/message/update_message.rb +30 -13
- data/lib/mongo/query.rb +97 -89
- data/lib/mongo/types/binary.rb +25 -21
- data/lib/mongo/types/code.rb +30 -0
- data/lib/mongo/types/dbref.rb +19 -23
- data/lib/mongo/types/objectid.rb +130 -116
- data/lib/mongo/types/regexp_of_holding.rb +27 -31
- data/lib/mongo/util/bson.rb +273 -160
- data/lib/mongo/util/byte_buffer.rb +32 -28
- data/lib/mongo/util/ordered_hash.rb +88 -42
- data/lib/mongo/util/xml_to_ruby.rb +18 -15
- data/mongo-ruby-driver.gemspec +103 -0
- data/test/mongo-qa/_common.rb +8 -0
- data/test/mongo-qa/admin +26 -0
- data/test/mongo-qa/capped +22 -0
- data/test/mongo-qa/count1 +18 -0
- data/test/mongo-qa/dbs +22 -0
- data/test/mongo-qa/find +10 -0
- data/test/mongo-qa/find1 +15 -0
- data/test/mongo-qa/gridfs_in +16 -0
- data/test/mongo-qa/gridfs_out +17 -0
- data/test/mongo-qa/indices +49 -0
- data/test/mongo-qa/remove +25 -0
- data/test/mongo-qa/stress1 +35 -0
- data/test/mongo-qa/test1 +11 -0
- data/test/mongo-qa/update +18 -0
- data/{tests → test}/test_admin.rb +25 -16
- data/test/test_bson.rb +268 -0
- data/{tests → test}/test_byte_buffer.rb +0 -0
- data/test/test_chunk.rb +84 -0
- data/test/test_collection.rb +282 -0
- data/test/test_connection.rb +101 -0
- data/test/test_cursor.rb +321 -0
- data/test/test_db.rb +196 -0
- data/test/test_db_api.rb +798 -0
- data/{tests → test}/test_db_connection.rb +4 -3
- data/test/test_grid_store.rb +284 -0
- data/{tests → test}/test_message.rb +1 -1
- data/test/test_objectid.rb +105 -0
- data/{tests → test}/test_ordered_hash.rb +55 -0
- data/{tests → test}/test_round_trip.rb +13 -9
- data/test/test_threading.rb +37 -0
- metadata +74 -32
- data/bin/validate +0 -51
- data/lib/mongo/mongo.rb +0 -74
- data/lib/mongo/types/undefined.rb +0 -31
- data/tests/test_bson.rb +0 -135
- data/tests/test_cursor.rb +0 -66
- data/tests/test_db.rb +0 -51
- data/tests/test_db_api.rb +0 -349
- data/tests/test_objectid.rb +0 -88
data/lib/mongo/collection.rb
CHANGED
@@ -1,153 +1,415 @@
|
|
1
1
|
# --
|
2
2
|
# Copyright (C) 2008-2009 10gen Inc.
|
3
3
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
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
7
|
#
|
8
|
-
#
|
9
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
10
|
-
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
|
11
|
-
# for more details.
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
9
|
#
|
13
|
-
#
|
14
|
-
#
|
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
15
|
# ++
|
16
16
|
|
17
17
|
require 'mongo/query'
|
18
18
|
|
19
|
-
module
|
20
|
-
module Mongo
|
21
|
-
module Driver
|
19
|
+
module Mongo
|
22
20
|
|
23
|
-
|
24
|
-
|
21
|
+
# A named collection of records in a database.
|
22
|
+
class Collection
|
25
23
|
|
26
|
-
|
24
|
+
attr_reader :db, :name, :hint
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
def initialize(db, name)
|
27
|
+
case name
|
28
|
+
when Symbol, String
|
29
|
+
else
|
30
|
+
raise TypeError, "new_name must be a string or symbol"
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
# single field name, array of field names, or a hash whose keys will
|
35
|
-
# become the hint field names. May be +nil+.
|
36
|
-
def hint(hint_fields)
|
37
|
-
@hint_fields = case hint_fields
|
38
|
-
when String
|
39
|
-
[hint_fields]
|
40
|
-
when Hash
|
41
|
-
hint_fields.keys
|
42
|
-
when nil
|
43
|
-
nil
|
44
|
-
else
|
45
|
-
hint_fields.to_a
|
46
|
-
end
|
47
|
-
self
|
48
|
-
end
|
33
|
+
name = name.to_s
|
49
34
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# assumed to be sorted in ascending order).
|
60
|
-
def find(selector={}, options={})
|
61
|
-
fields = options.delete(:fields)
|
62
|
-
fields = nil if fields && fields.empty?
|
63
|
-
offset = options.delete(:offset) || 0
|
64
|
-
limit = options.delete(:limit) || 0
|
65
|
-
sort = options.delete(:sort)
|
66
|
-
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
|
67
|
-
@db.query(self, Query.new(selector, fields, offset, limit, sort))
|
68
|
-
end
|
35
|
+
if name.empty? or name.include? ".."
|
36
|
+
raise InvalidName, "collection names cannot be empty"
|
37
|
+
end
|
38
|
+
if name.include? "$" and not name.match(/^\$cmd/)
|
39
|
+
raise InvalidName, "collection names must not contain '$'"
|
40
|
+
end
|
41
|
+
if name.match(/^\./) or name.match(/\.$/)
|
42
|
+
raise InvalidName, "collection names must not start or end with '.'"
|
43
|
+
end
|
69
44
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
res = @db.insert_into_db(@name, objects)
|
74
|
-
res.size > 1 ? res : res.first
|
75
|
-
end
|
76
|
-
alias_method :<<, :insert
|
45
|
+
@db, @name = db, name
|
46
|
+
@hint = nil
|
47
|
+
end
|
77
48
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
49
|
+
# Get a sub-collection of this collection by name.
|
50
|
+
#
|
51
|
+
# Raises InvalidName if an invalid collection name is used.
|
52
|
+
#
|
53
|
+
# :name :: the name of the collection to get
|
54
|
+
def [](name)
|
55
|
+
name = "#{self.name}.#{name}"
|
56
|
+
return Collection.new(db, name) if !db.strict? || db.collection_names.include?(name)
|
57
|
+
raise "Collection #{name} doesn't exist. Currently in strict mode."
|
58
|
+
end
|
82
59
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
60
|
+
# Set hint fields to use and return +self+. hint may be a single field
|
61
|
+
# name, array of field names, or a hash (preferably an OrderedHash).
|
62
|
+
# May be +nil+.
|
63
|
+
def hint=(hint)
|
64
|
+
@hint = normalize_hint_fields(hint)
|
65
|
+
self
|
66
|
+
end
|
87
67
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
68
|
+
# Query the database.
|
69
|
+
#
|
70
|
+
# The +selector+ argument is a prototype document that all results must
|
71
|
+
# match. For example:
|
72
|
+
#
|
73
|
+
# collection.find({"hello" => "world"})
|
74
|
+
#
|
75
|
+
# only matches documents that have a key "hello" with value "world".
|
76
|
+
# Matches can have other keys *in addition* to "hello".
|
77
|
+
#
|
78
|
+
# If given an optional block +find+ will yield a Cursor to that block,
|
79
|
+
# close the cursor, and then return nil. This guarantees that partially
|
80
|
+
# evaluated cursors will be closed. If given no block +find+ returns a
|
81
|
+
# cursor.
|
82
|
+
#
|
83
|
+
# :selector :: A document (hash) specifying elements which must be
|
84
|
+
# present for a document to be included in the result set.
|
85
|
+
#
|
86
|
+
# Options:
|
87
|
+
# :fields :: Array of field names that should be returned in the result
|
88
|
+
# set ("_id" will always be included). By limiting results
|
89
|
+
# to a certain subset of fields you can cut down on network
|
90
|
+
# traffic and decoding time.
|
91
|
+
# :skip :: Number of documents to omit (from the start of the result set)
|
92
|
+
# when returning the results
|
93
|
+
# :limit :: Maximum number of records to return
|
94
|
+
# :sort :: Either hash of field names as keys and 1/-1 as values; 1 ==
|
95
|
+
# ascending, -1 == descending, or array of field names (all
|
96
|
+
# assumed to be sorted in ascending order).
|
97
|
+
# :hint :: See #hint. This option overrides the collection-wide value.
|
98
|
+
# :snapshot :: If true, snapshot mode will be used for this query.
|
99
|
+
# Snapshot mode assures no duplicates are returned, or
|
100
|
+
# objects missed, which were preset at both the start and
|
101
|
+
# end of the query's execution. For details see
|
102
|
+
# http://www.mongodb.org/display/DOCS/How+to+do+Snapshotting+in+the+Mongo+Database
|
103
|
+
def find(selector={}, options={})
|
104
|
+
fields = options.delete(:fields)
|
105
|
+
fields = ["_id"] if fields && fields.empty?
|
106
|
+
skip = options.delete(:offset) || nil
|
107
|
+
if !skip.nil?
|
108
|
+
warn "the :offset option to find is deprecated and will be removed. please use :skip instead"
|
109
|
+
end
|
110
|
+
skip = options.delete(:skip) || skip || 0
|
111
|
+
limit = options.delete(:limit) || 0
|
112
|
+
sort = options.delete(:sort)
|
113
|
+
hint = options.delete(:hint)
|
114
|
+
snapshot = options.delete(:snapshot)
|
115
|
+
if hint
|
116
|
+
hint = normalize_hint_fields(hint)
|
117
|
+
else
|
118
|
+
hint = @hint # assumed to be normalized already
|
119
|
+
end
|
120
|
+
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
|
93
121
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
122
|
+
cursor = @db.query(self, Query.new(selector, fields, skip, limit, sort, hint, snapshot))
|
123
|
+
if block_given?
|
124
|
+
yield cursor
|
125
|
+
cursor.close()
|
126
|
+
nil
|
127
|
+
else
|
128
|
+
cursor
|
129
|
+
end
|
130
|
+
end
|
98
131
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
132
|
+
# Get a single object from the database.
|
133
|
+
#
|
134
|
+
# Raises TypeError if the argument is of an improper type. Returns a
|
135
|
+
# single document (hash), or nil if no result is found.
|
136
|
+
#
|
137
|
+
# :spec_or_object_id :: a hash specifying elements which must be
|
138
|
+
# present for a document to be included in the result set OR an
|
139
|
+
# instance of ObjectID to be used as the value for an _id query.
|
140
|
+
# if nil an empty spec, {}, will be used.
|
141
|
+
# :options :: options, as passed to Collection#find
|
142
|
+
def find_one(spec_or_object_id=nil, options={})
|
143
|
+
spec = case spec_or_object_id
|
144
|
+
when nil
|
145
|
+
{}
|
146
|
+
when ObjectID
|
147
|
+
{:_id => spec_or_object_id}
|
148
|
+
when Hash
|
149
|
+
spec_or_object_id
|
150
|
+
else
|
151
|
+
raise TypeError, "spec_or_object_id must be an instance of ObjectID or Hash, or nil"
|
152
|
+
end
|
153
|
+
find(spec, options.merge(:limit => -1)).next_object
|
154
|
+
end
|
106
155
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
156
|
+
# Save a document in this collection.
|
157
|
+
#
|
158
|
+
# If +to_save+ already has an '_id' then an update (upsert) operation
|
159
|
+
# is performed and any existing document with that _id is overwritten.
|
160
|
+
# Otherwise an insert operation is performed. Returns the _id of the
|
161
|
+
# saved document.
|
162
|
+
#
|
163
|
+
# :to_save :: the document (a hash) to be saved
|
164
|
+
#
|
165
|
+
# Options:
|
166
|
+
# :safe :: if true, check that the save succeeded. OperationFailure
|
167
|
+
# will be raised on an error. Checking for safety requires an extra
|
168
|
+
# round-trip to the database
|
169
|
+
def save(to_save, options={})
|
170
|
+
if id = to_save[:_id] || to_save['_id']
|
171
|
+
update({:_id => id}, to_save, :upsert => true, :safe => options.delete(:safe))
|
172
|
+
id
|
173
|
+
else
|
174
|
+
insert(to_save, :safe => options.delete(:safe))
|
175
|
+
end
|
176
|
+
end
|
112
177
|
|
113
|
-
|
114
|
-
|
115
|
-
|
178
|
+
# Insert a document(s) into this collection.
|
179
|
+
#
|
180
|
+
# "<<" is aliased to this method. Returns the _id of the inserted
|
181
|
+
# document or a list of _ids of the inserted documents. The object(s)
|
182
|
+
# may have been modified by the database's PK factory, if it has one.
|
183
|
+
#
|
184
|
+
# :doc_or_docs :: a document (as a hash) or Array of documents to be
|
185
|
+
# inserted
|
186
|
+
#
|
187
|
+
# Options:
|
188
|
+
# :safe :: if true, check that the insert succeeded. OperationFailure
|
189
|
+
# will be raised on an error. Checking for safety requires an extra
|
190
|
+
# round-trip to the database
|
191
|
+
def insert(doc_or_docs, options={})
|
192
|
+
doc_or_docs = [doc_or_docs] if !doc_or_docs.is_a?(Array)
|
193
|
+
res = @db.insert_into_db(@name, doc_or_docs)
|
194
|
+
if options.delete(:safe)
|
195
|
+
error = @db.error
|
196
|
+
if error
|
197
|
+
raise OperationFailure, error
|
116
198
|
end
|
199
|
+
end
|
200
|
+
res.size > 1 ? res : res.first
|
201
|
+
end
|
202
|
+
alias_method :<<, :insert
|
203
|
+
|
204
|
+
# Remove the records that match +selector+.
|
205
|
+
def remove(selector={})
|
206
|
+
@db.remove_from_db(@name, selector)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Remove all records.
|
210
|
+
def clear
|
211
|
+
remove({})
|
212
|
+
end
|
213
|
+
|
214
|
+
# Update a single document in this collection.
|
215
|
+
#
|
216
|
+
# :spec :: a hash specifying elements which must be present for
|
217
|
+
# a document to be updated
|
218
|
+
# :document :: a hash specifying the fields to be changed in the
|
219
|
+
# selected document, or (in the case of an upsert) the document to
|
220
|
+
# be inserted
|
221
|
+
#
|
222
|
+
# Options:
|
223
|
+
# :upsert :: if true, perform an upsert operation
|
224
|
+
# :safe :: if true, check that the update succeeded. OperationFailure
|
225
|
+
# will be raised on an error. Checking for safety requires an extra
|
226
|
+
# round-trip to the database
|
227
|
+
def update(spec, document, options={})
|
228
|
+
upsert = options.delete(:upsert)
|
229
|
+
safe = options.delete(:safe)
|
117
230
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
231
|
+
if upsert
|
232
|
+
@db.repsert_in_db(@name, spec, document)
|
233
|
+
else
|
234
|
+
@db.replace_in_db(@name, spec, document)
|
235
|
+
end
|
236
|
+
if safe
|
237
|
+
error = @db.error
|
238
|
+
if error
|
239
|
+
raise OperationFailure, error
|
122
240
|
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Create a new index. +field_or_spec+
|
245
|
+
# should be either a single field name or a Array of [field name,
|
246
|
+
# direction] pairs. Directions should be specified as
|
247
|
+
# Mongo::ASCENDING or Mongo::DESCENDING.
|
248
|
+
# +unique+ is an optional boolean indicating whether this index
|
249
|
+
# should enforce a uniqueness constraint.
|
250
|
+
def create_index(field_or_spec, unique=false)
|
251
|
+
@db.create_index(@name, field_or_spec, unique)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Drop index +name+.
|
255
|
+
def drop_index(name)
|
256
|
+
@db.drop_index(@name, name)
|
257
|
+
end
|
258
|
+
|
259
|
+
# Drop all indexes.
|
260
|
+
def drop_indexes
|
261
|
+
# just need to call drop indexes with no args; will drop them all
|
262
|
+
@db.drop_index(@name, '*')
|
263
|
+
end
|
264
|
+
|
265
|
+
# Drop the entire collection. USE WITH CAUTION.
|
266
|
+
def drop
|
267
|
+
@db.drop_collection(@name)
|
268
|
+
end
|
123
269
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
270
|
+
# Perform a query similar to an SQL group by operation.
|
271
|
+
#
|
272
|
+
# Returns an array of grouped items.
|
273
|
+
#
|
274
|
+
# :keys :: Array of fields to group by
|
275
|
+
# :condition :: specification of rows to be considered (as a 'find'
|
276
|
+
# query specification)
|
277
|
+
# :initial :: initial value of the aggregation counter object
|
278
|
+
# :reduce :: aggregation function as a JavaScript string
|
279
|
+
# :command :: if true, run the group as a command instead of in an
|
280
|
+
# eval - it is likely that this option will eventually be
|
281
|
+
# deprecated and all groups will be run as commands
|
282
|
+
def group(keys, condition, initial, reduce, command=false)
|
283
|
+
if command
|
284
|
+
hash = {}
|
285
|
+
keys.each do |k|
|
286
|
+
hash[k] = 1
|
134
287
|
end
|
135
288
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
@db.collections_info(@name).next_object()['options']
|
289
|
+
case reduce
|
290
|
+
when Code
|
291
|
+
else
|
292
|
+
reduce = Code.new(reduce)
|
141
293
|
end
|
142
294
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
295
|
+
result = @db.db_command({"group" =>
|
296
|
+
{
|
297
|
+
"ns" => @name,
|
298
|
+
"$reduce" => reduce,
|
299
|
+
"key" => hash,
|
300
|
+
"cond" => condition,
|
301
|
+
"initial" => initial}})
|
302
|
+
if result["ok"] == 1
|
303
|
+
return result["retval"]
|
304
|
+
else
|
305
|
+
raise OperationFailure, "group command failed: #{result['errmsg']}"
|
147
306
|
end
|
307
|
+
end
|
148
308
|
|
309
|
+
case reduce
|
310
|
+
when Code
|
311
|
+
scope = reduce.scope
|
312
|
+
else
|
313
|
+
scope = {}
|
314
|
+
end
|
315
|
+
scope.merge!({
|
316
|
+
"ns" => @name,
|
317
|
+
"keys" => keys,
|
318
|
+
"condition" => condition,
|
319
|
+
"initial" => initial })
|
320
|
+
|
321
|
+
group_function = <<EOS
|
322
|
+
function () {
|
323
|
+
var c = db[ns].find(condition);
|
324
|
+
var map = new Map();
|
325
|
+
var reduce_function = #{reduce};
|
326
|
+
while (c.hasNext()) {
|
327
|
+
var obj = c.next();
|
328
|
+
|
329
|
+
var key = {};
|
330
|
+
for (var i = 0; i < keys.length; i++) {
|
331
|
+
var k = keys[i];
|
332
|
+
key[k] = obj[k];
|
333
|
+
}
|
334
|
+
|
335
|
+
var aggObj = map.get(key);
|
336
|
+
if (aggObj == null) {
|
337
|
+
var newObj = Object.extend({}, key);
|
338
|
+
aggObj = Object.extend(newObj, initial);
|
339
|
+
map.put(key, aggObj);
|
340
|
+
}
|
341
|
+
reduce_function(obj, aggObj);
|
342
|
+
}
|
343
|
+
return {"result": map.values()};
|
344
|
+
}
|
345
|
+
EOS
|
346
|
+
return @db.eval(Code.new(group_function, scope))["result"]
|
347
|
+
end
|
348
|
+
|
349
|
+
# Rename this collection.
|
350
|
+
#
|
351
|
+
# If operating in auth mode, client must be authorized as an admin to
|
352
|
+
# perform this operation. Raises +InvalidName+ if +new_name+ is an invalid
|
353
|
+
# collection name.
|
354
|
+
#
|
355
|
+
# :new_name :: new name for this collection
|
356
|
+
def rename(new_name)
|
357
|
+
case new_name
|
358
|
+
when Symbol, String
|
359
|
+
else
|
360
|
+
raise TypeError, "new_name must be a string or symbol"
|
361
|
+
end
|
362
|
+
|
363
|
+
new_name = new_name.to_s
|
364
|
+
|
365
|
+
if new_name.empty? or new_name.include? ".."
|
366
|
+
raise InvalidName, "collection names cannot be empty"
|
367
|
+
end
|
368
|
+
if new_name.include? "$"
|
369
|
+
raise InvalidName, "collection names must not contain '$'"
|
370
|
+
end
|
371
|
+
if new_name.match(/^\./) or new_name.match(/\.$/)
|
372
|
+
raise InvalidName, "collection names must not start or end with '.'"
|
373
|
+
end
|
374
|
+
|
375
|
+
@db.rename_collection(@name, new_name)
|
376
|
+
end
|
377
|
+
|
378
|
+
# Get information on the indexes for the collection +collection_name+.
|
379
|
+
# Returns a hash where the keys are index names (as returned by
|
380
|
+
# Collection#create_index and the values are lists of [key, direction]
|
381
|
+
# pairs specifying the index (as passed to Collection#create_index).
|
382
|
+
def index_information
|
383
|
+
@db.index_information(@name)
|
384
|
+
end
|
385
|
+
|
386
|
+
# Return a hash containing options that apply to this collection.
|
387
|
+
# 'create' will be the collection name. For the other possible keys
|
388
|
+
# and values, see DB#create_collection.
|
389
|
+
def options
|
390
|
+
@db.collections_info(@name).next_object()['options']
|
391
|
+
end
|
392
|
+
|
393
|
+
# Get the number of documents in this collection.
|
394
|
+
def count()
|
395
|
+
find().count()
|
396
|
+
end
|
397
|
+
|
398
|
+
protected
|
399
|
+
|
400
|
+
def normalize_hint_fields(hint)
|
401
|
+
case hint
|
402
|
+
when String
|
403
|
+
{hint => 1}
|
404
|
+
when Hash
|
405
|
+
hint
|
406
|
+
when nil
|
407
|
+
nil
|
408
|
+
else
|
409
|
+
h = OrderedHash.new
|
410
|
+
hint.to_a.each { |k| h[k] = 1 }
|
411
|
+
h
|
149
412
|
end
|
150
413
|
end
|
151
414
|
end
|
152
415
|
end
|
153
|
-
|