C++ / Perl DBI Interface Overview: The system allows DBMS-indepedent SQL access from C++. The implementation and API are based on the Perl DBI library. There are two parts: - the Perl DBI server daemon, which accepts connections from multiple clients on a named unix-domain socket - the C++ client library, which mirrors DBI's object-oriented API for databases, connections and statements, and uses STL vectors (and hash-maps?) where perl uses arrays and hashes Functionality: - database connect / disconnect, database handle objects. - prepare statement, statement handle objects. - execute statement (including support for bind variables) - fetch row as vector (or as hash-map?) - number and names of fields in statement results - enumerate tables present in the database - test if a table is present in the database? - do a command (no prepare, no fetch) - fetchall Next step functionality: - selectall (prepare, execute & fetch all rows) - selectcol (prepare, execute & fetch all rows, for a single column) - commit & rollback ; autocommit control Binary Protocol: All integers are encoded in network byte-order (big-endian). Every message begins with a 4-byte 'length' field, followed by a 2-byte 'type', and a 2-byte 'client-ref-id'. In addition, every reply has a 2-byte 'status' field, where 0 indicates success, and anything else indicates an error. In this case there may be an error message in the body. request: [length][type][client-ref] reply: [length][type][client-ref][status] A 'list' in this protocol is a 4-byte 'number of elements' followed by that many elements, where each element is a 4-byte length (in bytes) followed by the data. list: [number of elements] [e1 len][e1 data] [e2 len][e2 data] ... [en len] [en data] 00xx General Commands: 0000 Connect to Database request body is a dbi connection string, e.g. 'Pg:dbname=mydb' - the 'dbi:' prefix is not sent reply body is a 2-byte database handle 01xx Database Commands: These all begin with a 2-byte database handle 0100 Disconnect request: nothing reply: nothing 0101 Enumerate Tables request: nothing reply: list of table names 0102 Test for Table request: table name reply: 1-byte boolean (0x00 or 0x01) 0103 Prepare SQL Query request: SQL, with '?' for placeholders reply: 2-byte statement handle 0104 Do SQL Command request: 2-byte length of SQL ; SQL, with '?' for placeholders ; list of bind values reply: nothing 0105 Select Row request: 2-byte length of SQL ; SQL, with '?' for placeholders ; list of bind values reply: list of field values (a single row) 0106 Select All Rows request: 2-byte length of SQL ; SQL, with '?' for placeholders ; list of bind values reply: list of rows (each being a list of field values) 0107 Select Column request: 2-byte length of SQL ; SQL, with '?' for placeholders ; list of bind values reply: list of field values (the first from each row, a single column) 02xx Statement Commands: These all begin with a 2-byte statement handle (but no database handle, this is implicit) 0200 Execute Statement request: list of bind values reply: 4-byte number of rows ; list of field names 0201 Fetch Row request: nothing reply: list of field values 0202 Finish request: nothing reply: nothing 0203 Fetch All Rows request: nothing reply: list of rows (each being a list of field values) Error Codes: ERROR_UNKNOWN_TYPE = 1; ERROR_DBI_FAIL = 2; ERROR_INVALID_HANDLE = 3; ERROR_TOO_MANY_HANDLES = 4; ERROR_SYNTAX = 5;