diff --git a/examples/info.rb b/examples/info.rb index a727bfb..c6a986e 100644 --- a/examples/info.rb +++ b/examples/info.rb @@ -23,7 +23,7 @@ p db.collection_names p db.collections_info # Index information -db.create_index('test', 'index_name', ['a']) +db.create_index('test', 'a') p db.index_information('test') # Destroy the collection diff --git a/examples/queries.rb b/examples/queries.rb index ecdfcfe..06eb5cf 100644 --- a/examples/queries.rb +++ b/examples/queries.rb @@ -59,7 +59,7 @@ pp coll.find('a' => /[1|2]/).explain() # collection, in which case they will be used with all queries, or they can be # specified per query, in which case that hint overrides the hint associated # with the collection if any. -coll.create_index('test_a_index', 'a') +coll.create_index('a') coll.hint = 'a' # You will see a different explanation now that the hint is in place diff --git a/lib/mongo.rb b/lib/mongo.rb index 35bf938..6bf1356 100644 --- a/lib/mongo.rb +++ b/lib/mongo.rb @@ -10,3 +10,10 @@ require 'mongo/db' require 'mongo/cursor' require 'mongo/collection' require 'mongo/admin' + +module XGen + module Mongo + ASCENDING = 1 + DESCENDING = -1 + end +end diff --git a/lib/mongo/collection.rb b/lib/mongo/collection.rb index af1c90f..3d741fa 100644 --- a/lib/mongo/collection.rb +++ b/lib/mongo/collection.rb @@ -70,7 +70,7 @@ module XGen h = options.dup h[:limit] = 1 cursor = find(selector, h) - cursor.next_object # don't need to explicitly close b/c of limit + cursor.next_object # don't need to explicitly close b/c of limit end # Insert +objects+, which are hashes. "<<" is aliased to this method. @@ -113,11 +113,12 @@ module XGen @db.modify_in_db(@name, selector, modifier_obj) end - # Create a new index named +index_name+. +fields+ should be an array - # of field names. - def create_index(name, *fields) - fields = *fields if fields.kind_of?(Array) && fields.length == 1 - @db.create_index(@name, name, fields) + # Create a new index. +field_or_spec+ + # should be either a single field name or a Array of [field name, + # direction] pairs. Directions should be specified as + # XGen::Mongo::ASCENDING or XGen::Mongo::DESCENDING. + def create_index(field_or_spec) + @db.create_index(@name, field_or_spec) end # Drop index +name+. diff --git a/lib/mongo/db.rb b/lib/mongo/db.rb index ba4d13d..6fa7329 100644 --- a/lib/mongo/db.rb +++ b/lib/mongo/db.rb @@ -305,7 +305,7 @@ module XGen def send_message(msg) send_to_db(MsgMessage.new(msg)) end - + # Returns a Cursor over the query results. # # Note that the query gets sent lazily; the cursor calls @@ -401,17 +401,28 @@ module XGen } end - # Create a new index on +collection_name+ named +index_name+. +fields+ - # should be an array of field names. Normally called by - # Collection#create_index. - def create_index(collection_name, index_name, fields) - sel = {:name => index_name, :ns => full_coll_name(collection_name)} - field_h = {} - fields.each { |f| field_h[f] = 1 } - sel[:key] = field_h + # Create a new index on +collection_name+. +field_or_spec+ + # should be either a single field name or a Array of [field name, + # direction] pairs. Directions should be specified as + # XGen::Mongo::ASCENDING or XGen::Mongo::DESCENDING. Normally called + # by Collection#create_index. + def create_index(collection_name, field_or_spec) + field_h = OrderedHash.new + if field_or_spec.is_a? String + field_h[field_or_spec] = 1 + else + field_or_spec.each { |f| field_h[f[0]] = f[1] } + end + name = gen_index_name(field_h) + sel = { + :name => name, + :ns => full_coll_name(collection_name), + :key => field_h + } @semaphore.synchronize { send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, sel)) } + name end # Insert +objects+ into +collection_name+. Normally called by @@ -471,6 +482,13 @@ module XGen Digest::MD5.hexdigest("#{username}:mongo:#{plaintext}") end + def gen_index_name(spec) + temp = [] + spec.each_pair { |field, direction| + temp = temp.push("#{field}_#{direction}") + } + return temp.join("_") + end end end end diff --git a/lib/mongo/gridfs/grid_store.rb b/lib/mongo/gridfs/grid_store.rb index e4958a1..75a3673 100644 --- a/lib/mongo/gridfs/grid_store.rb +++ b/lib/mongo/gridfs/grid_store.rb @@ -157,7 +157,7 @@ module XGen @curr_chunk = nth_chunk(0) @position = 0 when 'w' - chunk_collection.create_index("chunk_index", ['files_id', 'n']) + chunk_collection.create_index([['files_id', XGen::Mongo::ASCENDING], ['n', XGen::Mongo::ASCENDING]]) delete_chunks @curr_chunk = Chunk.new(self, 'n' => 0) @content_type = options[:content_type] if options[:content_type] @@ -165,7 +165,7 @@ module XGen @metadata = options[:metadata] if options[:metadata] @position = 0 when 'w+' - chunk_collection.create_index("chunk_index", ['files_id', 'n']) + chunk_collection.create_index([['files_id', XGen::Mongo::ASCENDING], ['n', XGen::Mongo::ASCENDING]]) @curr_chunk = nth_chunk(last_chunk_number) || Chunk.new(self, 'n' => 0) # might be empty @curr_chunk.pos = @curr_chunk.data.length if @curr_chunk @metadata = options[:metadata] if options[:metadata] diff --git a/tests/test_db_api.rb b/tests/test_db_api.rb index 545b7fd..0231b45 100644 --- a/tests/test_db_api.rb +++ b/tests/test_db_api.rb @@ -4,7 +4,7 @@ require 'test/unit' # NOTE: assumes Mongo is running class DBAPITest < Test::Unit::TestCase - + include XGen::Mongo include XGen::Mongo::Driver @@db = Mongo.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', @@ -275,28 +275,30 @@ class DBAPITest < Test::Unit::TestCase end def test_index_information - @@db.create_index(@@coll.name, 'index_name', ['a']) + name = @@db.create_index(@@coll.name, 'a') list = @@db.index_information(@@coll.name) assert_equal 1, list.length info = list[0] - assert_equal 'index_name', info[:name] + assert_equal name, 'a_1' + assert_equal name, info[:name] assert_equal 1, info[:keys]['a'] ensure - @@db.drop_index(@@coll.name, 'index_name') + @@db.drop_index(@@coll.name, name) end def test_multiple_index_cols - @@db.create_index(@@coll.name, 'index_name', ['a', 'b', 'c']) + name = @@db.create_index(@@coll.name, [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]]) list = @@db.index_information(@@coll.name) assert_equal 1, list.length info = list[0] - assert_equal 'index_name', info[:name] + assert_equal name, 'a_-1_b_1_c_-1' + assert_equal name, info[:name] keys = info[:keys].keys assert_equal ['a', 'b', 'c'], keys.sort ensure - @@db.drop_index(@@coll.name, 'index_name') + @@db.drop_index(@@coll.name, name) end def test_array @@ -403,7 +405,7 @@ class DBAPITest < Test::Unit::TestCase end def test_hint - @@coll.create_index('test_a_index', 'a') + name = @@coll.create_index('a') begin assert_nil @@coll.hint assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size @@ -426,7 +428,7 @@ class DBAPITest < Test::Unit::TestCase assert_nil @@coll.hint assert_equal 1, @@coll.find('a' => 1).to_a.size ensure - @@coll.drop_index('test_a_index') + @@coll.drop_index(name) end end