You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rivet-dev@tcl.apache.org by Michael Schlenker <sc...@uni-oldenburg.de> on 2005/11/02 14:44:45 UTC
Comparing nstcl-database with DIO and XOSql (long)
Hi all,
while looking for a database abstraction layer i had a look at
nstcl-database (http://nstcl.sourceforge.net), basically a compatibility
package to aolservers database api, and also looked at the rivet DIO
package. I also took a cursory look at XOSql
(http://www.xdobry.de/xosql/index.html)
So i started with a simple features checklist:
Supported Databases:
--------------------------------------------
MySQL nstcl, DIO, XOSql
PostgreSQL nstcl, DIO, XOSql
Sybase (equiv to MS SQL) nstcl
SQLite nstcl, DIO, XOSql
Oracle nstcl, XOSql
Solid nstcl
ODBC nstcl, XOSql
use Perl DBI XOSQL
--------------------------------------------
Not much of a concern, as adding new databases to DIO looks as easy as
it is for nstcl, just adding some small wrapper procs.
License:
--------------------------------------------
DIO Apache License
nstcl MIT/X11 License
XOSql GNU General Public License
--------------------------------------------
OO Style:
--------------------------------------------
DIO incrTcl
nstcl none
XOSql XOTcl
--------------------------------------------
Basic Functionalities:
executing a SQL query
--------------------------------------------
DIO $db exec $query
nstcl db_dml statement1 $query (*)
XOSql $db execute $query
--------------------------------------------
(* This is for a query modifing a value)
getting a single value from an SQL query
--------------------------------------------
DIO set string [$db string $query]
nstcl set string [database_to_tcl_string $dbhandle $query]
XOSql set string [lindex [[$db query $query] fetch] 0]
--------------------------------------------
getting one row of a SQL query into an array
--------------------------------------------
DIO $db array $query $arrayVar
nstcl* db_1row statement2 $query -columnVar $arrayVar
XOSql set rObj [$db query $query]
set keys [$rObj columNames]
set values [$rObj fetch]
foreach key $keys value $values {
set $arrayVar($key) $value
}
--------------------------------------------
(* nstcl errors out if 0 or more than one row is returned)
loop over the rows of a SQL query
(Example: set query "SELECT id,name FROM person")
--------------------------------------------
DIO set rObj [$db exec $query]
$rObj forall -array result {
puts "$result(id) -> $result(name)"
}
nstcl db_foreach statement3 $query {
puts "$id -> $name"
}
XOSql set rObj [$db query $query]
while {[llength [set row [$rObj fetch]]]} {
puts "[lindex $row 0] -> [lindex $row 1]"
}
--------------------------------------------
nstcl's style risks accidental overwriting of variables,
which could lead to security problems.
getting the first column of a SQL query as list
-----------------------------------------------
DIO set list [$db list $query]
nstcl set list [db_list statement4 $query]
XOSql set rObj [$db query $query]
set list [list]
while {[llength [set row [$rObj fetch]]]} {
lappend list [lindex $row 0]
}
-----------------------------------------------
Getting the whole result as nested list of lists
------------------------------------------------
DIO set llist [list]
set rObj [$db exec $query]
$rObj forall -list row {lappend llist $row}
nstcl set llist [db_list_of_lists statement5 $query]
XOSql set llist [$db queryList $query]
------------------------------------------------
Get the number of affected rows for a query
------------------------------------------------
DIO set rObj [$db exec $query]
set numRows [$rObj numrows]
nstcl* ?
XOSql set rObj [$db execute $query]
set numRows [$rObj rows]
------------------------------------------------
(* no idea after just looking at the docs)
Inserting a new row into the database
------------------------------------------------
DIO $db insert $arrayVar -table demo
nstcl* set id $arrayVar(id)
set name $arrayVar(id)
db_dml statement {
insert into demo (id , name) values (:id, :name)
}
XOSql set keys [array names $arrayVar]
set values [list]
foreach key $keys {lappend values $arrayVar($key)}
$db inserRow demo $keys $values
--------------------------------------------------------
(* not sure if the bind variable feature supports arrays,
the first two lines may be superfluous.)
Inserting a new row with automatic id
--------------------------------------------------------
DIO $db insert $arrayVar -table demo \
-keyfield id -autokey 1 -sequence demo_seq
nstcl* set name $arrayVar(name)
db_dml statement {
insert into demo (id, name)
values (
(select * FROM nextval(demo_seq)
), :name)
}
XOSql set keys [array names $arrayVar]
set values [list]
foreach key $keys {lappend values $arrayVar($key)}
$db rowInsertAutoId demo $keys $values id $sequencer **
--------------------------------------------------------
(* basically no support for automatic ids, use what the
underlying database provides)
(** I couldn't figure out from the docs what exactly has to be provided
by sequencer)
Delete a record from the database by primary key
--------------------------------------------------------
DIO $db delete $key -table demo -keyfield id
nstcl db_dml statement {
delete from demo where id = :id
}
XOSql* $db execute "delete from demo where id = $id"
--------------------------------------------------------
(* not sure if any quoting is done, may be a security problem)
Transaction support
--------------------------------------------------------
DIO $db exec {BEGIN TRANSACTION}
...
# do some operations
...
$db exec {COMMIT TRANSACTION}
nstcl* db_transaction {
...
# do some operations
...
}
XOSql $db execute {BEGIN TRANSACTION}
...
# do some operations
...
$db execute {COMMIT TRANSACTION}
---------------------------------------------------------
Basically neither DIO nor XOSql seem to have any real
transaction support.nstcl supports optional code to eval in case
of errors during a transaction to decide on commit or rollback.
Quoting support, for dynamic queries
---------------------------------------------------------
DIO* attempts autoquoting of values in queries,
XOSql provides escape method for simple value quoting
nstcl binding variables for queries with autoquoting
functions to quote identifiers and values
---------------------------------------------------------
* The current practice in DIO is insecure and is an SQL injection attack
vector. Only values are quoted. Identifiers (table and field names) are
passed to the database without any quoting.
Value quoting seems broken and incomplete. It does not take SQL quoting
rules into account, which may lead to data inconsistencies.
Example of SQL Injection:
set table users
set match {'\' OR 1==1; --}
$obj exec "SELECT * FROM $table WHERE id = $match AND password = $passwd;"
Similar issues may be present in XOSql and nstcl but i did not take a
closer look.
Conclusions:
-------------------------------------------------------------
All three interfaces behave quite similar for simple queries,
only differing in style of commands (OO vs. procedural) and
arguments/results available (objs, lists, nested lists, arrays).
Mostly a matter of taste.
XOSql offers the interesting option to use the Perl DBI drivers with
the help of an extension of the same author. Similar things could
probably easily be done with TclBlend and JDBC drivers.
For complexer scenarios both XOSql and DIO are missing support for
handling transactions.
nstcl's database support adds support for bind variables for all
databases, based on some simple tcl procs, which could be adopted by DIO
and XOSql. Even better would be to use the binding functions and support
for prepared statements of the underlying database. At least SQLlite and
newer Pgtcl versions support some form of binding variables.
To provide appropriate quoting support, all layers should look at the db
interfaces and use the database specific quoting functions (available at
least for mysql, postgres) and provide a compatibility function based on
the SQL standard + variations for each db driver for all others.
I have not yet looked at the DIODisplay and the nstcl multirow
datasource features, which look interesting.
Hope this is interesting or informative for some of you
Michael Schlenker
---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.apache.org
For additional commands, e-mail: rivet-dev-help@tcl.apache.org
Re: Comparing nstcl-database with DIO and XOSql (long)
Posted by Wojciech Kocjan <wo...@kocjan.org>.
Dnia 02-11-2005 o 14:44:45 Michael Schlenker <sc...@uni-oldenburg.de>
napisaĆ:
> Hi all,
>
> while looking for a database abstraction layer i had a look at
> nstcl-database (http://nstcl.sourceforge.net), basically a compatibility
> package to aolservers database api, and also looked at the rivet DIO
> package. I also took a cursory look at XOSql
> (http://www.xdobry.de/xosql/index.html)
Could you also take a look at tcldb?
It's located in http://sourceforge.net/projects/dqsoftware/
Some of my comments:
1/ it's really impossible to provide SQL-injection proof toolkit. Well,
almost impossible. But making $db exec "INSERT INTO table
VALUES('$x','$y')" sounds a bit impossible to me.
Tcldb does that by doing:
$db exec "INSERT INTO table VALUES('@X@','@Y@')" x $x y $y (it quotes
according to current database's quoting rules)
2/ You should insert some speed tests - ie 1000 inserts, large selects etc.
3/ Could you also include sqlite in the databases? I find it a great db.
4/ Otherwise a very interesting text.
--
WK
---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.apache.org
For additional commands, e-mail: rivet-dev-help@tcl.apache.org