Class: XGen::Mongo::Driver::DB

Inherits:
Object
  • Object
show all
Defined in:
lib/mongo/db.rb

Overview

A Mongo database.

Constant Summary collapse

SYSTEM_NAMESPACE_COLLECTION =
"system.namespaces"
SYSTEM_INDEX_COLLECTION =
"system.indexes"
SYSTEM_PROFILE_COLLECTION =
"system.profile"
SYSTEM_COMMAND_COLLECTION =
"$cmd"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db_name, host = 'localhost', port = XGen::Mongo::Driver::Mongo::DEFAULT_PORT) ⇒ DB

db_name

The database name

host

The database host name or IP address. Defaults to ‘localhost’.

port

The database port number. Defaults to XGen::Mongo::Driver::Mongo::DEFAULT_PORT.



62
63
64
65
66
67
68
69
# File 'lib/mongo/db.rb', line 62

def initialize(db_name, host='localhost', port=XGen::Mongo::Driver::Mongo::DEFAULT_PORT)
  raise "Invalid DB name" if !db_name || (db_name && db_name.length > 0 && db_name.include?("."))
  @name, @host, @port = db_name, host, port
  @socket = TCPSocket.new(@host, @port)
  @strict = false
  @semaphore = Object.new
  @semaphore.extend Mutex_m
end

Instance Attribute Details

#nameObject (readonly)

The name of the database.



50
51
52
# File 'lib/mongo/db.rb', line 50

def name
  @name
end

#socketObject (readonly)

The database’s socket. For internal use only.



53
54
55
# File 'lib/mongo/db.rb', line 53

def socket
  @socket
end

#strict=(value) ⇒ Object (writeonly)

Strict mode enforces collection existence checks. When true, asking for a collection that does not exist or trying to create a collection that already exists raises an error.

Strict mode is off (false) by default. Its value can be changed at any time.



44
45
46
# File 'lib/mongo/db.rb', line 44

def strict=(value)
  @strict = value
end

Instance Method Details

#adminObject



120
121
122
# File 'lib/mongo/db.rb', line 120

def admin
  Admin.new(self)
end

#closeObject

Close the connection to the database.



155
156
157
# File 'lib/mongo/db.rb', line 155

def close
  @socket.close
end

#collection(name) ⇒ Object

Return a collection. If strict is false, will return existing or new collection. If strict is true, will raise an error if collection name does not already exists.



127
128
129
130
131
132
133
134
# File 'lib/mongo/db.rb', line 127

def collection(name)
  return Collection.new(self, name) if collection_names.include?(full_coll_name(name))
  if strict?
    raise "Collection #{name} doesn't exist. Currently in strict mode."
  else
    create_collection(name)
  end
end

#collection_namesObject

Returns an array of collection names. Each name is of the form “database_name.collection_name”.



73
74
75
76
77
# File 'lib/mongo/db.rb', line 73

def collection_names
  names = collections_info.collect { |doc| doc['name'] || '' }
  names.delete('')
  names
end

#collections_info(coll_name = nil) ⇒ Object

Returns a cursor over query result hashes. Each hash contains a ‘name’ string and optionally an ‘options’ hash. If coll_name is specified, an array of length 1 is returned.



82
83
84
85
86
# File 'lib/mongo/db.rb', line 82

def collections_info(coll_name=nil)
  selector = {}
  selector[:name] = full_coll_name(coll_name) if coll_name
  query(SYSTEM_NAMESPACE_COLLECTION, Query.new(selector))
end

#count(collection_name, selector = {}) ⇒ Object

Return the number of records in collection_name that match selector. If selector is nil or an empty hash, returns the count of all records. Normally called by Collection#count.



206
207
208
209
210
211
212
213
# File 'lib/mongo/db.rb', line 206

def count(collection_name, selector={})
  oh = OrderedHash.new
  oh[:count] = collection_name
  oh[:query] = selector || {}
  doc = db_command(oh)
  return doc['n'].to_i if ok?(doc)
  raise "Error with count command: #{doc.inspect}"
end

#create_collection(name, options = {}) ⇒ Object

Create a collection. If strict is false, will return existing or new collection. If strict is true, will raise an error if collection name already exists.

Options is an optional hash:

:capped

Boolean. If not specified, capped is false.

:size

If capped is true, specifies the maximum number of bytes. If false, specifies the initial extent of the collection.

:max

Max number of records in a capped collection. Optional.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/mongo/db.rb', line 101

def create_collection(name, options={})
  # First check existence
  if collection_names.include?(full_coll_name(name))
    if strict?
      raise "Collection #{name} already exists. Currently in strict mode."
    else
      return Collection.new(self, name)
    end
  end

  # Create new collection
  oh = OrderedHash.new
  oh[:create] = name
  doc = db_command(oh.merge(options || {}))
  ok = doc['ok']
  return Collection.new(self, name) if ok.kind_of?(Numeric) && (ok.to_i == 1 || ok.to_i == 0)
  raise "Error creating collection: #{doc.inspect}"
end

#create_index(collection_name, index_name, fields) ⇒ Object

Create a new index on collection_name named index_name. fields should be an array of field names. Normally called by Collection#create_index.



255
256
257
258
259
260
261
262
263
# File 'lib/mongo/db.rb', line 255

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
  @semaphore.synchronize {
    send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, sel))
  }
end

#db_command(selector) ⇒ Object

DB commands need to be ordered, so selector must be an OrderedHash (or a Hash with only one element). What DB commands really need is that the “command” key be first.

Do not call this. Intended for driver use only.



292
293
294
295
296
297
298
299
300
301
302
# File 'lib/mongo/db.rb', line 292

