Forum OpenACS Development: Bind variable emulation in Tcl?
Reason I ask, is I've just hacked together support for multiple
databases in my ACS 4.2 DB API, principally so I can use it with the nsodbc
which I'm pretty sure does not support bind variables. And right now
my "replacement" for the '
ns_ora $type $db -bind $bind
$sql' type calls in
db_exec is '
variables not supported for this database."'.
The only requirement is that expressions like:
foo_id = '123'
work, i.e. that integers can be quoted and will be interpreted as numbers. Oracle and PG both allow this (though the Oracle driver does
real bind vars, of course) and I think it's standard SQL 92.
Doing it at the Tcl level wouldn't be that hard - check out the regexps in the PG or Oracle driver that identify :tcl_var constructs.
But doing it right in nsodbc would be more efficient.
First of all, what is the deal with the
args parameter in
the Oracle version of
The principle users of this db_exec args parameter seem to be the db_exec_plsql, db_dml, and db_blob_get_file procs. Looks like the $args parameter is only important for lobs, but I'm at a loss as to what exactly is going on there.Oracle: return [eval [list ns_ora $type $db -bind $bind $sql] $args] Postgres: return [eval [list ns_pg_bind $type $db -bind $bind $sql]]
Secondly, I grabbed the OpenACS code out of CVS, and noticed that the ACS Tcl package has three separate *database-procs*.tcl files:
00-database-procs-oracle.tcl 00-database-procs-postgresql.tcl 00-database-procs.tcl
I guess you guys went with separate -oracle and -postgresql files in order to avoid switch statements?
Well, now that I've added support for multiple database drivers to my 10-database-procs.tcl, I've got switch statements in there for Oracle, Postgres, and nsodbc anyway. So, seems to me that if at some point I want to try and add this same feature to OpenACS, I might as well merge the three files back into one, with switch statements galore, no? What do you think?
the particular RDMBS. Only the generic and the proper specialized file are sourced by the bootstrap installer. In other words, if you're running under PostgreSQL then 00-database-procs.tcl and 00-database-procs-postgresql.tcl will be sourced.
What you should do is make a new 00-database-procs-db2.tcl (or whatever db you're planning to support) and write specialized versions of the procs and stuff them in there.
You then need to add the RDMBS name to the known db names, and add some code to bootstrap/installer including checks to make sure the right db and version's mapped to the pools, and off you go.
We don't have an approach that lets us define an 00-database-procs-odbc.tcl and then map several DB's atop it. My guess is that there will still be DB differences, i.e. in procedural languages, that will require specialization even though they may use the generic odbc driver to connect to the RDBMS.