cpdo  cpdo_skeleton

ACHTUNG: THE CPDO WIKI IS NOW (AS OF 2011-May-17) MAINTAINED ON A DEDICATED WIKI SITE: http://whiki.wanderinghorse.net/wikis/cpdo/?page=cpdo_skeleton

The file cpdo_skeleton.c contains a non-functional, but compilable, cpdo_driver implementation which can be used to speed up the process of creating new drivers. It contains dummy implementations for all of the API members, ready to be filled out. How much effort that requires (or does not require, in the case of sqlite3) depends on the underlying database access API. As a basis for comparison:

  • The initial draft of cpdo_sqlite3, the first driver, took around 6 hours, and probably has a total of 8-10 hours invested in it (it's grown as the core API has grown). Much of that time was while i was still designing/factoring/refactoring the core interfaces, so the driver didn't actually take all that long to develop. sqlite3 is, from a client-side perspective, one of the simplest-to-use libraries around, and implementing this driver posed no special challenges.
  • In strong constrast... the initial version of cpdo_mysql5 took about 12 hours, and about 8 hours of that was just figuring out how to use their parameter/result binding mechanism and setting up the infrastructure to support MySQL's needs (and boy, does it have needs!). MySQL has lots of docs, but they are often quite vague, poorly cross-referenced (use doxygen, dammit!), annoyingly imprecise, or simply do not reflect reality. After much googling i found only one useful example i could really learn from - the PHP mysqli driver. A good deal of infrastructure was added added to the library to support this driver (and future ones with similar designs), and it has a total of well over 30 hours invested it.

The up-side to the effort put in to the MySQL driver is that we now have more library-level bits which we will almost certainly need for future drivers.

The drivers i "would like to implement" but will probably never get around to doing:

  • Postgres, just in case someone out there actually does use PG (i've only once seen it in action, and that was back in 2002 or so).
  • ocilib provides an easy-to-use Oracle binding which i used on a commercial project in early 2011. My main limiting factor here is access to a machine with all the necessary Oracle bits. (If that were not an issue, i would have already started this one.) If someone out there can provide me with SSH access to such a machine (and install emacs or xemacs on it for me) then i'll have a go at it. (If you have such a machine, please read this blog post!)

After looking over Postgres' and ocilib's APIs, i believe most of the infrastructure added for MySQL will be useful in binding those (in particular ocilib), and if it is then we can probably refactor a significant fraction of cpdo_mysql5's innards into reusable components for the other drivers.

After more looking over Postgres, i'm starting to think that Postgres' general world view is too different to easily consolidate here. Some of the problem areas i foresee:

  • Bound parameters use a non-standard format (e.g. $1 instead of ?). We could parse them ourselves and get around that, but PG also has some constructs which would make custom parsing more difficult, e.g. $1::int4 means that parameter 1 is being explicitly cast to a 4-byte integer. We would need to be able to tokenize and understand these constructs in order to ensure the proper type conversions are made, and i'm really not up to re-implementing PG's parsing code.
  • When preparing statements with bound arguments, we have to tell PG it how many arguments we are passing in the SQL (not sure why it can't deduce that itself). We can do that only if we parse the SQL ourselves, but see the notes above regarding PG-specific argument passing conventions.

The following page has been the basis for most of my thinking on PG: