jmongo 1.1.1 → 1.1.2

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/Rakefile CHANGED
@@ -36,6 +36,10 @@ def replace_header(head, header_name)
36
36
  head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
37
37
  end
38
38
 
39
+ def jruby?
40
+ RUBY_PLATFORM.to_s == 'java'
41
+ end
42
+
39
43
  #############################################################################
40
44
  #
41
45
  # Custom tasks
@@ -65,7 +69,16 @@ task :release => :build do
65
69
  sh "git tag v#{version}"
66
70
  sh "git push origin master"
67
71
  sh "git push origin v#{version}"
68
- sh "gem push pkg/#{name}-#{version}.gem"
72
+
73
+ command = "gem push pkg/#{name}-#{version}.gem"
74
+
75
+ if jruby?
76
+ puts "--------------------------------------------------------------------------------------"
77
+ puts "can't push to rubygems using jruby at the moment, so switch to mri and run: #{command}"
78
+ puts "--------------------------------------------------------------------------------------"
79
+ else
80
+ sh command
81
+ end
69
82
  end
70
83
 
71
84
  desc "Build #{gem_file} into the pkg directory"
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jmongo'
3
- s.version = '1.1.1'
4
- s.date = '2011-10-06'
3
+ s.version = '1.1.2'
4
+ s.date = '2011-10-10'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Chuck Remes","Guy Boertje", "Lee Henson"]
7
7
  s.email = ["cremes@mac.com", "guyboertje@gmail.com", "lee.m.henson@gmail.com"]
@@ -19,7 +19,7 @@ module Mongo
19
19
  include Mongo::JavaImpl::Collection_
20
20
 
21
21
  attr_reader :j_collection, :j_db
22
- attr_reader :db, :name, :pk_factory, :hint
22
+ attr_reader :db, :name, :pk_factory
23
23
 
24
24
  # Initialize a collection object.
25
25
  #
@@ -57,9 +57,13 @@ module Mongo
57
57
  @name = validate_name(name)
58
58
  @db, @j_db = db, db.j_db
59
59
  @connection = @db.connection
60
- @pk_factory = @opts[:pk] || BSON::ObjectId
60
+ @pk_factory = @opts.delete(:pk)|| BSON::ObjectId
61
61
  @hint = nil
62
- @j_collection = j_collection || @j_db.get_collection(@name)
62
+ @j_collection = j_collection || @j_db.create_collection(@name, to_dbobject(@opts))
63
+ end
64
+
65
+ def safe
66
+ !!@opts.fetch(:safe, false)
63
67
  end
64
68
 
65
69
  # Return a sub-collection of this collection by name. If 'users' is a collection, then
@@ -75,13 +79,13 @@ module Mongo
75
79
  # the specified sub-collection
76
80
  def [](name)
77
81
  new_name = "#{self.name}.#{name}"
78
- validate_name new_name
79
- @db.create_collection(new_name, @opts)
82
+ @db.collection(new_name, @opts)
80
83
  end
81
84
 
82
85
  def capped?
83
- @j_collection.isCapped
86
+ @j_collection.capped?
84
87
  end
88
+
85
89
  # Set a hint field for query optimizer. Hint may be a single field
86
90
  # name, array of field names, or a hash (preferably an [OrderedHash]).
87
91
  # If using MongoDB > 1.1, you probably don't ever need to set a hint.
@@ -89,8 +93,13 @@ module Mongo
89
93
  # @param [String, Array, OrderedHash] hint a single field, an array of
90
94
  # fields, or a hash specifying fields
91
95
  def hint=(hint=nil)
96
+ @hint = prep_hint(hint)
97
+ self
92
98
  end
93
99
 
100
+ def hint
101
+ @hint
102
+ end
94
103
  # Query the database.
95
104
  #
96
105
  # The +selector+ argument is a prototype document that all results must
@@ -152,7 +161,7 @@ module Mongo
152
161
  end
153
162
 
154
163
  if hint
155
- hint = normalize_hint_fields(hint)
164
+ hint = prep_hint(hint)
156
165
  else
157
166
  hint = @hint # assumed to be normalized already
158
167
  end
@@ -239,9 +248,13 @@ module Mongo
239
248
  # @core insert insert-instance_method
240
249
  def insert(doc_or_docs, options={})
241
250
  doc_or_docs = [doc_or_docs] unless doc_or_docs.kind_of?(Array)
242
- doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
251
+ doc_or_docs.collect! do |doc|
252
+ @pk_factory.create_pk(doc)
253
+ prep_id(doc)
254
+ end
255
+ safe = options.fetch(:safe, @opts[:safe])
243
256
  continue = (options[:continue_on_error] || false)
