Permalink
Browse files

Add some collection management and improve sort

  • Loading branch information...
1 parent 4e41933 commit c1b91bf14728b88c65e57e0b1b2a95916764d734 @gdb committed Jul 11, 2011
Showing with 58 additions and 6 deletions.
  1. +35 −5 lib/embedded-mongo/backend/collection.rb
  2. +14 −1 lib/embedded-mongo/backend/db.rb
  3. +9 −0 lib/embedded-mongo/db.rb
@@ -4,10 +4,15 @@ class DuplicateKeyError < StandardError; end
def initialize(db, name)
# TODO: system.namespaces
- raise ArgumentError.new("Invalid collection name #{name.inspect}") if name['.'] or name['$']
@db = db
@name = name
@data = []
+
+ if name == 'system.namespaces'
+ # mark as system?
+ elsif name['.'] or name['$']
+ raise ArgumentError.new("Invalid collection name #{name.inspect}")
+ end
end
def insert_documents(documents)
@@ -21,7 +26,7 @@ def find(selector, opts)
raise ArgumentError.new("Unrecognized opts: #{opts.inspect}") unless opts.empty?
results = []
- @data.each do |doc|
+ data.each do |doc|
if selector_match?(selector, doc)
results << doc
break if limit > 0 and results.length >= limit
@@ -30,7 +35,14 @@ def find(selector, opts)
EmbeddedMongo.log.info("Query has #{results.length} matches")
if sort
- sort = [sort] unless sort.first.kind_of?(Array)
+ case sort
+ when String
+ sort = [[sort]]
+ when Array
+ sort = [sort] unless sort.first.kind_of?(Array)
+ else
+ raise Mongo::InvalidSortValueError.new("invalid sort type: #{sort.inspect}")
+ end
results.sort! { |x, y| sort_cmp(sort, x, y) }
end
results
@@ -67,6 +79,14 @@ def remove(selector={}, opts={})
private
+ def data
+ if @name == 'system.namespaces'
+ @db.collections.keys.map { |name| { 'name' => "#{@db.name}.#{name}" } }
+ else
+ @data
+ end
+ end
+
def check_id(doc)
id = doc['_id']
raise NotImplementedError.new("#{doc.inspect} has no '_id' attribute") unless id
@@ -90,10 +110,20 @@ def insert(doc)
end
def sort_cmp(sort, x, y)
- sort.each do |field, direction|
+ sort.each do |spec|
+ case spec
+ when String
+ field = spec
+ direction = nil
+ when Array
+ field, direction = spec
+ else
+ raise Mongo::InvalidSortValueError.new("invalid sort directive: #{spec.inspect}")
+ end
+
x_val = x[field.to_s]
y_val = y[field.to_s]
- if direction.to_s == 'ascending' or direction.to_s == 'asc' or (direction.kind_of?(Numeric) and direction > 0)
+ if direction.to_s == 'ascending' or direction.to_s == 'asc' or (direction.kind_of?(Numeric) and direction > 0) or direction.nil?
if x_val.kind_of?(Numeric) and y_val.kind_of?(Numeric)
cmp = x_val <=> y_val
elsif x_val.kind_of?(Numeric)
@@ -1,5 +1,7 @@
module EmbeddedMongo::Backend
class DB
+ attr_reader :collections, :name
+
def initialize(manager, name)
raise ArgumentError.new("Invalid collection name #{name.inspect}") if name['.'] or name['$']
@manager = manager
@@ -16,11 +18,21 @@ def run_command(cmd)
'dropped' => @name,
'ok' => 1.0
}]
+ elsif collection_name = cmd['drop']
+ @collections.delete(collection_name)
+ [{
+ 'ok' => 1.0
+ }]
+ elsif collection_name = cmd['create']
+ get_collection(collection_name)
+ [{
+ 'ok' => 1.0
+ }]
elsif cmd['buildinfo']
raise "Command #{cmd.inspect} only allowed for admin database" unless @name == 'admin'
# {"version"=>"1.6.3", "gitVersion"=>"nogitversion", "sysInfo"=>"Linux allspice 2.6.24-28-server #1 SMP Wed Aug 18 21:17:51 UTC 2010 x86_64 BOOST_LIB_VERSION=1_42", "bits"=>64, "debug"=>false, "ok"=>1.0}
[{
- 'version' => '0.0.1',
+ 'version' => '1.8.0', # sure, this seems like a good version (must exceed 1.1.3)
'gitVersion' => 'nogitversion',
'sysInfo' => 'fake sysinfo',
'bits' => 64,
@@ -44,6 +56,7 @@ def set_last_error(opts)
}.merge(opts)
end
+ # TODO: don't think we always create a collection
def get_collection(collection_name)
@collections[collection_name] ||= Collection.new(self, collection_name)
end
View
@@ -1,5 +1,14 @@
module EmbeddedMongo
class DB < Mongo::DB
+ # verbatim
+ def rename_collection(from, to)
+ oh = BSON::OrderedHash.new
+ oh[:renameCollection] = "#{@name}.#{from}"
+ oh[:to] = "#{@name}.#{to}"
+ doc = DB.new('admin', @connection).command(oh, :check_response => false)
+ ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
+ end
+
# mostly verbatim
def command(selector, opts={})
check_response = opts.fetch(:check_response, true)

0 comments on commit c1b91bf

Please sign in to comment.