def db_command(selector)
  if !selector.kind_of?(OrderedHash)
    if !selector.kind_of?(Hash) || selector.keys.length > 1
      raise "db_command must be given an OrderedHash when there is more than one key"
    end
  end

  q = Query.new(selector)
  q.number_to_return = 1
  query(SYSTEM_COMMAND_COLLECTION, q).next_object
end

#drop_collection(name) ⇒ Object

Drop collection name. Returns true on success or if the collection does not exist, false otherwise.



138
139
140
141
142
143
144
# File 'lib/mongo/db.rb', line 138

def drop_collection(name)
  return true unless collection_names.include?(full_coll_name(name))

  coll = collection(name)
  coll.drop_indexes     # Mongo requires that we drop indexes manually
  ok?(db_command(:drop => name))
end

#drop_index(collection_name, name) ⇒ Object

Drop index name from collection_name. Normally called from Collection#drop_index or Collection#drop_indexes.



217
218
219
220
221
222
223
# File 'lib/mongo/db.rb', line 217

def drop_index(collection_name, name)
  oh = OrderedHash.new
  oh[:deleteIndexes] = collection_name
  oh[:index] = name
  doc = db_command(oh)
  raise "Error with drop_index command: #{doc.inspect}" unless ok?(doc)
end

#full_coll_name(collection_name) ⇒ Object



277
278
279
# File 'lib/mongo/db.rb', line 277

def full_coll_name(collection_name)
  "#{@name}.#{collection_name}"
end

#index_information(collection_name) ⇒ Object

Return an array of hashes, one for each index on collection_name. Normally called by Collection#index_information. Each hash contains:

:name

Index name

:keys

Hash whose keys are the names of the fields that make up the key and values are integers.

:ns

Namespace; same as collection_name.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/mongo/db.rb', line 234

def index_information(collection_name)
  sel = {:ns => full_coll_name(collection_name)}
  query(SYSTEM_INDEX_COLLECTION, Query.new(sel)).collect { |row|
    h = {:name => row['name']}
    raise "Name of index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:name]

    h[:keys] = row['key']
    raise "Keys for index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:keys]

    h[:ns] = row['ns']
    raise "Namespace for index on return from db was nil. Coll = #{full_coll_name(collection_name)}" unless h[:ns]
    h[:ns].sub!(/.*\./, '')
    raise "Error: ns != collection" unless h[:ns] == collection_name

    h
  }
end

#insert_into_db(collection_name, objects) ⇒ Object

Insert objects into collection_name. Normally called by Collection#insert.



267
268
269
270
271
# File 'lib/mongo/db.rb', line 267

def insert_into_db(collection_name, objects)
  @semaphore.synchronize {
    objects.each { |o| send_to_db(InsertMessage.new(@name, collection_name, o)) }
  }
end

#master?Boolean

Returns true if this database is a master (or is not paired with any other database), false if it is a slave.

Returns:

  • (Boolean)


148
149
150
151
152
# File 'lib/mongo/db.rb', line 148

def master?
  doc = db_command(:ismaster => 1)
  is_master = doc['ismaster']
  ok?(doc) && is_master.kind_of?(Numeric) && is_master.to_i == 1
end

#ok?(doc) ⇒ Boolean

Return true if doc contains an ‘ok’ field with the value 1.

Returns:

  • (Boolean)


282
283
284
285
# File 'lib/mongo/db.rb', line 282

def ok?(doc)
  ok = doc['ok']
  ok.kind_of?(Numeric) && ok.to_i == 1
end

#query(collection_name, query) ⇒ Object

Send a Query to collection_name and return a Cursor over the results.



166
167
168
169
170
171
# File 'lib/mongo/db.rb', line 166

def query(collection_name, query)
  @semaphore.synchronize {
    send_to_db(QueryMessage.new(@name, collection_name, query))
    Cursor.new(self, collection_name, query.number_to_return)
  }
end

#remove_from_db(collection_name, selector) ⇒ Object

Remove the records that match selector from collection_name. Normally called by Collection#remove or Collection#clear.



175
176
177
178
179
# File 'lib/mongo/db.rb', line 175

def remove_from_db(collection_name, selector)
  @semaphore.synchronize {
    send_to_db(RemoveMessage.new(@name, collection_name, selector))
  }
end

#replace_in_db(collection_name, selector, obj) ⇒ Object Also known as: modify_in_db

Update records in collection_name that match selector by applying obj as an update. Normally called by Collection#replace.



183
184
185
186
187
# File 'lib/mongo/db.rb', line 183

def replace_in_db(collection_name, selector, obj)
  @semaphore.synchronize {
    send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, false))
  }
end

#repsert_in_db(collection_name, selector, obj) ⇒ Object

Update records in collection_name that match selector by applying obj as an update. If no match, inserts (???). Normally called by Collection#repsert.



195
196
197
198
199
200
201
# File 'lib/mongo/db.rb', line 195

def repsert_in_db(collection_name, selector, obj)
  # TODO if PKInjector, inject
  @semaphore.synchronize {
    send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, true))
    obj
  }
end

#send_message(msg) ⇒ Object

Send a MsgMessage to the database.



160
161
162
# File 'lib/mongo/db.rb', line 160

def send_message(msg)
  send_to_db(MsgMessage.new(msg))
end

#send_to_db(message) ⇒ Object



273
274
275
# File 'lib/mongo/db.rb', line 273

def send_to_db(message)
  @socket.print(message.buf.to_s)
end

#strict?Boolean

Returns the value of the strict flag.

Returns:

  • (Boolean)


47
# File 'lib/mongo/db.rb', line 47

def strict?; @strict; end