244
- docs = insert_documents(doc_or_docs, options[:safe], continue)
257
+ docs = insert_documents(doc_or_docs, safe, continue)
245
258
  docs.size == 1 ? docs.first['_id'] : docs.collect{|doc| doc['_id']}
246
259
  end
247
260
  alias_method :<<, :insert
@@ -293,7 +306,8 @@ module Mongo
293
306
  # @core update update-instance_method
294
307
  def update(selector, document, options={})
295
308
  upsert, multi = !!(options[:upsert]), !!(options[:multi])
296
- update_documents(selector, document, upsert, multi, options[:safe])
309
+ safe = options.fetch(:safe, @opts[:safe])
310
+ update_documents(selector, document, upsert, multi, safe)
297
311
  end
298
312
 
299
313
  # Create a new index.
@@ -339,10 +353,13 @@ module Mongo
339
353
  #
340
354
  # @core indexes create_index-instance_method
341
355
  def create_index(spec, opts={})
342
- _create_indexes(spec, opts)
356
+ _create_index(spec, opts)
343
357
  end
344
- alias_method :ensure_index, :create_index
345
358
 
359
+ def ensure_index(spec, opts={})
360
+ _ensure_index(spec, opts)
361
+ end
362
+
346
363
  # Drop a specified index.
347
364
  #
348
365
  # @param [String, Array] spec
@@ -583,10 +600,10 @@ module Mongo
583
600
  #
584
601
  # @raise [Mongo::InvalidNSName] if +new_name+ is an invalid collection name.
585
602
  def rename(new_name)
586
- name = validate_name(new_name)
603
+ _name = validate_name(new_name)
587
604
  begin
588
- jcol = @j_collection.rename(name)
589
- @name = name
605
+ jcol = @j_collection.rename(_name)
606
+ @name = _name
590
607
  @j_collection = jcol
591
608
  rescue => ex
592
609
  raise MongoDBError, "Error renaming collection: #{name}, more: #{ex.message}"
@@ -608,7 +625,6 @@ module Mongo
608
625
  # @return [Hash] options that apply to this collection.
609
626
  def options
610
627
  info = @db.collections_info(@name).to_a
611
- ap info
612
628
  info.last['options']
613
629
  end
614
630
 
@@ -632,39 +648,5 @@ module Mongo
632
648
  end
633
649
 
634
650
  alias :size :count
635
-
636
- protected
637
-
638
- def validate_name(new_name)
639
- raise TypeError, "new_name must be a string like" unless new_name.respond_to?(:to_s)
640
-
641
- name = new_name.to_s
642
-
643
- if name.empty? || name.include?("..")
644
- raise Mongo::InvalidNSName, "collection names cannot be empty"
645
- end
646
- if name.include? "$"
647
- raise Mongo::InvalidNSName, "collection names must not contain '$'" unless name =~ /((^\$cmd)|(oplog\.\$main))/
648
- end
649
- if name.match(/^\./) || name.match(/\.$/)
650
- raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
651
- end
652
- name
653
- end
654
-
655
- def normalize_hint_fields(hint)
656
- case hint
657
- when String
658
- {hint => 1}
659
- when Hash
660
- hint
661
- when nil
662
- nil
663
- else
664
- h = BSON::OrderedHash.new
665
- hint.to_a.each { |k| h[k.to_s] = 1 }
666
- h
667
- end
668
- end
669
651
  end
670
652
  end
@@ -20,28 +20,40 @@ module Mongo
20
20
  include Mongo::JavaImpl::Connection_::InstanceMethods
21
21
  extend Mongo::JavaImpl::Connection_::ClassMethods
22
22
 
23
- attr_reader :connection, :connector, :logger, :auths, :primary
23
+ attr_reader :connection, :connector, :logger, :auths, :primary, :write_concern
24
24
 
25
25
  DEFAULT_PORT = 27017
26
26
 
27
27
  def initialize host = nil, port = nil, opts = {}
28
+ @logger = opts.delete(:logger)
29
+ @auths = opts.delete(:auths) || []
28
30
  if opts.has_key?(:new_from_uri)
29
- @options = opts
30
31
  @mongo_uri = opts[:new_from_uri]
32
+ @options = @mongo_uri.options
33
+ @write_concern = @options.write_concern
31
34
  @connection = JMongo::Mongo.new(@mongo_uri)
32
35
  else
33
- @logger = opts[:logger]
34
36
  @host = host || 'localhost'
35
37
  @port = port || 27017
36
38
  @server_address = JMongo::ServerAddress.new @host, @port
37
39
  @options = JMongo::MongoOptions.new
