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

Reply via email to