mongo 0.1.0 → 0.15
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 +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
|
-
|