Provisional Driver API
"Level 0 Driver"
A "Level 0" driver is one that exposes and supports the basic operations of Mongo with no value-add. I think that all operations at level 0 should be "document" operations, keeping anything that smells of an "object operation" out, and in some upper-level layer.
Level 0 Driver Features
Required
- BSON serialization/deserialization
- basic operations as listed in this section
- full cursor support (e.g. support OP_GET_MORE operation)
- close cursors via OP_KILL_CURSORS
- database command support
- handle query errors
- convert all strings to UTF-8
- hint, explain, count, $where
- database profiling: set/get profiling level, get profiling info
- validate a collection in a database
Optional
- automatic reconnection
- buffer pooling
- advanced connection management (master-server, replica pair, Option_SlaveOk)
- Tailable cursor support
Server Object
A level 0 driver will implement the following connection options.
Single Server Connection
A driver should be able to connect to a single server. By default this must be localhost:27017, and must also allow the server to be specified by hostname and port.
Mongo m = new Mongo(String host, int port);
How the driver does this is up to the driver - make it idiomatic. However, a driver should make it explicit and clear what is going on.
Pair Mode Connection
A driver must be able to support "Pair Mode" configurations, where two instances of Mongo, labeled "left" and "right", and configured for hot-failover.
The driver should determine which of the pair is the current master, and send all operations to that server. In the event of an error, either socket error or a "not a master" error, the driver must restart the determination process. It must not assume the other server in the pair is now the master.
ServerPair sp = new ServerPair(INETAddr...); Mongo m = new Mongo(sp)
A driver may optionally allow a driver to connect deliberately to the "non-master" in the pair, for debugging, admin or operational purposes.
ServerPair sp = new ServerPair(INETAddr...); sp.setTarget(ServerPair.SHADOW_MASTER);
Mongo m = new Mongo(sp);
- Cluster Mode Connect to master in master-slave cluster
ServerCluster sc = new ServerCluster(INETAddr...); Mongo m = new Mongo(sc);
## Connect to slave in read-only mode in master-slave cluster
ServerCluster sc = new ServerCluster(INETAddr...); sc.setTarget(...)
Mongo m = new Mongo(sc);
or maybe make it like *Default/Simple* w/ a flag?
Other than that, we need a way to get a DB object :
Mongo m = new Mongo();
DB db = m.getDB(name);
And a list of db names (useful for tools...) :
List<String> getDBNameList();
Database Object
Simple operations on a database object :
/**
* get name of database
*/
String dbName = db.getName();
/**
* Get a list of all the collection names in this database
*/
List<String> cols = db.getCollectionNames();
/**
* get a collection object. Can optionally create it if it
* doesn't exist, or just be strict. (XJDM has strictness as an option)
*/
Collection coll = db.getCollection(string);
/**
* Create a collection w/ optional options. Can fault
* if the collection exists, or can just return it if it already does
*/
Collection coll = db.createCollection( string);
Collection coll = db.createCollection( string, options);
/**
* Drop a collection by its name or by collection object.
* Driver could invalidate any outstanding Collection objects
* for that collection, or just hope for the best.
*/
boolean b = db.dropCollection(name);
boolean b = db.dropCollection(Collection);
/**
* Execute a command on the database, returning the
* BSON doc with the results
*/
Document d = db.executeCommand(command);
/**
* Close the [logical] database
*/
void db.close();
/**
* Erase / drop an entire database
*/
bool dropDatabase(dbname)
Database Administration
These methods have to do with database metadata: profiling levels and collection validation. Each admin object is associated with a database. These methods could either be built into the Database class or provided in a separate Admin class whose instances are only available from a database instance.
/* get an admin object from a database object. */
Admin admin = db.getAdmin();
/**
* Get profiling level. Returns one of the strings "off", "slowOnly", or
* "all". Note that the database returns an integer. This method could
* return an int or an enum instead --- in Ruby, for example, we return
* symbols.
*/
String profilingLevel = admin.getProfilingLevel();
/**
* Set profiling level. Takes whatever getProfilingLevel() returns.
*/
admin.setProfilingLevel("off");
/**
* Retrieves the database's profiling info.
*/
Document profilingInfo = admin.getProfilingInfo();
/**
* Returns true if collection is valid; raises an exception if not.
*/
boolean admin.validateCollection(collectionName);
Collection
Basic Ops
/**
* full query capabilities - limit, skip, returned fields, sort, etc
*/
Cursor find(...);
void insert(...) void remove(query) void modify(selector, modifier) void replace(selector, object) void repsert(selector, object) long getCount();
long getCount(query);
Index Operations
void createIndex( index_info)
void dropIndex(name)
void dropIndexes()
List<info> getIndexInformation()
Misc Operations
document explain(query)
options getOptions();
string getName();
void close();
Cursor Object
document getNextDocument()
iterator getIterator() bool hasMore()
void close()
"Level 1 Driver"
A "level 1" driver uses a "level 0" driver to add additional functionality. In terms of our history, I think that this is where "ORM"-type of functions should appear.
I think that we might have a variety of level 1 drivers :
- Level 1 "ORM" Driver : this would support stuff like save(), ensureIndex(), auto create index for _id, resolution of DB Refs, etc
- Level 1 "GridFS" Driver : this would be a separate and distinct driver that leverages a level 0 driver to do GridFS. No need to combine w/ anything else
Level 1 Database Object
/**
* resolve a DBRef, with recursion. This is a potentially dangerous operation, as the
* resulting document graph - and thus the resulting single document, can be arbitrarily
* and surprisingly large
*/
Document resolveReference(DBRef ref, boolean recurse);
Level 1 Collection Object
/**
*
* From JS, this is a caching index function that supported the
* multiple re-entry and re-initialization model on the app server. It's a far
* more difficult operation outside of the controlled environment of an app server, since
* one process has no clue about what other code might be doing (like dropping the index)
*
* Put here for completeness
*/
boolean coll.ensureIndex(...);
/**
* "saves" a document - this means that if it's already blessed with an _id, the doc
* in the database is updated, and if it doesn't have an _id, and _id is injected and then
* the doc is inserted into the collection.
*
* There are some interesting implications here now that we're considering relaxing
* the constraint on _id being a BabbleOID, and letting it be anything. There will have to
* be some kind of "PKInjector" (see the XJDM) where the programmer can give the level 1
* driver an _id factory....
*/
void coll.save(Document doc);
IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.
These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group. blog comments powered by Disqus