views:

356

answers:

3

LuaSQL, which seems to be the canonical library for most SQL database systems in Lua, doesn't seem to have any facilities for quoting/escaping values in queries. I'm writing an application that uses SQLite as a backend, and I'd love to use an interface like the one specified by Python's DB-API:

c.execute('select * from stocks where symbol=?', t)

but I'd even settle for something even dumber, like:

conn:execute("select * from stocks where symbol=" + luasql.sqlite.quote(t))

Are there any other Lua libraries that support quoting for SQLite? (LuaSQLite3 doesn't seem to.) Or am I missing something about LuaSQL? I'm worried about rolling my own solution (with regexes or something) and getting it wrong. Should I just write a wrapper for sqlite3_snprintf?

+3  A: 

I haven't looked at LuaSQL in a while but last time I checked it didn't support it. I use Lua-Sqlite3.

require("sqlite3")

db = sqlite3.open_memory()

db:exec[[ CREATE TABLE tbl( first_name TEXT, last_name TEXT ); ]]

stmt = db:prepare[[ INSERT INTO tbl(first_name, last_name) VALUES(:first_name, :last_name) ]]

stmt:bind({first_name="hawkeye", last_name="pierce"}):exec()
stmt:bind({first_name="henry", last_name="blake"}):exec()

for r in db:rows("SELECT * FROM tbl") do
    print(r.first_name,r.last_name)
end
uroc
Awesome. Thanks to both of you for pointing me in the right direction, and thanks also for the illustrative example. I wish I could "accept" both answers.
adrian
did you mean to use :bind_names instead of :bind?
Henk
+4  A: 

LuaSQLite3 as well an any other low level binding to SQLite offers prepared statements with variable parameters; these use methods to bind values to the statement parameters. Since SQLite does not interpret the binding values, there is simply no possibility of an SQL injection. This is by far the safest (and best performing) approach.

uroc shows an example of using the bind methods with prepared statements.

Doug Currie
Parameterized sql statements are indeed much faster because sqlite doesn't have to reparse every sql statement to determine the execution plan when you bind your variables. See also here: http://stackoverflow.com/questions/904796/how-do-i-get-around-the-problem-in-sqlite-and-c/926251#926251
tuinstoel
A: 

By the way in Lua SQL there is an undocumented escape function for the sqlite3 driver in conn:escape where conn is a connection variable.

For example with the code

print ("con:escape works. test'test = "..con:escape("test'test"))

the result is:

con:escape works. test'test = test''test

I actually tried that to see what it'd do. Apparently there is also such a function for their postgres driver too. I found this by looking at the tests they had.

Hope this helps.

Arle Nadja