Mohegan SkunkWorks

Sun, 28 Feb 2010 19:18:52 EST

Connections in CL-MONGO

I revamped the way connections to a mongo database are handled in cl-mongo. In the new implementation each connection is referenced by a unique name. Each connection is stored in a connection registry. Database calls in cl-mongo default to using the :default connection. The connection parameters used by the default connection for host, port and db are accessible through the mongo-default-.. special variables.

defgeneric mongo (&key host port db name) gets the connection referred to by the :name keyword. The default for :name is :default. If no connection with that name exists, a new connection will be created.

defun mongo-show () will show all connections currently in the registry.

(defgeneric mongo-swap (left right) will swap two connections. This is useful if you want to use a different default connection, or want to change the parameters on an existing named connection.

defgeneric mongo-close ( name ) is used to close a connection. The special keyword :all can be used to close all connections in the registry.

Opening connections

The generic function mongo is used to create a connection. mongo takes four keywords as an argument. :name is the name of the connection and the other three parameterkeywords :host :port and :db are used to establish a connection to a mongodb instance.Each of the four keywords has a default value which will be used if none in provided by the caller.

The first thing mongo does is see whether a connection with name exists in the connection registry. If not, it will create one with the parameters provided through the :host :port and :db keywords. The connection registry is a hash table with the name as key and the mongo connection object as the value.

The default for :name is the keyword :default. The default connection parameters can be set through the dynamic variables *mongo-default-host*, *mongo-default-port* and *mongo-default-db*. They are currently set to "localhost", the default mongo port and "admin" respectively.So the first time (mongo) is executed a connection using default values for the connection parameters is created.

Unless a mongo connection is provided through the :mongo keyword,database operations, like db.use or db.find all execute (mongo) to get a connection.So a call to these functions creates default connection as a side-effect.

There is no restriction on the type of the :name parameter. Typically I would expect a symbol or a unique id to be used. Strings can be used as well. Each connection is assigned a unique id. This id, in distinction to the name, cannot be changed.

It's important to realize that if a connection name exists in the registry the associated connection object is returned and other keywords are ignored.So if a connection named :alt exists in the *mongo-registry* the :port keyword in (mongo :name :alt :port 12388 ) are ignored. In addition, the network parameters of the connection object returned by *(mongo :name )* are read-only. The reason they're read-only is that changing these parameters doesn't really change the actual connection. I also wanted a mongo call to be fast. Using the (mongo..) method to manage connections would impact the speed of the look-up. (mongo-swap..) is the method to use when you want to change connection parameters.

Swapping connections

Using mongo over the LISP REPL is different from say a java-script client. A java-script client is typically tied to a specific mongo connection. Connections to multiple servers can be established using the REPL by calling (mongo..) with different connection parameters. However, there 's only one :default connection. The :default connection is privileged in that it is used "by default" in all other mongo database calls. You could pass in an alternative connection using the :mongo keyword but that obviously a bit cumbersome. The alternative is to swap connections and tie a different connection to the :default keyword.

(mongo-swap left right) provides this functionality. (mongo-swap left right) swaps the names of the connections and returns them in the order they were passed in. So if you want to make you're :alt connection the default connection, you call (mongo-swap :default :alt) and the :alt is now the referred to by the keyword :default and the connection previously referred to by keyword :default is now referred to by the keyword :alt.

An other use of (mongo-swap..) is to change the parameters of particular connection. Suppose you want to have the connection bound to :alt refer to a different host. You can do this : (mongo_close (mongo-swap :alt (mongo :name :tmp :host )))

This will create mongo connection named :temp which is swapped with the current :alt connection and the old :alt connection object (now bound to :tmp) is closed.

Inspecting connections

There are two ways to take a look at the connection registry :

  (show :connections) 

The second command is basically wrapped around the first one. show is a general shell command which takes a variety of keywords and returns database data like the server status.

Closing connections

Use (mongo-close <name> ) to close a connection named . If you pass in the keyword :all all connections will be closed. (mongo-close..) will also remove the connection from the registry.