Permalink
Browse files

Merge remote branch 'simplyjt/master'

  • Loading branch information...
2 parents 01e95e0 + 6ad1462 commit 98bd2bcd2b79a4c69b7b123c9aa2dab3671c368d @kristianmandrup committed Mar 17, 2010
View
54 README.rdoc
@@ -1,3 +1,57 @@
+== Sequence plugin
+
+This will enable one to use SQL-like sequence for id (_id).
+
+Just do
+
+ include MongoMapper::Document
+ include UseSequenceAsMongoId
+
+== Strict Keys
+
+When you do
+
+ Foo.create(:explicit_key => 'bar', :implicity_key => 'cake')
+
+even when :implicity_key was not definied (i.e. key :implicity_key, String), MongoMapper will still create the new key and insert the document.
+
+If you want to disable that for mantainability, do
+
+ include SaveToMongoKeysOnly
+ include MongoMapper::Document
+
+== Embedded documents without id (_id)
+
+Sometimes there's no reason to use id for embedded documents. Just do
+
+ include NoEmbeddedMongoId
+ include MongoMapper::EmbeddedDocument
+
+== Operator 'e'
+
+When you do
+
+ Foo.all(:array => [1,2])
+
+what you get is actually
+
+ Foo.all(:array.in => [1,2])
+
+which is fine in most case, but sometimes you just want to match the exact array (as in spatial data). Now you can do
+
+ Foo.all(:array.e => [1,2])
+
+which guarantees no operator will be used.
+
+== Disclaimer for the new features
+
+All the old tests pass. But I still need to write tests for the new features.
+
+== How to use spatial index
+
+ key :lat_lng, Array # or use embedded document type
+ ensure_index [[:lat_lng, "2d"]]
+
= MongoMapper
A Ruby Object Mapper for Mongo.
View
4 lib/mongo_mapper/plugins.rb
@@ -32,3 +32,7 @@ def plugin(mod)
require 'mongo_mapper/plugins/associations'
require 'mongo_mapper/plugins/pagination'
+require 'mongo_mapper/plugins/sequence/sequence'
+require 'mongo_mapper/plugins/sequence/use_sequence_as_mongo_id'
+require 'mongo_mapper/plugins/before_flags/no_embedded_mongo_id'
+require 'mongo_mapper/plugins/before_flags/save_to_mongo_keys_only'
View
10 lib/mongo_mapper/plugins/before_flags/no_embedded_mongo_id.rb
@@ -0,0 +1,10 @@
+module NoEmbeddedMongoId
+ def self.included(base)
+ base.extend ClassMethods
+ end
+ module ClassMethods
+ def no_embedded_mongo_id
+ true
+ end
+ end
+end
View
10 lib/mongo_mapper/plugins/before_flags/save_to_mongo_keys_only.rb
@@ -0,0 +1,10 @@
+module SaveToMongoKeysOnly
+ def self.included(base)
+ base.extend ClassMethods
+ end
+ module ClassMethods
+ def save_to_mongo_keys_only
+ true
+ end
+ end
+end
View
27 lib/mongo_mapper/plugins/keys.rb
@@ -2,7 +2,7 @@ module MongoMapper
module Plugins
module Keys
def self.configure(model)
- model.key :_id, ObjectId
+ model.key :_id, ObjectId unless model.respond_to?(:no_embedded_mongo_id)
end
module ClassMethods
@@ -148,8 +148,8 @@ module InstanceMethods
def initialize(attrs={}, from_database=false)
unless attrs.nil?
provided_keys = attrs.keys.map { |k| k.to_s }
- unless provided_keys.include?('_id') || provided_keys.include?('id')
- write_key :_id, Mongo::ObjectID.new
+ unless self.class.respond_to?(:no_embedded_mongo_id) || provided_keys.include?('_id') || provided_keys.include?('id')
+ write_key :_id, self.class.respond_to?(:next_mongo_id) ? self.class.next_mongo_id : Mongo::ObjectID.new
end
end
@@ -168,6 +168,25 @@ def new?
@new
end
+ def old?
+ !@new
+ end
+
+ def set_attributes(hash, *key_white_list)
+ key_white_list.each do |k|
+ str = "#{k}="
+ if respond_to?(str)
+ if hash.has_key?(k)
+ send(str, hash[k])
+ else
+ raise(ArgumentError, "#{hash.inspect} has no key: #{k}")
+ end
+ else
+ raise(ArgumentError, "Instance of #{self.class} class does not respond to method: #{str}")
+ end
+ end
+ end
+
def attributes=(attrs)
return if attrs.blank?
@@ -234,7 +253,7 @@ def [](name)
end
def []=(name, value)
- ensure_key_exists(name)
+ ensure_key_exists(name) unless self.class.respond_to?(:save_to_mongo_keys_only)
write_key(name, value)
end
View
10 lib/mongo_mapper/plugins/sequence/sequence.rb
@@ -0,0 +1,10 @@
+class Sequence
+ include MongoMapper::Document
+
+ key :_id, String
+ key :v, Integer, :default => 0
+
+ def self.next_id(id)
+ database.command(OrderedHash['findandmodify', 'sequences', 'query', id, 'update', {'$inc' => {'v' => 1}}, 'new', true])['value']['v']
+ end
+end
View
14 lib/mongo_mapper/plugins/sequence/use_sequence_as_mongo_id.rb
@@ -0,0 +1,14 @@
+module UseSequenceAsMongoId
+ def self.included(base)
+ base.extend ClassMethods
+ base.class_eval do
+ Sequence.create(:id => base.to_s) if Sequence.first(:id => base.to_s).nil?
+ key :_id, Integer
+ end
+ end
+ module ClassMethods
+ def next_mongo_id
+ Sequence.next_id(self.to_s)
+ end
+ end
+end
View
4 lib/mongo_mapper/query.rb
@@ -56,7 +56,7 @@ def modifier?(field)
end
def symbol_operator?(object)
- object.respond_to?(:field, :operator)
+ object.respond_to?(:field, :operator) and object.operator != 'e'
end
def to_criteria(conditions, parent_key=nil)
@@ -127,4 +127,4 @@ def normalized_sort(sort)
end
end
end
-end
+end
View
2 lib/mongo_mapper/support.rb
@@ -172,7 +172,7 @@ def initialize(field, operator, options={})
end
class Symbol
- %w(gt lt gte lte ne in nin mod all size where exists asc desc).each do |operator|
+ %w(e inc set unset near gt lt gte lte ne in nin mod all size where exists asc desc).each do |operator|
define_method(operator) do
SymbolOperator.new(self, operator)
end unless method_defined?(operator)

0 comments on commit 98bd2bc

Please sign in to comment.