From: Elias K. <ek...@so...> - 2002-07-31 19:23:58
|
Hello everybody, I have some proposals for the DB2 driver as well as the Ruby DBI/DBD API, and I would be grateful to hear your opinions. In detail: 1)BLOB/CLOB support I work on a project that will be using DB2 as a backend to store ruby objects (via Marshall.store) in VARCHAR columns and I am hitting on the database limit of pagesize (4096 bytes default). Extending the pagesize at db creation up to 32K will not solve the problem, but will only postpone it for a later time, so the logical solution seems to use large objects (LOB). Looking at existing work, I see that only the postgres driver for ruby implements LOB functionality, but then it is hidden from the DBI. Class DBI::Binary seems a good starting point, so my first thought is to add functionality like the one found on java.sql.[B|C]lob interfaces. I think that JDBC is very well designed (although its datatype strictness really gets on my nerves) and we can borrow many ideas and function calls. Or, we can borrow ideas from Python/Perl DBI implementations. Or better, we can keep it simple and use Ruby in a clever manner to hide all this complexity from the user. 2) Parameter binding Right now, parameter binding uses ugly string concatenation to produce ad-hoc SQL statements, which cancels all performance gains from prepared (precompiled) statements. Apart from that, it doesn't support input/output and output parameters, which means that most existing legacy databases that use stored procedures are useless under Ruby. Therefore, we need to define some sort of attribute to let the db driver know what kind of parameter we use. We could be using 'attribs' parameter in DBI::Statement.bind_param to do this. For instance: statement.bind_param(1, value1, { 'direction' => 'in', 'type' => SQL_BLOB}) statement.bind_param(2, value2, { 'direction' => 'out', 'type' => SQL_INTEGER}) statement.bind_param(3, value3, { 'direction' => 'inout', 'type' => SQL_VARCHAR}) In this case: a) direction => 'in' would mean that parameter is bound for input (no expected result from the db statement) b) 'out' means that parameter is bound for output (value generated by database, ruby variable initialized & populated at statement execution time) c) 'inout' means the same as 'out' except that we use the ruby variable's value at execution, dispose the value and populate a new value with the statement results attribute 'type' must be supplied because the low-level driver needs to know what kind of data to expect from the database. Therefore, all returned ('out'/'inout') values should be instantiated from a base class that matches closely the specified SQL datatype. Furthermore, for BLOB/CLOB functionality, value1 could be: a) read directly from memory, b) if it was a string it could represent a filename, then we could bind the parameter to the file itself. DB2 and ODBC have SQLBindFileTo(Col|Param) 3) DB2 driver I admit I am confused as to where to draw the separation line between database handling logic and the ruby DBD implementation. Looking at the ODBC driver (~120k!) I see that all low-level work is done in C and the driver uses Ruby to act as a bridge to ODBC functions. This decision means that we have to take care of memory management, garbage collection etc. in C. What is your opinion? See you, Elias |