38
- @options.connectionsPerHost = opts[:pool_size] || 1
39
- @options.socketTimeout = opts[:timeout].to_i * 1000 || 5000
40
+ opts.each do |k,v|
41
+ key = k.to_sym
42
+ jmo_key = JMongo.options_ruby2java_lu(key)
43
+ case jmo_key
44
+ when :safe
45
+ @write_concern = DB.write_concern(v)
46
+ @options.w = @write_concern.w
47
+ @options.wtimeout = @write_concern.wtimeout
48
+ @options.fsync = @write_concern.fsync
49
+ else
50
+ jmo_val = JMongo.options_ruby2java_xf(key, v)
51
+ @options.send("#{jmo_key}=", jmo_val)
52
+ end
53
+ end
40
54
  @connection = JMongo::Mongo.new(@server_address, @options)
41
55
  end
42
56
  @connector = @connection.connector
43
- @logger = opts[:logger]
44
- @auths = opts.fetch(:auths, [])
45
57
  add = @connector.address
46
58
  @primary = [add.host, add.port]
47
59
  end
@@ -124,7 +136,10 @@ module Mongo
124
136
  #
125
137
  # @return [Hash]
126
138
  def database_info
127
- raise_not_implemented
139
+ doc = self['admin'].command({:listDatabases => 1})
140
+ doc['databases'].each_with_object({}) do |db, info|
141
+ info[db['name']] = db['sizeOnDisk'].to_i
142
+ end
128
143
  end
129
144
 
130
145
  # Return an array of database names.
@@ -143,7 +158,7 @@ module Mongo
143
158
  #
144
159
  # @core databases db-instance_method
145
160
  def db(db_name, options={})
146
- DB.new db_name, self, options
161
+ DB.new db_name, self, options
147
162
  end
148
163
 
149
164
  # Shortcut for returning a database. Use DB#db to accept options.
@@ -18,19 +18,30 @@ module Mongo
18
18
  include Mongo::JavaImpl::Db_
19
19
  include Mongo::JavaImpl::Utils
20
20
 
21
- attr_reader :j_db
22
- attr_reader :name
23
- attr_reader :connection
21
+ attr_reader :j_db, :name, :connection, :safe
24
22
 
25
- attr_writer :strict
23
+ attr_accessor :strict
26
24
 
27
25
  ProfileLevel = {:off => 0, :slow_only => 1, :all => 2, 0 => 'off', 1 => 'slow_only', 2 => 'all'}
28
26
 
27
+ def self.write_concern(safe_)
28
+ return safe_ if safe_.is_a?(JMongo::WriteConcern)
29
+ return JMongo::WriteConcern.new(0) if safe_.is_a?(FalseClass)
30
+ return JMongo::WriteConcern.new(true) if safe_.is_a?(TrueClass)
31
+ return JMongo::WriteConcern.new(safe.to_i) if safe_.is_a?(Numeric)
32
+ return JMongo::WriteConcern.new(-1) unless safe_.is_a?(Hash)
33
+ w = safe_.fetch(:w, 0)
34
+ t = safe_.fetch(:wtimeout, 0)
35
+ f = !!safe_.fetch(:fsync, false)
36
+ JMongo::WriteConcern.new(w, t, f) #dont laugh!
37
+ end
38
+
29
39
  def initialize(db_name, connection, options={})
30
40
  @name = db_name
31
41
  @connection = connection
32
42
  @j_db = @connection.connection.get_db db_name
33
43
  @pk_factory = options[:pk]
44
+ @safe = options[:safe]
34
45
  @strict = options.fetch(:strict, false)
35
46
  end
36
47
 
@@ -64,39 +75,45 @@ module Mongo
64
75
 
65
76
  def collections
66
77
  collection_names.map do |name|
67
- Collection.new(self, name)
78
+ collection(name)
68
79
  end
69
80
  end
70
81
 
71
82
  def collections_info(coll_name=nil)
72
- selector = {}
73
- selector[:name] = full_collection_name(coll_name) if coll_name
74
- coll = self.collection(SYSTEM_NAMESPACE_COLLECTION)
75
- coll.find selector
83
+ _collections_info coll_name
76
84
  end
77
85
 
78
86
  def create_collection(name, options={})
79
- if collection_names.include?(name)
80
- raise MongoDBError, "Collection #{name} already exists. Currently in strict mode." if @strict
81
- collection(name, options)
82
- else
83
- begin
84
- jc = @j_db.create_collection(name, to_dbobject(options))
85
- Collection.new self, name, options, jc
86
- rescue NativeException => ex
87
- raise MongoDBError, "Collection #{name} creation error: " +
88
- ex.message
87
+ validate_name(name)
88
+ if collection_exists?(name)
89
+ if strict?
90
+ raise MongoDBError, "Collection #{name} already exists. Currently in strict mode."
91
+ else
92
+ return Collection.new self, name, options, @j_db.get_collection(name)
89
93
  end
