luasqL -- iterator from manual does not work -- cursor still open

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

luasqL -- iterator from manual does not work -- cursor still open

douglas mcallaster
Folks,

I'm brand new to Lua.
Using LuaSql could be very cool.

Below code has two test scripts: 
the first one works
but the second one fails -- per my comments on the two cursor:close() lines

Would a kind soul edit the second one so that it would work?
I really am new, so I need explicit corrections
==============================
---------------------------------
-- below job does work, very cool:
---------------------------------
require      "luasql.sqlite3"
env = assert (luasql.sqlite3())
con = assert (env:connect("try1.db"))
cur = assert (con:execute[[SELECT name, email from people]])
row = cur:fetch ({}, "a")
while row do
  print(string.format([[
  Name: %s, Email: %s]]
  ,row.email))
  row = cur:fetch (row, "a")
end
cur:close()
con:close()
env:close()
--------------------------------------------------------
-- but below iterator (from luasql manual) does NOT work
--------------------------------------------------------
function rows (connection, sql_statement)
  local cursor = assert (connection:execute (sql_statement))
  return function ()
    return cursor:fetch()
  end
end

require      "luasql.sqlite3"
env = assert (luasql.sqlite3())
con = assert (env:connect("try1.db"))
for name, email in rows (con, "select name, email from people") do
  print (string.format ("%s: %s", name, email))
end
--cursor:close()  without this statement error is: there are open cursors
cursor:close()    -- with this statement error is: attempt to index global cursor
con:close()
env:close()

Reply | Threaded
Open this post in threaded view
|

Re: luasqL -- iterator from manual does not work -- cursor still open

Tomás Guisasola-2
Hi Douglas

The function 'rows' could return the cursor along with the iterator:

-- NOT TESTED
function rows (connection, sql_statement)
  local cursor = assert (connection:execute (sql_statement))
  return function ()
    return cursor:fetch()
  end, cursor -- this line changed!
end

But in that case, you'll have to change the loop:

-- NOT TESTED
...
local iter, cursor = rows (con, "select name, email from people")
for name, email in iter do
  print (string.format ("%s: %s", name, email))
end
cursor:close()
...

Some drivers might close the cursor when the last result is reached,
such as Postgres and SQLite 3.  The problem with the code you posted
is about visibility, not closing cursors :-)

Regards,
Tomás

Em seg, 15 de abr de 2019 às 10:41, douglas mcallaster
<[hidden email]> escreveu:

>
> Folks,
>
> I'm brand new to Lua.
> Using LuaSql could be very cool.
>
> Below code has two test scripts:
> the first one works
> but the second one fails -- per my comments on the two cursor:close() lines
>
> Would a kind soul edit the second one so that it would work?
> I really am new, so I need explicit corrections
> ==============================
> ---------------------------------
> -- below job does work, very cool:
> ---------------------------------
> require      "luasql.sqlite3"
> env = assert (luasql.sqlite3())
> con = assert (env:connect("try1.db"))
> cur = assert (con:execute[[SELECT name, email from people]])
> row = cur:fetch ({}, "a")
> while row do
>   print(string.format([[
>   Name: %s, Email: %s]]
>   ,row.name
>   ,row.email))
>   row = cur:fetch (row, "a")
> end
> cur:close()
> con:close()
> env:close()
> --------------------------------------------------------
> -- but below iterator (from luasql manual) does NOT work
> --------------------------------------------------------
> function rows (connection, sql_statement)
>   local cursor = assert (connection:execute (sql_statement))
>   return function ()
>     return cursor:fetch()
>   end
> end
>
> require      "luasql.sqlite3"
> env = assert (luasql.sqlite3())
> con = assert (env:connect("try1.db"))
> for name, email in rows (con, "select name, email from people") do
>   print (string.format ("%s: %s", name, email))
> end
> --cursor:close()  without this statement error is: there are open cursors
> cursor:close()    -- with this statement error is: attempt to index global cursor
> con:close()
> env:close()
>