It was thus said that the Great Daniel Gruno once stated:
> With regards to how :query should work, this could either be done
> synchronously, wherein all rows are fetched at once, or async where rows
> are fetched as needed. The sync way is rather easy, but could fill up
> more memory than needed, while the async has a smaller footprint but
> proves rather difficult to implement, as the darn dbd driver keeps
> wanting to free up the result set before it's finished being used
> (apr_dbd_get_row keeps segfaulting when I request a row that is out of
> bounds... :( ). Also,there is the consideration of what happens if you
> query a db, get a result set, close the db handle and try to fetch more
> rows - this would most likely result in a segfault, as the db handle
> would have been freed when you try to use it again (how to check that?).
> Also, getting the number of rows, or even doing: for k, v in pairs(rows)
> ... proves to be quite difficult with the async method.
>
> What I've pieced together so far would work something like this:
>
> local results, err = db:query("SELECT .....")
> it not err then
> -- Async method here:
> local x = 1
> local row = results(x) -- fetch row 1
> while row do
> ....
> x = x + 1
> row = results(x) -- fetch row 2,3,4,5...N
> end
>
> -- Sync method here:
> local rows = results() -- fetch all rows at once
> for index, row in pairs(rows) do
> ....
> end
> end
You could always create an interator for the results and hide the method
(sync/async) behind it:
function db:query(q)
...
local function results_async()
local function getnext(state) -- state is the db "object"
return db:results_next(state)
end
return getnext,self
end
local function results_sync()
local row = db:results_all(db)
return pairs(row)
end
...
return results_async,err
end
local results, err = db:query("SELECT ... ")
if not err then
for row in results() do
blah_de_blah_blah()
end
end
Untested code and all that (so it may very be wrong, but the intent is
there)
-spc