суббота, 10 октября 2009 г.

Подготовка sql-запроса для SQLite в tcl

При создании видов биндинг переменных невозможен, потому приходится генерировать sql-строку с уже подставленными значениями переменных. Для того, чтобы это сделать безопасно, SQLite предоставляет функцию quote(). При использовании несуществующих переменных приведенная ниже функция ::dataset::prepare выдаст ошибку, в то время как стандартный механизм биндинга переменных в таком случае подставляет значение NULL.

Пример использования:

package require sqlite3
sqlite3 db :memory:
set i 1
set j a1
array set info {1 a b 2}
puts [::dataset::prepare db {create view view_test as select $i union select $j union select $info(1) union select $info(b)} i j info]
create view view_test as select 1 union select 'a1' union select 'a' union select 2


Реализация:

proc ::dataset::prepare {handler sql args} {
foreach arg $args {
upvar 0 $arg name
if {[uplevel 1 [list array exists $arg]]} {
foreach {key val} [uplevel 1 [list array get $arg]] {
set name($key) [$handler onecolumn {select quote($val)}]
}
} else {
set name [uplevel 1 [list set $arg]]
set name [$handler onecolumn {select quote($name)}]
}
}
return [subst -nobackslashes -nocommands $sql]
}


P.S. Порядок следования имен переменных в аргументах функции ::dataset::prepare значения не имеет.

Комментариев нет:


(C) Alexey Pechnikov aka MBG, mobigroup.ru