90
94
  end
95
+ begin
96
+ Collection.new self, name, options
97
+ rescue => ex
98
+ raise MongoDBError, "Collection #{name} creation error: " + ex.message
99
+ end
91
100
  end
92
101
 
93
102
  def collection(name, options = {})
94
- Collection.new self, name, options
103
+ validate_name(name)
104
+ if strict? && !collection_exists?(name)
105
+ raise MongoDBError, "Collection #{name} does not exists. Currently in strict mode."
106
+ else
107
+ Collection.new self, name, options, @j_db.get_collection(name)
108
+ end
95
109
  end
96
110
  alias_method :[], :collection
97
111
 
98
112
  def drop_collection(name)
99
- coll = collection(name).j_collection.drop
113
+ col_name = name.to_s
114
+ return true unless collection_exists?(col_name)
115
+
116
+ ok?(command(:drop => col_name))
100
117
  end
101
118
 
102
119
  def get_last_error
@@ -122,15 +139,13 @@ module Mongo
122
139
 
123
140
  def dereference(dbref)
124
141
  ns = dbref.namespace
125
- raise MongoArgumentError, "No namespace for dbref: #{dbref.inspect}"
142
+ raise MongoArgumentError, "No collection for dbref: #{dbref.inspect}" unless collection_exists?(ns)
126
143
  collection(ns).find_one("_id" => dbref.object_id)
127
144
  end
128
145
 
129
146
  def eval(code, *args)
130
147
  doc = do_eval(code, *args)
131
- return unless doc
132
- return doc['retval']['value'] if doc['retval'] && doc['retval']['value']
133
- doc['retval']
148
+ (retval = doc['retval']).is_a?(Hash) && (value = retval['value']) ? value : retval
134
149
  end
135
150
 
136
151
  def rename_collection(from, to)
@@ -143,12 +158,12 @@ module Mongo
143
158
  end
144
159
 
145
160
  def drop_index(collection_name, index_name)
146
- self[collection_name].drop_index(index_name)
161
+ collection(collection_name).drop_index(index_name)
147
162
  end
148
163
 
149
164
  def index_information(collection_name)
150
165
  info = {}
151
- from_dbobject(@j_db.get_collection(collection_name).get_index_info).each do |index|
166
+ from_dbobject(@j_db.getCollectionFromString(collection_name).getIndexInfo).each do |index|
152
167
  info[index['name']] = index
153
168
  end
154
169
  info
@@ -258,11 +273,6 @@ module Mongo
258
273
  end
259
274
  doc
260
275
  end
261
-
262
- # additions to the ruby driver
263
- def has_collection?(name)
264
- has_coll name
265
- end
266
276
  end # class DB
267
277
 
268
278
  end # module Mongo
@@ -2,7 +2,6 @@ module BSON
2
2
  # add missing BSON::ObjectId ruby methods
3
3
  java_import Java::OrgBsonTypes::ObjectId
4
4
 
5
- java_import Java::ComMongodb::DBRef
6
5
  java_import Java::OrgBsonTypes::MaxKey
7
6
  java_import Java::OrgBsonTypes::MinKey
8
7
  java_import Java::OrgBsonTypes::Symbol
@@ -18,7 +17,7 @@ module BSON
18
17
  end
19
18
 
20
19
  def self.create_pk(doc)
21
- doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!(:_id => self.new)
20
+ doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!('_id' => self.new)
22
21
  end
23
22
 
24
23
  def self.from_time(time, opts={})
@@ -105,6 +104,31 @@ module BSON
105
104
  alias :to_bson_code :to_bson
106
105
  end
107
106
 
107
+ class DBRef
108
+
109
+ attr_reader :namespace, :object_id
110
+
111
+ # Create a DBRef. Use this class in conjunction with DB#dereference.
112
+ #
113
+ # @param [String] a collection name
114
+ # @param [ObjectId] an object id
115
+ #
116
+ # @core dbrefs constructor_details
117
+ def initialize(namespace, object_id)
118
+ @namespace = namespace
119
+ @object_id = object_id
120
+ end
121
+
122
+ def to_s
123
+ "ns: #{namespace}, id: #{object_id}"
124
+ end
125
+
126
+ def to_hash
127
+ {"$ns" => @namespace, "$id" => @object_id }
128
+ end
129
+
130
+ end
131
+
108
132
  # Generic Mongo Ruby Driver exception class.
109
133
  class MongoRubyError < StandardError; end
110
134