MongoDB Xojo Driver (maybe)

All,

I am trying to gather support to help MongoDB (inc) write a driver for Xojo. If you can sign on to the jira case, it can help drive the development of the driver.

mongodb driver

thanks!
sb

Done

Added my vote.

thanks for signing on.

added my vote!

+1

+1

Have to admit that I’ve been avoiding NoSQL until now, and have been sticking with well proven relational databases… but MongoDB looks like an interesting data solution. Busy downloading MongoDB to learn more about it.

After spending a few weeks with MongoDB I’m completely sold on the idea that MongoDB offers a lot of value to the data world.

So much so that I started writing a Xojo MongoDB driver in 100% pure Xojo (no external libraries required). I designed the driver according to the requirements given at
http://docs.mongodb.org/meta-driver/latest/legacy/mongodb-driver-requirements/

There is still lots to do, but with this first release all the basic required objects are in place (e.g. client, database, collection and cursor) with a few basic methods such as “findOne”, “find” and “insert”. This will allow you to query your MongoDB databases and do basic inserts.

I had to write a BSON Serializer from scratch for the driver, so if try out the driver, please keep in mind that the BSON serializer is only partially implemented (e.g. cannot handle regular expression without them being in quoted… yet…).

Also, this first version of the driver doesn’t support replicated and sharded MongoDB environments yet (only a MongoDB hosted on a single machine). If there is enough interest I’d love to take this driver to become a full implementation. Any feedback anyone might have will really help me a lot in achieving such a goal.

The driver can be downloaded from

http://www.xojo3d.com/mongodriver/XojoMongoDriver_0.1.0.zip

Simply import the “BSONSerializer” and “MongoDriver” modules into your project. I tried to keep the workings of the driver to be an exact match of the existing drivers. So if you’ve used a MongoDB driver before, it should be easy enough to use the Xojo version of it.

Here is some sample code…

  Dim client As new MongoDriver.MongoClient() ' connect to localport on default port
  Dim db As MongoDriver.MongoDatabase
  Dim coll As MongoDriver.MongoCollection
  Dim cursor As MongoDriver.MongoCursor
  
  ' wait for connection to be established
  ' NOTE: this will eventually be done automatically by the client constructor
  while not client.IsConnected
    App.DoEvents
  wend
  
  db = client.getDB("test") ' get database object
  
  coll = db.getCollection("data") ' get collection object
  
  coll.insert "{mydoc:123}" ' insert a document into collection
  
  ' query and loop through documents
  
  cursor = coll.find("{mydoc:123}")
  while cursor.hasNext
    System.DebugLog cursor.getNextDocument()
  wend

If you want to connect to a MongoDB on a different machine, simply instantiate the client object as follow:

Dim client As new MongoDriver.MongoClient("some_remote_addr", port#)

2,000,000 bonus points awarded.

and another 2million bonus points… :slight_smile:

By the way, none of my bonus points were awarded for just making this. You get 250 regular points for that. The 2M bonus points are for making it in 100% pure Xojo. This will be incredibly helpful for solution debuggability.

I’m glad you like.

Having it in pure Xojo definitely makes things easier. Luckily the MongoDB driver design is very efficient and the driver code shouldn’t increase the final binary size with too much.

MongoDriver 0.1.1 now available… (use at own risk)… I recommend that you first test the driver on a test database and collection before using it for production data.

http://www.xojo3d.com/mongodriver/MongoDriver_0.1.1.zip

Changes:

  • Client object now waits for TCP connection to be established in constructor
  • Added MongoClient.Constructor(initAddress) method
  • Added client.Update(…)
  • Added client.Delete(…)
  • Renamed cursor.getNextDocument() to cursor.getNext()
  • Added collection.update(, , , )
  • Added collection.remove(, )

Sample code:

  Dim client As new MongoDriver.MongoClient() ' connect to localhost on default port
  Dim db As MongoDriver.MongoDatabase
  Dim coll As MongoDriver.MongoCollection
  Dim cursor As MongoDriver.MongoCursor
  
  db = client.getDB("test") ' get database object
  
  coll = db.getCollection("data") ' get collection object
  
  coll.insert "{mydoc:123}" ' insert document into collection
  
  ' query and loop through documents
  
  cursor = coll.find("{}")
  while cursor.hasNext
    System.DebugLog cursor.getNext()
  wend
  
  coll.remove("{a:1}") ' remove document
  
  coll.update"{mydoc:123}", "{$set:{mydoc:234}}" ' update document

According to the MongoDB documentation about the collection.remove(query,justOne) method, justOne should be False by default.

This implies that either one of the following instructions will delete ALL the documents in your collection.

coll.remove()
coll.remove("{}")

This seems a bit dangerous to me, and in I’ve programmed the driver so that justOne=True by default. You have to specifically indicate you want to remove all the documents by setting justOne to False.

If you have any questions, requests or suggestions about the driver, please let me know. Keep in mind, the driver still only supports a database on a single machine. Support for shards and replicas will be added at a later stage.

To make things easier I’ve started a public GitHub repository for the Xojo MongoDB driver.

Thanks for your GREAT contribution!! I have been using Python to be able to work with MongoDB, but now I can use Xojo!! I host my databases on www.mongolabs. They have a free database package for developers.

Thanks, keep working on the MongoDB driver!!!

Glad to hear it helped Mario. I’ll definitely keep working at it.

I have tested out the driver and it works great. Granted I have only done a little testing with it but what I tested worked flawlessly.

thanks for tackling the driver!!

You’re welcome Scott, and I’m glad to hear it works.

There is a few things I still want to add to the BSON Serializer (before expanding the objects with more methods)… like regular expressions. The ability to query documents using regular expressions is a powerful feature of MongoDB.

Currently, if you want to query your documents with regular expressions you need to write it as…

MyCollection.find({ field: { $regex: “acme.*corp”, $options: “i” } })

the following is a nicer syntax IMO to do the same query, but I need to add support for this syntax the BSON Serializer…

MyCollection.find({ field: /acme.*corp/i })

Thank you for all of the work, Alwyn!

One issue I’m coming up with… When I save a new document, the “_id” field is saved as an ObjectID. When I try to save a modified version of the document, the driver finds the “_id” field, and tries to do an update; but, the _id is no longer an ObjectID. This causes a duplicate document to be saved. It actually looks like the ObjectID is being stripped out during the find operation.

Do you have any suggestions on how to handle this?

Thanks!