diff -pruN 2.6.0-3/Makefile 2.7.0-1/Makefile
--- 2.6.0-3/Makefile	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/Makefile	2025-04-23 23:51:04.000000000 +0000
@@ -1,4 +1,4 @@
-V= 2.6.0
+V= 2.7.0
 CONFIG= ./config
 
 include $(CONFIG)
@@ -16,7 +16,7 @@ SPACE= $(EMPTY) $(EMPTY)
 all : 
 	@echo "usage: make { $(subst $(SPACE),$(SPACE)|$(SPACE),$(DRIVER_LIST)) }"
 
-# explicity matches against the list of avilable driver names
+# explicitly matches against the list of available driver names
 $(DRIVER_LIST) : % : src/%.so
 
 # builds the specified driver
diff -pruN 2.6.0-3/README 2.7.0-1/README
--- 2.6.0-3/README	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/README	2025-04-23 23:51:04.000000000 +0000
@@ -1,13 +1,13 @@
 LuaSQL
-http://keplerproject.github.io/luasql
+https://lunarmodules.github.io/luasql/
 
 LuaSQL is a simple interface from Lua to a DBMS. It enables a Lua program to:
 
-    * Connect to ODBC, ADO, Oracle, MySQL, SQLite, Firebird and PostgreSQL databases; 
+    * Connect to ODBC, ADO, Oracle, MySQL, SQLite, Firebird and PostgreSQL databases;
     * Execute arbitrary SQL statements;
     * Retrieve results in a row-by-row cursor fashion.
 
-LuaSQL is free software and uses the same license as Lua 5.1. 
+LuaSQL is free software and uses the same license as Lua 5.1.
 
 
 Source code for LuaSQL can be downloaded from its GitHub repository.
diff -pruN 2.6.0-3/config 2.7.0-1/config
--- 2.6.0-3/config	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/config	2025-04-23 23:51:04.000000000 +0000
@@ -46,9 +46,8 @@ DRIVER_LIBS_firebird ?= -L/usr/local/fir
 DRIVER_INCS_firebird ?=
 
 # general compilation parameters
-WARN = -Wall -Wmissing-prototypes -Wmissing-declarations -pedantic
+WARN= -fPIC $(OPTFLAGS) -Wmissing-prototypes -Wmissing-declarations -ansi -pedantic
 INCS = -I$(LUA_INC)
-DEFS =
-CFLAGS = -O2 -std=gnu99 $(WARN) -fPIC $(DRIVER_INCS) $(INCS) \
-         -DLUASQL_VERSION_NUMBER='"$V"' $(DEFS)
+DEFS = -std=gnu99 -fPIC
+CFLAGS=$(WARN) $(DRIVER_INCS) $(INCS) -DLUASQL_VERSION_NUMBER='"$V"' $(DEFS)
 CC= gcc
diff -pruN 2.6.0-3/debian/changelog 2.7.0-1/debian/changelog
--- 2.6.0-3/debian/changelog	2024-08-12 09:08:53.000000000 +0000
+++ 2.7.0-1/debian/changelog	2025-08-15 10:52:03.000000000 +0000
@@ -1,3 +1,13 @@
+lua-sql (2.7.0-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream release (closes: #1063730).
+  * Refresh patches.
+  * Add a patch from upstream which implements missing cur_gc function
+    in ls_odbc.c.
+
+ -- Sergei Golovan <sgolovan@debian.org>  Fri, 15 Aug 2025 13:52:03 +0300
+
 lua-sql (2.6.0-3) unstable; urgency=medium
 
   * Team upload.
diff -pruN 2.6.0-3/debian/patches/0001-doc-br-remove-img-link-to-w3.org-validator-icon.patch 2.7.0-1/debian/patches/0001-doc-br-remove-img-link-to-w3.org-validator-icon.patch
--- 2.6.0-3/debian/patches/0001-doc-br-remove-img-link-to-w3.org-validator-icon.patch	2024-08-12 09:08:53.000000000 +0000
+++ 2.7.0-1/debian/patches/0001-doc-br-remove-img-link-to-w3.org-validator-icon.patch	2025-08-15 10:52:03.000000000 +0000
@@ -10,24 +10,20 @@ Subject: doc/br: remove img link to w3.o
  doc/br/manual.html   | 2 +-
  5 files changed, 5 insertions(+), 7 deletions(-)
 
-diff --git a/doc/br/examples.html b/doc/br/examples.html
-index cc4ecc1..4edd1eb 100644
 --- a/doc/br/examples.html
 +++ b/doc/br/examples.html
-@@ -155,7 +155,7 @@ se ainda existem mais linhas).</p>
+@@ -146,7 +146,7 @@
  </div> <!-- id="main" -->
  
  <div id="about">
 -	<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
 +	<p><a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.0!</a></p>
- 	<p><small>
- 		$Id: examples.html,v 1.7 2008/06/11 00:26:13 jasonsantos Exp $
- 	</small></p>
-diff --git a/doc/br/history.html b/doc/br/history.html
-index 4ad4642..b36addc 100644
+ </div> <!-- id="about" -->
+ 
+ </div> <!-- id="container" -->
 --- a/doc/br/history.html
 +++ b/doc/br/history.html
-@@ -118,8 +118,7 @@ na implementa&ccedil;&atilde;o em rela&ccedil;&atilde;o &agrave; vers&atilde;o 1
+@@ -112,8 +112,7 @@
  </div> <!-- id="main" -->
  
  <div id="about">
@@ -37,11 +33,9 @@ index 4ad4642..b36addc 100644
  	<p><small>$Id: history.html,v 1.11 2008/06/11 00:26:13 jasonsantos Exp $</small>
      </p>
  </div> <!-- id="about" -->
-diff --git a/doc/br/index.html b/doc/br/index.html
-index c7019be..47b998a 100644
 --- a/doc/br/index.html
 +++ b/doc/br/index.html
-@@ -150,8 +150,7 @@ e usu&aacute;rios da plataforma Kepler.
+@@ -152,8 +152,7 @@
  </div> <!-- id="main" -->
  
  <div id="about">
@@ -51,24 +45,20 @@ index c7019be..47b998a 100644
  	<p><small>$Id: index.html,v 1.9 2008/06/11 00:26:13 jasonsantos Exp $</small>
      </p>
  </div> <!-- id="about" -->
-diff --git a/doc/br/license.html b/doc/br/license.html
-index 085b71f..5d8a2b2 100644
 --- a/doc/br/license.html
 +++ b/doc/br/license.html
-@@ -112,7 +112,7 @@ THE SOFTWARE.</p>
+@@ -112,7 +112,7 @@
  </div> <!-- id="main" -->
  
  <div id="about">
 -<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
 +	<p><a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.0!</a></p>
  <p><small>
- $Id: license.html,v 1.6 2008/06/11 00:26:13 jasonsantos Exp $
  </small></p>
-diff --git a/doc/br/manual.html b/doc/br/manual.html
-index d2a3af9..7c99fd0 100644
+ </div> <!-- id="about" -->
 --- a/doc/br/manual.html
 +++ b/doc/br/manual.html
-@@ -395,7 +395,7 @@ o driver para SQLite3 ainda oferece uma funcionalidade adicional:</p>
+@@ -393,7 +393,7 @@
  </div> <!-- id="main" -->
  
  <div id="about">
diff -pruN 2.6.0-3/debian/patches/0002-correct-parameter-types-to-fix-ftbfs.patch 2.7.0-1/debian/patches/0002-correct-parameter-types-to-fix-ftbfs.patch
--- 2.6.0-3/debian/patches/0002-correct-parameter-types-to-fix-ftbfs.patch	2024-08-12 09:08:53.000000000 +0000
+++ 2.7.0-1/debian/patches/0002-correct-parameter-types-to-fix-ftbfs.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,40 +0,0 @@
-From: Marko Lindqvist <cazfi74@gmail.com>
-Date: Mon, 7 Feb 2022 00:02:52 +0200
-Subject: [PATCH] ls_odbc.c: Correct parameter types
- Fix compiler warnings about wrong types passed as function parameters
-
---- a/src/ls_odbc.c
-+++ b/src/ls_odbc.c
-@@ -32,11 +32,11 @@
- #define LUASQL_STATEMENT_ODBC "ODBC statement"
- #define LUASQL_CURSOR_ODBC "ODBC cursor"
- 
--/* holds data for paramter binding */
-+/* holds data for parameter binding */
- typedef struct {
- 	SQLPOINTER buf;
--	SQLINTEGER len;
--	SQLINTEGER type;
-+	SQLLEN len;
-+	SQLLEN type;
- } param_data;
- 
- /* general form of the driver objects */
-@@ -685,7 +685,7 @@
- 		return create_cursor(L, -1, stmt, numcols);
- 	} else {
- 		/* if action has no results (e.g., UPDATE) */
--		SQLINTEGER numrows;
-+		SQLLEN numrows;
- 		if(error(SQLRowCount(stmt->hstmt, &numrows))) {
- 			return fail(L, hSTMT, stmt->hstmt);
- 		}
-@@ -697,7 +697,7 @@
- 
- static int set_param(lua_State *L, stmt_data *stmt, int i, param_data *data)
- {
--	static SQLINTEGER cbNull = SQL_NULL_DATA;
-+	static SQLLEN cbNull = SQL_NULL_DATA;
- 
- 	switch(lua_type(L, -1)) {
- 	case LUA_TNIL: {
diff -pruN 2.6.0-3/debian/patches/0002-ls-odbc-implement-missing-cur-gc-function.patch 2.7.0-1/debian/patches/0002-ls-odbc-implement-missing-cur-gc-function.patch
--- 2.6.0-3/debian/patches/0002-ls-odbc-implement-missing-cur-gc-function.patch	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/debian/patches/0002-ls-odbc-implement-missing-cur-gc-function.patch	2025-08-15 10:52:03.000000000 +0000
@@ -0,0 +1,24 @@
+From: Upstream
+Description: Patch adds missing cur_gc function to the ODBC code.
+Last-Modified: Fri, 15 Aug 2025 13:50:25 +0300
+
+--- a/src/ls_odbc.c
++++ b/src/ls_odbc.c
+@@ -493,6 +493,17 @@
+ }
+ 
+ /*
++** Cursor object collector function
++*/
++static int cur_gc (lua_State *L)
++{
++	cur_data *cur = (cur_data *) luaL_checkudata (L, 1, LUASQL_CURSOR_ODBC);
++	if (cur != NULL && !(cur->closed))
++	        cur_shut(L, cur);
++	return 0;
++}
++
++/*
+ ** Closes a cursor.
+ */
+ static int cur_close (lua_State *L)
diff -pruN 2.6.0-3/debian/patches/series 2.7.0-1/debian/patches/series
--- 2.6.0-3/debian/patches/series	2024-08-12 09:08:53.000000000 +0000
+++ 2.7.0-1/debian/patches/series	2025-08-15 10:52:03.000000000 +0000
@@ -1,2 +1,2 @@
 0001-doc-br-remove-img-link-to-w3.org-validator-icon.patch
-0002-correct-parameter-types-to-fix-ftbfs.patch
+0002-ls-odbc-implement-missing-cur-gc-function.patch
diff -pruN 2.6.0-3/doc/br/examples.html 2.7.0-1/doc/br/examples.html
--- 2.6.0-3/doc/br/examples.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/br/examples.html	2025-04-23 23:51:04.000000000 +0000
@@ -1,8 +1,8 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt" lang="pt">
 <head>
-    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</title>
+    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programação Lua</title>
     <link rel="stylesheet" href="doc.css" type="text/css"/>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 </head>
@@ -15,7 +15,7 @@
 		<img alt="LuaSQL logo" src="luasql.png"/>
 	</a></div>
 	<div id="product_name"><big><strong>LuaSQL</strong></big></div>
-	<div id="product_description">Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</div>
+	<div id="product_description">Conectividade de banco de dados para a linguagem de programação Lua</div>
 </div> <!-- id="product" -->
 
 <div id="main">
@@ -24,39 +24,18 @@
 <h1>LuaSQL</h1>
 	<ul>
 		<li><a href="index.html">Home</a>
-			<ul>
-				<li><a href="index.html#overview">Vis&atilde;o Geral</a></li>
-				<li><a href="index.html#status">Status</a></li>
-				<li><a href="index.html#download">Download</a></li>
-				<li><a href="index.html#credits">Cr&eacute;ditos</a></li>
-				<li><a href="index.html#contact">Contato</a></li>
-			</ul>
 		</li>
 		<li><a href="manual.html">Manual</a>
-			<ul>
-				<li><a href="manual.html#introduction">Introdu&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#compiling">Compilando</a></li>
-				<li><a href="manual.html#installation">Instala&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#errors">Tratamento de erros</a></li>
-				<li><a href="manual.html#drivers">Drivers</a></li>
-				<li><a href="manual.html#environment_object">Ambiente</a></li>
-				<li><a href="manual.html#connection_object">Conex&atilde;o</a></li>
-				<li><a href="manual.html#cursor_object">Cursor</a></li>
-				<li><a href="manual.html#postgres_extensions">PostgreSQL</a></li>
-				<li><a href="manual.html#mysql_extensions">MySQL</a></li>
-				<li><a href="manual.html#oracle_extensions">Oracle</a></li>
-				<li><a href="manual.html#sqlite3_extensions">SQLite3</a></li>
-			</ul>
 		</li>
 		<li><strong>Exemplos</strong></li>
-		<li><a href="history.html">Hist&oacute;rico</a></li>
-        <li><a href="http://github.com/keplerproject/luasql">Projeto</a>
+		<li><a href="history.html">Histórico</a></li>
+        <li><a href="https://github.com/lunarmodules/luasql">Projeto</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
-		<li><a href="license.html">Licen&ccedil;a</a></li>
+		<li><a href="license.html">Licença</a></li>
 	</ul>
 </div> <!-- id="navigation" -->
 
@@ -64,12 +43,12 @@
 	
 <h2><a name="examples"></a>Exemplos</h2>
 
-<p>Abaixo, voc&ecirc; ver&aacute; um pequeno exemplo do c&oacute;digo do uso b&aacute;sico da biblioteca.
-Em seguida, outro exemplo mostra como criar um 
+<p>Abaixo, você verá um pequeno exemplo do código do uso básico da biblioteca.
+Em seguida, outro exemplo mostra como criar um
 <a href="#iterator_example">iterador</a> sobre o resultado de uma determinada consulta.</p>
 
 
-<h3><a name="basic_use"></a>Uso b&aacute;sico</h3>
+<h3><a name="basic_use"></a>Uso básico</h3>
 <pre class="example">
 -- carregar o driver
 require "luasql.postgres"
@@ -87,7 +66,7 @@ res = assert (con:execute[[
 ]])
 -- adiciona alguns elementos
 list = {
-  { name="Jos&eacute; das Couves", email="jose@couves.com", },
+  { name="José das Couves", email="jose@couves.com", },
   { name="Manoel Joaquim", email="manoel.joaquim@cafundo.com", },
   { name="Maria das Dores", email="maria@dores.com", },
 }
@@ -112,17 +91,17 @@ con:close()
 env:close()
 </pre>
 
-<p>O resultado desse script ser&aacute;:</p>
+<p>O resultado desse script será:</p>
 
 <pre class="example">
-Nome: Jos&eacute; das Couves, E-mail: jose@couves.com
+Nome: José das Couves, E-mail: jose@couves.com
 Nome: Manoel Joaquim, E-mail: manoel.joaquim@cafundo.com
 Nome: Maria das Dores, E-mail: maria@dores.com
 </pre>
 
 
 <h3><a name="iterator_example"></a>Uso do iterador</h3>
-<p>Pode ser &uacute;til oferecer um iterador para cada registro do resultado:</p>
+<p>Pode ser útil oferecer um iterador para cada registro do resultado:</p>
 
 <pre class="example">
 function rows (connection, sql_statement)
@@ -133,8 +112,8 @@ function rows (connection, sql_statement
 end
 </pre>
 
-<p>Esse iterador &eacute; usado da seguinte forma:</p>
- 
+<p>Esse iterador é usado da seguinte forma:</p>
+
 <pre class="example">
 require "luasql.mysql"
 env = assert (luasql.mysql())
@@ -144,11 +123,23 @@ for id, name, address in rows (con, "sel
 end
 </pre>
 
-<p>A implementa&ccedil;&atilde;o acima utiliza a coleta de lixo de Lua para
-fechar o cursor. Ela pode ser melhorada de modo a apresentar
-mensagens de erro mais adequadas (incluindo o statement SQL por
-exemplo) ou para fechar explicitamente o cursor (verificando
-se ainda existem mais linhas).</p>
+<p>Obviamente, o código acima só funciona se houver uma tabela chamadas <code>contacts</code> com as colunas apropriadas.
+No final do <i>loop</i> o objeto cursor será automaticamente fechado pelo driver, já que todo o resultado foi recuperado.</p>
+
+<h3><a name="To_be_closed"></a>Objetos <i>to-be-closed</i></h3>
+
+<p>
+<strong style="color: red;">Nota de Compatibilidade:</strong>
+Variáveis <i>To-be-closed</i> é um recurso introduzido na versão 5.4 de Lua. Portanto, essa funcionalidade só pode ser usada se o driver LuaSQL (versão &gt; 2.6) for compilado para a versão 5.4 ou superior de Lua.
+</p>
+
+<pre class="example">
+function getName(db, id)
+  -- Este código requer Lua 5.4 ou superior devido ao uso de variáveis to-be-closed
+  local cur &lt;close&gt; = db:execute("SELECT name FROM contacts WHERE id = " .. id)
+  return cur:fetch()
+end
+</pre>
 
 </div> <!-- id="content" -->
 
@@ -156,9 +147,6 @@ se ainda existem mais linhas).</p>
 
 <div id="about">
 	<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
-	<p><small>
-		$Id: examples.html,v 1.7 2008/06/11 00:26:13 jasonsantos Exp $
-	</small></p>
 </div> <!-- id="about" -->
 
 </div> <!-- id="container" -->
diff -pruN 2.6.0-3/doc/br/history.html 2.7.0-1/doc/br/history.html
--- 2.6.0-3/doc/br/history.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/br/history.html	2025-04-23 23:51:04.000000000 +0000
@@ -1,8 +1,8 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt" lang="pt">
 <head>
-    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</title>
+    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programação Lua</title>
     <link rel="stylesheet" href="doc.css" type="text/css"/>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 </head>
@@ -16,7 +16,7 @@
 		<img alt="LuaSQL logo" src="luasql.png"/>
 	</a></div>
 	<div id="product_name"><big><strong>LuaSQL</strong></big></div>
-	<div id="product_description">Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</div>
+	<div id="product_description">Conectividade de banco de dados para a linguagem de programação Lua</div>
 </div> <!-- id="product" -->
 
 <div id="main">
@@ -25,87 +25,81 @@
 <h1>LuaSQL</h1>
 	<ul>
 		<li><a href="index.html">Home</a>
-			<ul>
-				<li><a href="index.html#overview">Vis&atilde;o Geral</a></li>
-				<li><a href="index.html#status">Status</a></li>
-				<li><a href="index.html#download">Download</a></li>
-				<li><a href="index.html#credits">Cr&eacute;ditos</a></li>
-				<li><a href="index.html#contact">Contato</a></li>
-			</ul>
 		</li>
 		<li><a href="manual.html">Manual</a>
-			<ul>
-				<li><a href="manual.html#introduction">Introdu&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#compiling">Compilando</a></li>
-				<li><a href="manual.html#installation">Instala&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#errors">Tratamento de erros</a></li>
-				<li><a href="manual.html#drivers">Drivers</a></li>
-				<li><a href="manual.html#environment_object">Ambiente</a></li>
-				<li><a href="manual.html#connection_object">Conex&atilde;o</a></li>
-				<li><a href="manual.html#cursor_object">Cursor</a></li>
-				<li><a href="manual.html#postgres_extensions">PostgreSQL</a></li>
-				<li><a href="manual.html#mysql_extensions">MySQL</a></li>
-				<li><a href="manual.html#oracle_extensions">Oracle</a></li>
-				<li><a href="manual.html#sqlite3_extensions">SQLite3</a></li>
-			</ul>
 		</li>
 		<li><a href="examples.html">Exemplos</a></li>
-		<li><strong>Hist&oacute;rico</strong></li>
+		<li><strong>Histórico</strong></li>
         <li><a href="http://github.com/keplerproject/luasql">Projeto</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
-		<li><a href="license.html">Licen&ccedil;a</a></li>
+		<li><a href="license.html">Licença</a></li>
 	</ul>
 </div> <!-- id="navigation" -->
 
 <div id="content">
 
-<h2><a name="history"></a>Hist&oacute;ria</h2>
+<h2><a name="history"></a>História</h2>
 
 <dl class="history">
+    <dt><strong>LuaSQL 2.7.0</strong> [23/04/2025]</dt>
+    <dd>
+      <ul>
+        <li>Adaptação de todos os drivers para a versão 5.4 de Lua com suporte a variáveis <i>to-be-closed</i></li>
+        <li>Padronização da implementação do método <code>:close()</code> para retornar false seguido de uma string quando houver objetos relacionados ainda abertos.</li>
+      </ul>
+    </dd>
+
+    <dt><strong>LuaSQL 2.6.1</strong> [07/02/2024]</dt>
+    <dd>
+      <ul>
+        <li>Correção na compatibilidade do driver SQLite3 para versões anteriores a Lua 5.3 (agradecimento a Daniel McCarney)</li>
+      </ul>
+    </dd>
+
     <dt><strong>2.0.2</strong> [26/06/2006]</dt>
-    <dd>M&eacute;todo <a href="manual.html#mysql_extensions">numrows</a> acrescentado ao driver MySQL.<br />
+    <dd>Método <a href="manual.html#mysql_extensions">numrows</a> acrescentado ao driver MySQL.<br />
     Adicionado um arquivo <code>config</code> para o <code>makefile</code>.<br />
-    Adicionada configura&ccedil;&atilde;o do driver LinuxODBC.<br />
+    Adicionada configuração do driver LinuxODBC.<br />
     Corrigiu um bug no driver SQLite (bug encontrado por Mike Petersen).<br />
     Corrigiu bugs nos drivers JDBC, OCI8 e ADO.<br />
     Testes melhorados.<br />
-    Documenta&ccedil;&atilde;o melhorada.<br />
+    Documentação melhorada.<br />
     </dd>
-    
+
     <dt><strong>2.0.1</strong> [02/06/2005]</dt>
     <dd>Corrigiu alguns erros relativos ao driver ODBC.</dd>
-    
+
     <dt><strong>2.0.0</strong> [22/03/2005]</dt>
     <dd>Novo driver ADO e corrigiu alguns erros relativos ao driver ODBC.</dd>
-    
+
     <dt><strong>2.0 beta 3</strong> [23/12/2004]</dt>
     <dd>Corrigiu apenas alguns pequenos erros.</dd>
-  
+
     <dt><strong>2.0 beta 2</strong> [26/11/2004]</dt>
     <dd>Corrigiu alguns erros e introduziu os novos drivers SQLite and JDBC.
-    Utiliza a 
+    Utiliza a
     <a href="http://www.keplerproject.org/compat/">proposta de pacotes</a>
     para Lua 5.1. Veja mais detalhes em
-    <a href="manual.html#installation">Instala&ccedil;&atilde;o</a>.
+    <a href="manual.html#installation">Instalação</a>.
     </dd>
-    
+
     <dt><strong>2.0 beta</strong> [10/12/2003]</dt>
 </dl>
 
 
 <p>
-A vers&atilde;o 2.0 apresenta algumas modifica&ccedil;&otilde;es no design e aprimoramentos
-na implementa&ccedil;&atilde;o em rela&ccedil;&atilde;o &agrave; vers&atilde;o 1.0:
+A versão 2.0 apresenta algumas modificações no design e aprimoramentos
+na implementação em relação à versão 1.0:
 </p>
 <ul>
-  <li>Novo m&eacute;todo de <code>fetch</code>: mais eficiente e mais flex&iacute;vel;</li>
-  <li>Novo m&eacute;todo de <code>setautocommit</code>;</li>
-  <li>Compat&iacute;vel com Lua 5.0 e 5.1;</li>
-  <li>Carreg&aacute;vel dinamicamente ou estaticamente;</li>
+  <li>Novo método de <code>fetch</code>: mais eficiente e mais flexível;</li>
+  <li>Novo método de <code>setautocommit</code>;</li>
+  <li>Compatível com Lua 5.0 e 5.1;</li>
+  <li>Carregável dinamicamente ou estaticamente;</li>
   <li>Novos drivers para bancos de dados Oracle e MySQL.</li>
 </ul>
 
diff -pruN 2.6.0-3/doc/br/index.html 2.7.0-1/doc/br/index.html
--- 2.6.0-3/doc/br/index.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/br/index.html	2025-04-23 23:51:04.000000000 +0000
@@ -1,22 +1,21 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt" lang="pt">
 <head>
-    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</title>
+    <title>LuaSQL: Conectividade de banco de dados para a linguagem de programação Lua</title>
     <link rel="stylesheet" href="doc.css" type="text/css"/>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 </head>
-
 <body>
 
 <div id="container">
 	
 <div id="product">
-	<div id="product_logo"><a href="http://www.keplerproject.org">
+	<div id="product_logo"><a href="https://github.com/lunarmodules/luasql">
 		<img alt="LuaSQL logo" src="luasql.png"/>
 	</a></div>
 	<div id="product_name"><big><strong>LuaSQL</strong></big></div>
-	<div id="product_description">Conectividade de banco de dados para a linguagem de programa&ccedil;&atilde;o Lua</div>
+	<div id="product_description">Conectividade de banco de dados para a linguagem de programação Lua</div>
 </div> <!-- id="product" -->
 
 <div id="main">
@@ -26,123 +25,126 @@
 	<ul>
 		<li><strong>Home</strong>
 			<ul>
-				<li><a href="index.html#overview">Vis&atilde;o Geral</a></li>
+				<li><a href="index.html#overview">Visão Geral</a></li>
 				<li><a href="index.html#status">Status</a></li>
 				<li><a href="index.html#download">Download</a></li>
-				<li><a href="index.html#credits">Cr&eacute;ditos</a></li>
+				<li><a href="index.html#credits">Créditos</a></li>
 				<li><a href="index.html#contact">Contato</a></li>
 			</ul>
 		</li>
 		<li><a href="manual.html">Manual</a>
-			<ul>
-				<li><a href="manual.html#introduction">Introdu&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#compiling">Compilando</a></li>
-				<li><a href="manual.html#installation">Instala&ccedil;&atilde;o</a></li>
-				<li><a href="manual.html#errors">Tratamento de erros</a></li>
-				<li><a href="manual.html#drivers">Drivers</a></li>
-				<li><a href="manual.html#environment_object">Ambiente</a></li>
-				<li><a href="manual.html#connection_object">Conex&atilde;o</a></li>
-				<li><a href="manual.html#cursor_object">Cursor</a></li>
-				<li><a href="manual.html#postgres_extensions">PostgreSQL</a></li>
-				<li><a href="manual.html#mysql_extensions">MySQL</a></li>
-				<li><a href="manual.html#oracle_extensions">Oracle</a></li>
-				<li><a href="manual.html#sqlite3_extensions">SQLite3</a></li>
-			</ul>
 		</li>
 		<li><a href="examples.html">Exemplos</a></li>
-		<li><a href="history.html">Hist&oacute;rico</a></li>
-        <li><a href="http://github.com/keplerproject/luasql/">Project</a>
+		<li><a href="history.html">Histórico</a></li>
+        <li><a href="https://github.com/lunarmodules/luasql">Projeto</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug tracker</a></li>
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug tracker</a></li>
             </ul>
         </li>
-		<li><a href="license.html">Licen&ccedil;a</a></li>
+		<li><a href="license.html">Licença</a></li>
 	</ul>
 </div> <!-- id="navigation" -->
 
 <div id="content">
-<h2><a name="overview"></a>Vis&atilde;o Geral</h2>
+
+<h2><a name="overview"></a>Visão Geral</h2>
+
 <p>
-LuaSQL &eacute; uma interface simples entre Lua e um sistema gerenciador de banco de dados (DBMS). Ela permite que um programa Lua:
+LuaSQL é uma interface simples entre Lua e um sistema gerenciador de banco de dados (DBMS). Ela permite que um programa Lua:
 </p>
+
 <ul>
 	<li> Conecte-se aos bancos de dados ODBC, ADO, Oracle, MySQL, SQLite, JDBC e PostgreSQL;</li>
-	<li> Execute comandos arbrit&aacute;rios do SQL;</li>
+	<li> Execute comandos arbritários através de SQL;</li>
 	<li> Recupere resultados no modo linha-a-linha de um cursor SQL.</li>
 </ul>
 
 <p>
-LuaSQL &eacute; um software livre e utiliza a mesma <a href="license.html">licen&ccedil;a</a>
-do Lua 5.0.
+LuaSQL é um software livre e utiliza a mesma <a href="license.html">licença</a>
+de Lua 5.1.
 </p>
 
 <h2><a name="status"></a>Status</h2>
-<p>A vers&atilde;o LuaSQL 2.0.2 (para Lua 5.0) est&aacute; dispon&iacute;vel para
-<a href="#download">download</a>.
-</p>
 
-<p>O driver PostgreSQL foi testado em Windows, Linux e MacOS X e &eacute; compat&iacute;vel com
-PostgreSQL 7.x e 8.x.</p>
-<p>O driver ODBC foi testado em Windows (drivers SQLServer e Microsoft Access).</p>
-<p>O driver MySQL foi testado em Windows, Linux e &eacute; compat&iacute;vel com as vers&otilde;es 4.0, 4.1 e 5.0.</p>
-<p>O driver Oracle foi testado em Windows e &eacute; compat&iacute;vel com OCI 8 API.</p>
-<p>O driver SQLite foi testado em Windows e Linux e &eacute; compat&iacute;vel com as vers&otilde;es 2.x.</p>
-<p>O driver JDBC foi testado em Windows com LuaJava 1.0 e JDK 1.4 (driver MySQL).</p> 
-<p>O driver ADO foi testado em Windows, com LuaCOM 1.3 (driver Microsoft Access).</p>
+<p>
+A versão LuaSQL 2.7.0 (para Lua 5.X) está disponível para <a href="#download">download</a>.
+Para mais detalhes sobre as funcionalidades de cada versão, confira o <a href="history.html">histórico</a>.
+</p>
 
 <h2><a name="download"></a>Download</h2>
 <p>
-LuaSQL pode ser instalado via <a href="http://luarocks.org">LuaRocks</a>, usando
-o driver do seu banco de dados escolhido:
+LuaSQL pode ser instalado via <a href="https://luarocks.org">LuaRocks</a>, usando
+o driver do banco de dados de sua escolha:
 
-<pre>
-luarocks install luasql-sqlite3
-luarocks install luasql-postgres
+<pre class="example">
+luarocks install luasql-firebird
 luarocks install luasql-mysql
-luarocks install luasql-sqlite
+luarocks install luasql-oci8
 luarocks install luasql-odbc
+luarocks install luasql-postgres
+luarocks install luasql-sqlite
+luarocks install luasql-sqlite3
 </pre>
 
-O código fonte do LuaSQL pode ser baixado do seu repositório no <a href=
-"http://github.com/keplerproject/luasql">GitHub</a>.
+O código fonte da LuaSQL pode ser baixado do seu repositório no <a href="https://github.com/lunarmodules/luasql">GitHub</a>.
 </p>
 
-<h2><a name="credits"></a>Cr&eacute;ditos</h2>
+<h2><a name="credits"></a>Créditos</h2>
+
+<h4>LuaSQL 2.x</h4>
 
-<h4>LuaSQL 2.0</h4>
 <p>
-A Vers&atilde;o 2.0 foi redesenhada por Roberto Ierusalimschy, Andr&eacute; Carregal
-e Tom&aacute;s Guisasola como parte do
+A versão 2.7 introduz suporte a variáveis <a href="https://lua.org/manual/5.4/">To-be-closed</a> além de adaptar todos os drivers para a versão 5.4 de Lua. <br>Esta versão foi implementada por Chaitanya Deshmukh durante o GSoC 2024 sob a orientação de Tomás Guisasola.
+</p>
+
+<p>
+A versão 2.5 incorpora suporte a busca no resultado no driver MySQL.
+</p>
+<p>
+A versão 2.3.5 incorpora algumas correções e pequenas melhorias (agradecimento a IR4T4 e tomatolog).
+Essa versão funciona com as versões 5.1, 5.2 and 5.3 de Lua.
+</p>
+<p>
+A versão 2.3 é apenas uma adaptação do código para funcionar com as versões 5.0, 5.1 e 5.2 de Lua.
+</p>
+<p>
+A partir da versão 2.2 começou o desenvolvimento distribuído com todas as discussões sobre o projeto acontecendo na <a href="https://groups.google.com/forum/#!forum/kepler-project">lista de interesse do Projeto Kepler</a>.
+Novos desenvolvedores: Hisham Muhammad, Ignacio Burgueño, Luis Eduardo Jason Santos, Marc Nijdam, Mauricio Bomfim and Scott Morgan.
+</p>
+<h4>LuaSQL 2.0 e 2.1</h4>
+<p>
+A versão 2.0 foi redesenhada por Roberto Ierusalimschy, André Carregal
+e Tomás Guisasola como parte do
 <a href="http://www.keplerproject.org">Projeto Kepler</a>.
-A implementa&ccedil;&atilde;o &eacute; compat&iacute;vel com Lua 5.0 e foi codificada por Tom&aacute;s Guisasola, Eduardo Quint&atilde;o, Thiago Ponte, Fabio Mascarenhas, Danilo Tuler, 
-com inestim&aacute;veis contribui&ccedil;&otilde;es de Michael Roth, Tiago Dionizio e Leonardo Godinho.
+A implementação das versões 2.0 e 2.1 é compatível com Lua 5.0 e foi codificada
+por Tomás Guisasola, Eduardo Quintão, Thiago Ponte, Fabio Mascarenhas, Danilo Tuler,
+com inestimáveis contribuições de Michael Broughton, Pedro Maia, Klaus Ripke, Michael Roth, Tiago Dionizio e Leonardo Godinho.
 </p>
 
 <h4>LuaSQL 1.0</h4>
 <p>
-LuaSQL foi projetado por Pedro Miller Rabinovitch e Roberto
-Ierusalimschy.
-A primeira implementa&ccedil;&atilde;o era compat&iacute;vel com Lua 4.0a.
-Muitas modifica&ccedil;&otilde;es foram feitas, mas n&atilde;o distribu&iacute;das, por Diego Nehab (ODBC),
-Carlos Cassino, Tom&aacute;s Guisasola and Eduardo Quint&atilde;o (PostgreSQL).
+LuaSQL foi projetado por Pedro Miller Rabinovitch e Roberto Ierusalimschy.
+A primeira implementação era compatível com Lua 4.0a.
+Muitas modificações foram feitas, mas não distribuídas, por Diego Nehab (ODBC),
+Carlos Cassino, Tomás Guisasola and Eduardo Quintão (PostgreSQL).
 </p>
 <p>
-O desenvolvimento de LuaSQL foi patrocinado pela 
-<a href="http://www.fabricadigital.com.br">F&aacute;brica Digital</a>, FINEP e CNPq.
+O desenvolvimento da LuaSQL foi patrocinado pela
+<a href="http://www.fabricadigital.com.br">Fábrica Digital</a>, FINEP e CNPq.
 </p>
 
 <h2><a name="contact"></a>Contato</h2>
 
 <p>
-Para mais informa&ccedil;&otilde;es, entre em
+Para mais informações, entre em
 <a href="mailto:info-NO-SPAM-THANKS@keplerproject.org">contato</a> conosco.
-Coment&aacute;rios s&atilde;o muito bem-vindos!
+Comentários são muito bem-vindos!
 </p>
 
 <p>
-A <a href="https://groups.google.com/forum/#!forum/kepler-project">lista de discuss&atilde;o</a>
-do projeto Kepler &eacute; outra forma de entrar em contato com desenvolvedores
-e usu&aacute;rios da plataforma Kepler.
+A <a href="https://groups.google.com/forum/#!forum/kepler-project">lista de discussão</a>
+do projeto Kepler é outra forma de entrar em contato com desenvolvedores
+e usuários da plataforma Kepler.
 </p>
 
 </div> <!-- id="content" -->
diff -pruN 2.6.0-3/doc/br/license.html 2.7.0-1/doc/br/license.html
--- 2.6.0-3/doc/br/license.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/br/license.html	2025-04-23 23:51:04.000000000 +0000
@@ -52,8 +52,8 @@
 		<li><a href="history.html">Hist&oacute;rico</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Projeto</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><strong>Licen&ccedil;a</strong></li>
@@ -87,7 +87,7 @@ somewhere in your product or its documen
 The implementation is not derived from licensed software.</p>
 
 <hr/>
-<p>Copyright &copy; 2003-2006 The Kepler Project.</p>
+<p>Copyright &copy; 2003-2025 The Kepler Project.</p>
 
 <p>Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -114,7 +114,6 @@ THE SOFTWARE.</p>
 <div id="about">
 <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
 <p><small>
-$Id: license.html,v 1.6 2008/06/11 00:26:13 jasonsantos Exp $
 </small></p>
 </div> <!-- id="about" -->
 
diff -pruN 2.6.0-3/doc/br/manual.html 2.7.0-1/doc/br/manual.html
--- 2.6.0-3/doc/br/manual.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/br/manual.html	2025-04-23 23:51:04.000000000 +0000
@@ -52,8 +52,8 @@
 		<li><a href="history.html">Hist&oacute;rico</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Projeto</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">Licen&ccedil;a</a></li>
@@ -85,16 +85,16 @@ A conex&atilde;o pode executar comandos
 um arquivo fonte e um arquivo cabe&ccedil;alho comuns a todos os drivers
 (<code>luasql.h</code> e <code>luasql.c</code>) &ndash; e um arquivo fonte para cada driver.
 Cada driver deve ser compilado juntamente com o arquivo <code>luasql.c</code>
-para gerar uma biblioteca. Essa biblioteca pode ser linkada &agrave; aplica&ccedil;&atilde;o  
+para gerar uma biblioteca. Essa biblioteca pode ser linkada &agrave; aplica&ccedil;&atilde;o
 ou carregada dinamicamente. A fun&ccedil;&atilde;o de inicializa&ccedil;&atilde;o &eacute;
-<code>luaopen_luasql<em>nomedriver</em></code> e &eacute; compat&iacute;vel com o formato 
+<code>luaopen_luasql<em>nomedriver</em></code> e &eacute; compat&iacute;vel com o formato
 <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require"><code>open-library</code></a> de Lua.</p>
 
 <h2><a name="installation"></a>Instala&ccedil;&atilde;o</h2>
 
-<p>Todos os drivers LuaSQL seguem a 
+<p>Todos os drivers LuaSQL seguem a
 <a href="http://www.keplerproject.org/compat">proposta de pacotes</a>
-para Lua 5.1. Logo, esse pacote deve ser "instalado". Consulte a se&ccedil;&atilde;o de 
+para Lua 5.1. Logo, esse pacote deve ser "instalado". Consulte a se&ccedil;&atilde;o de
 <a href="http://www.keplerproject.org/compat/manual.html#configuration">
 configura&ccedil;&atilde;o do Compat-5.1</a> para saber como instalar os pacotes bin&aacute;rios
 da maneira correta.
@@ -188,12 +188,11 @@ env = luasql.jdbc ("com.mysql.jdbc.Drive
     <dt><a name="env_close"></a><strong><code>env:close()</code></strong></dt>
     <dd>Fecha o ambiente <code>env</code>. S&oacute; &eacute; bem sucedido se todas as suas
         conex&otilde;es j&aacute; tiverem sido fechadas anteriormente.<br/>
-        Retorna: <code>true</code>, em caso de sucesso; <code>false</code>, quando o ambiente
-        j&aacute; estiver fechado.
+        Retorna: <code>true</code> em caso de sucesso e em caso de falha retorna <code>false</code> com uma <code>mensagem de string</code> indicando o motivo da falha.
     </dd>
 
     <dt><a name="env_connect"></a><strong><code>env:connect(sourcename[,username[,password]])</code></strong></dt>
-    <dd>Conecta &agrave; fonte de dados especificada em <code>sourcename</code> usando 
+    <dd>Conecta &agrave; fonte de dados especificada em <code>sourcename</code> usando
         <code>username</code> e <code>password</code> se eles s&atilde;o fornecidos.<br/>
         O <code>sourcename</code> pode variar de acordo com cada driver.
         Alguns usam simplesmente o nome do banco de dados, como PostgreSQL, MySQL e SQLite;
@@ -210,7 +209,7 @@ env = luasql.jdbc ("com.mysql.jdbc.Drive
 
 <h2><a name="connection_object"></a>Conex&atilde;o</h2>
 
-<p>Uma conex&atilde;o cont&eacute;m atributos e par&acirc;metros espec&iacute;ficos de uma 
+<p>Uma conex&atilde;o cont&eacute;m atributos e par&acirc;metros espec&iacute;ficos de uma
 &uacute;nica conex&atilde;o de base de dados. Uma conex&atilde;o &eacute; criada chamando
 o m&eacute;todo <code><a href="#env_connect">environment:connect</a></code>.</p>
 
@@ -220,7 +219,7 @@ o m&eacute;todo <code><a href="#env_conn
     <dt><a name="conn_close"></a><strong><code>conn:close()</code></strong></dt>
     <dd>Fecha a conex&atilde;o <code>conn</code>. S&oacute; &eacute; bem sucedido se todos
         os seus cursores tiverem sido fechados anteriormente e se a conex&atilde;o ainda estiver aberta.<br/>
-        Retorna: <code>true</code>, em caso de sucesso; <code>false</code> em caso de fracasso.
+        Retorna: <code>true</code> em caso de sucesso e em caso de falha retorna <code>false</code> com uma <code>mensagem de string</code> indicando o motivo da falha.
     </dd>
 
     <dt><a name="conn_commit"></a><strong><code>conn:commit()</code></strong></dt>
@@ -267,8 +266,7 @@ e <a href="#oracle_extensions">Oracle</a
 <dl class="reference">
     <dt><a name="cur_close"></a><strong><code>cur:close()</code></strong></dt>
     <dd>Fecha esse cursor.<br/>
-        Retorna: <code>true</code>, em caso de sucesso; <code>false</code>, quando o cursor
-        j&aacute; est&aacute; fechado.
+        Retorna: <code>true</code> em caso de sucesso e em caso de falha retorna <code>false</code> com uma <code>mensagem de string</code> indicando o motivo da falha.
     </dd>
 
     <dt><a name="cur_fetch"></a><strong><code>cur:fetch([table[,modestring]])</code></strong></dt>
@@ -278,7 +276,7 @@ e <a href="#oracle_extensions">Oracle</a
         chamado com uma tabela, os resultados s&atilde;o copiados para a tabela e a tabela
         &eacute; retornada. Neste caso, pode ser usado um
         par&acirc;metro opcional de modo (<code>modestring</code>): uma seq&uuml;&ecirc;ncia
-        de caracteres indicando como deve ser constru&iacute;da a tabela de resultados. 
+        de caracteres indicando como deve ser constru&iacute;da a tabela de resultados.
         A seq&uuml;&ecirc;ncia de caracteres do modo pode conter:
         <dl>
             <dt><strong>"n"</strong></dt><dd>a tabela resultante ter&aacute; &iacute;ndices num&eacute;ricos (padr&atilde;o)</dd>
@@ -320,7 +318,7 @@ o driver Postgres oferece as seguintes f
     <dd>No driver PostgreSQL este m&eacute;todo tem mais dois par&acirc;metros opcionais que indicam
         o <code>hostname</code> e a <code>port</code> a serem utilizados na conex&atilde;o.
         Al&eacute;m disso, o primeiro par&acirc;metro tamb&eacute;m pode conter todas as informa&ccedil;&otilde;es
-        de conex&atilde;o, como &eacute; dito na documenta&ccedil;&atilde;o 
+        de conex&atilde;o, como &eacute; dito na documenta&ccedil;&atilde;o
         para a fun&ccedil;&atilde;o <code>PQconnectdb</code> no manual do PostgreSQL
         (ex. <small><code>environment:connect("dbname=&lt;<em>name</em>&gt; user=&lt;<em>username</em>&gt;")</code></small>)<br/>
         Veja tamb&eacute;m: <a href="#environment_object">ambiente</a><br/>
@@ -404,4 +402,4 @@ o driver para SQLite3 ainda oferece uma
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/fr/doc.css 2.7.0-1/doc/fr/doc.css
--- 2.6.0-3/doc/fr/doc.css	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/doc.css	2025-04-23 23:51:04.000000000 +0000
@@ -1,16 +1,16 @@
-body { 
-    margin-left: 1em; 
-    margin-right: 1em; 
+body {
+    margin-left: 1em;
+    margin-right: 1em;
     font-family: arial, helvetica, geneva, sans-serif;
     background-color:#ffffff; margin:0px;
 }
 
 code {
-    font-family: "Andale Mono", monospace; 
+    font-family: "Andale Mono", monospace;
 }
 
 tt {
-    font-family: "Andale Mono", monospace; 
+    font-family: "Andale Mono", monospace;
 }
 
 body, td, th { font-size: 11pt; }
@@ -35,10 +35,10 @@ h3 { padding-top: 1em; }
 
 p { margin-left: 1em; }
 
-p.name { 
-    font-family: "Andale Mono", monospace; 
+p.name {
+    font-family: "Andale Mono", monospace;
     padding-top: 1em;
-    margin-left: 0em; 
+    margin-left: 0em;
 }
 
 blockquote { margin-left: 3em; }
@@ -60,13 +60,13 @@ blockquote { margin-left: 3em; }
     padding: 1em;
     margin-left: 1em;
     margin-right: 1em;
-    font-family: "Andale Mono", monospace; 
+    font-family: "Andale Mono", monospace;
     font-size: smaller;
 }
 
-hr { 
+hr {
     margin-left: 0em;
-    background: #00007f; 
+    background: #00007f;
     border: 0px;
     height: 1px;
 }
@@ -205,7 +205,7 @@ div.header, div.footer { margin-left: 0e
         display: none;
     }
     .example {
-        font-family: "Andale Mono", monospace; 
+        font-family: "Andale Mono", monospace;
         font-size: 8pt;
         page-break-inside: avoid;
     }
diff -pruN 2.6.0-3/doc/fr/examples.html 2.7.0-1/doc/fr/examples.html
--- 2.6.0-3/doc/fr/examples.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/examples.html	2025-04-23 23:51:04.000000000 +0000
@@ -52,8 +52,8 @@
 		<li><a href="history.html">History</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -135,7 +135,7 @@ end
 </pre>
 
 <p>Here is how the iterator is used:</p>
- 
+
 <pre class="example">
 env = assert (require"luasql.mysql".mysql())
 con = assert (env:connect"my_db")
@@ -146,6 +146,21 @@ end
 
 <p>Obviously, the code above only works if there is a table called contacts with the columns id, name and address in this order. At the end of the loop the cursor will be automatically closed by the driver.</p>
 
+<h3><a name="To_be_closed"></a>To-be-closed Objects</h3>
+
+<p>
+	<strong style="color: red;">Compatibility Note:</strong>
+	To-be-closed variables is a feature introduced in Lua 5.4. Therefore, this functionality can only be used if LuaSQL (version > 2.6) is compiled against Lua version 5.4 or higher.
+</p>
+
+<pre class="example">
+function getName(db, id)
+  -- This code requires Lua 5.4 or higher due to the use of to-be-closed variables.
+  local cur &lt;close&gt; = db:execute("SELECT name FROM contacts WHERE id = " .. id)
+  return cur:fetch()
+end
+</pre>
+
 </div> <!-- id="content" -->
 
 </div> <!-- id="main" -->
diff -pruN 2.6.0-3/doc/fr/history.html 2.7.0-1/doc/fr/history.html
--- 2.6.0-3/doc/fr/history.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/history.html	2025-04-23 23:51:04.000000000 +0000
@@ -52,8 +52,8 @@
 		<li><strong>History</strong></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -120,7 +120,7 @@
         <li>Corrected bug avoiding duplicate access to stack</li>
     </ul>
     </dd>
-    
+
     <dt><strong><a href="http://www.keplerproject.org/luasql/2.0/">LuaSQL 2.0.2</a></strong> [26/Jun/2006]</dt>
     <dd>
     <ul>
@@ -196,4 +196,4 @@
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/fr/index.html 2.7.0-1/doc/fr/index.html
--- 2.6.0-3/doc/fr/index.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/index.html	2025-04-23 23:51:04.000000000 +0000
@@ -41,7 +41,7 @@
 				<li><a href="manual.html#drivers">Drivers</a></li>
 				<li><a href="manual.html#environment_object">Environment</a></li>
 				<li><a href="manual.html#connection_object">Connection</a></li>
-				<li><a href="manual.html#cursor_object">Curseurr</a></li>
+				<li><a href="manual.html#cursor_object">Curseur</a></li>
 				<li><a href="manual.html#postgres_extensions">PostgreSQL</a></li>
 				<li><a href="manual.html#mysql_extensions">MySQL</a></li>
 				<li><a href="manual.html#oracle_extensions">Oracle</a></li>
@@ -50,9 +50,9 @@
 		</li>
 		<li><a href="examples.html">Exemples</a></li>
 		<li><a href="history.html">History?historique?</a></li>
-        <li><a href="http://github.com/keplerproject/luasql/">Projet</a>
+        <li><a href="https://github.com/lunarmodules/luasql">Projet</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/">Bug tracker</a></li>
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug tracker</a></li>
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -89,7 +89,7 @@ For more details on the features list pl
 
 <h2><a name="download"></a>Download</h2>
 <p>
-LuaSQL peut être installé via <a href="http://luarocks.org">LuaRocks</a>.
+LuaSQL peut être installé via <a href="https://luarocks.org">LuaRocks</a>.
 Choissisez le moteur pour votre base de données:
 
 <pre>
@@ -100,7 +100,7 @@ luarocks install luasql-sqlite
 luarocks install luasql-odbc
 </pre>
 Le code source pour LuaSQL peut être téléchargé de son dépôt à <a href=
-"http://github.com/keplerproject/luasql">GitHub</a>.
+"https://github.com/lunarmodules/luasql">GitHub</a>.
 </p>
 
 <h2><a name="credits"></a>Credits</h2>
@@ -127,7 +127,7 @@ The first implementation was compatible
 Many modifications were made but not distributed by Diego Nehab (ODBC),
 Carlos Cassino, Tom&aacute;s Guisasola and Eduardo Quint&atilde;o (PostgreSQL).</p>
 
-<p>LuaSQL development was sponsored by 
+<p>LuaSQL development was sponsored by
 <a href="http://www.fabricadigital.com.br">F&aacute;brica Digital</a>, FINEP and CNPq.</p>
 
 <h2><a name="contact"></a>Contact us</h2>
@@ -150,4 +150,4 @@ Comments are welcome!</p>
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/fr/license.html 2.7.0-1/doc/fr/license.html
--- 2.6.0-3/doc/fr/license.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/license.html	2025-04-23 23:51:04.000000000 +0000
@@ -51,8 +51,8 @@
 		<li><a href="history.html">History</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><strong>License</strong></li>
diff -pruN 2.6.0-3/doc/fr/manual.html 2.7.0-1/doc/fr/manual.html
--- 2.6.0-3/doc/fr/manual.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/fr/manual.html	2025-04-23 23:51:04.000000000 +0000
@@ -52,8 +52,8 @@
 		<li><a href="history.html">History</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -97,7 +97,7 @@ as Lua 5.1.
 a pair of common source and header files (<code>luasql.h</code> and <code>luasql.c</code>);
 and one source file for each driver.
 Each driver should be compiled with the luasql.c file to generate a library.
-This library can be linked to the application or dynamically loaded. 
+This library can be linked to the application or dynamically loaded.
 The initialization function is <code>luaopen_luasql<em>drivername</em></code> and it is a Lua
 <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require"><code>open-library</code></a> compatible function.
 </p>
@@ -183,11 +183,10 @@ local env = driver.odbc()
 	<dt><a name="env_close"></a><strong><code>env:close()</code></strong></dt>
 	<dd>Closes the environment <code>env</code>.
 	Only successful if all connections pertaining to it were closed first.<br/>
-	Returns: <code>true</code> in case of success; <code>false</code> when
-	the object is already closed.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	<dt><a name="env_connect"></a><strong><code>env:connect(sourcename[,username[,password]])</code></strong></dt>
-	<dd>Connects to a data source specified in <code>sourcename</code> using 
+	<dd>Connects to a data source specified in <code>sourcename</code> using
 	<code>username</code> and <code>password</code> if they are supplied.<br/>
 	The <code>sourcename</code> may vary according to each driver.
 	Some use a simple database name, like PostgreSQL, MySQL and SQLite;
@@ -215,7 +214,7 @@ method.</p>
 	<dt><a name="conn_close"></a><strong><code>conn:close()</code></strong></dt>
 	<dd>Closes the connection <code>conn</code>.
 	Only successful if all cursors pertaining to it have been closed and the connection is still open.<br/>
-	Returns: <code>true</code> in case of success and <code>false</code> in case of failure.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	
 	<dt><a name="conn_commit"></a><strong><code>conn:commit()</code></strong></dt>
@@ -268,8 +267,7 @@ and <a href="#oracle_extensions">Oracle<
 
 	<dt><a name="cur_close"></a><strong><code>cur:close()</code></strong></dt>
 	<dd>Closes this cursor.<br/>
-	Returns: <code>true</code> in case of success and <code>false</code> when
-	the object is already closed.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	
 	<dt><a name="cur_fetch"></a><strong><code>cur:fetch([table[,modestring]])</code></strong></dt>
@@ -430,4 +428,4 @@ the SQLite3 driver also offers this extr
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/us/doc.css 2.7.0-1/doc/us/doc.css
--- 2.6.0-3/doc/us/doc.css	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/doc.css	2025-04-23 23:51:04.000000000 +0000
@@ -1,4 +1,4 @@
-body { 
+body {
     color: #47555c;
     font-size: 16px;
     font-family: "Open Sans", sans-serif;
@@ -24,18 +24,18 @@ hr {
 }
 
 code {
-    font-family: "Open Sans Mono", "Andale Mono", monospace; 
+    font-family: "Open Sans Mono", "Andale Mono", monospace;
 }
 
 tt {
-    font-family: "Open Sans Mono", "Andale Mono", monospace; 
+    font-family: "Open Sans Mono", "Andale Mono", monospace;
 }
 
 body, td, th {
 }
 
 textarea, pre, tt {
-    font-family: "Open Sans Mono", "Andale Mono", monospace; 
+    font-family: "Open Sans Mono", "Andale Mono", monospace;
 }
 
 img {
@@ -205,7 +205,7 @@ dl.reference dd {
         display: none;
     }
     .example {
-        font-family: "Andale Mono", monospace; 
+        font-family: "Andale Mono", monospace;
         font-size: 8pt;
         page-break-inside: avoid;
     }
diff -pruN 2.6.0-3/doc/us/examples.html 2.7.0-1/doc/us/examples.html
--- 2.6.0-3/doc/us/examples.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/examples.html	2025-04-23 23:51:04.000000000 +0000
@@ -11,9 +11,9 @@
 <div id="container">
 	
 <div id="product">
-	<div id="product_logo">
+	<div id="product_logo"><a href="http://www.keplerproject.org">
 		<img alt="LuaSQL logo" src="luasql.png"/>
-	</div>
+	</a></div>
 	<div id="product_name"><big><b>LuaSQL</b></big></div>
 	<div id="product_description">Database connectivity for the Lua programming language</div>
 </div> <!-- id="product" -->
@@ -29,10 +29,10 @@
 		</li>
 		<li><strong>Examples</strong></li>
 		<li><a href="history.html">History</a></li>
-        <li><a href="http://github.com/keplerproject/luasql">Project</a>
+        <li><a href="https://github.com/lunarmodules/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -114,7 +114,7 @@ end
 </pre>
 
 <p>Here is how the iterator is used:</p>
- 
+
 <pre class="example">
 env = assert (require"luasql.mysql".mysql())
 con = assert (env:connect"my_db")
@@ -125,6 +125,21 @@ end
 
 <p>Obviously, the code above only works if there is a table called contacts with the columns id, name and address in this order. At the end of the loop the cursor will be automatically closed by the driver.</p>
 
+<h3><a name="To_be_closed"></a>To-be-closed Objects</h3>
+
+<p>
+	<strong style="color: red;">Compatibility Note:</strong>
+	To-be-closed variables is a feature introduced in Lua 5.4. Therefore, this functionality can only be used if LuaSQL (version &gt; 2.6) is compiled against Lua version 5.4 or higher.
+</p>
+
+<pre class="example">
+function getName(db, id)
+  -- This code requires Lua 5.4 or higher due to the use of to-be-closed variables.
+  local cur &lt;close&gt; = db:execute("SELECT name FROM contacts WHERE id = " .. id)
+  return cur:fetch()
+end
+</pre>
+
 </div> <!-- id="content" -->
 
 </div> <!-- id="main" -->
diff -pruN 2.6.0-3/doc/us/history.html 2.7.0-1/doc/us/history.html
--- 2.6.0-3/doc/us/history.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/history.html	2025-04-23 23:51:04.000000000 +0000
@@ -31,8 +31,8 @@
 		<li><strong>History</strong></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -44,6 +44,29 @@
 <h2><a name="history"></a>History</h2>
 
 <dl class="history">
+    <dt><strong>LuaSQL 2.7.0</strong> [23/Apr/2025]</dt>
+    <dd>
+      <ul>
+        <li>LuaSQL is adapted to Lua version 5.4 and all the drivers are compatible with To-be-closed variables.</li>
+        <li>The <code>:close()</code> method now returns false and a string with appropriate message instead of raising an error when there are related open objects.</li>
+      </ul>
+    </dd>
+
+    <dt><strong>LuaSQL 2.6.1</strong> [07/Feb/2024]</dt>
+    <dd>
+      <ul>
+        <li>Corrected compatibility to Lua versions below 5.3 to SQLite3 (thanks to Daniel McCarney)</li>
+      </ul>
+    </dd>
+
+    <dt><strong>LuaSQL 2.6.0</strong> [09/Sep/2020]</dt>
+    <dd>
+      <ul>
+        <li>Added read-only mode to SQLite3 and two new methods to MySQL fetch</li>
+        <li>Added library opening functions to ease the initialization process in C applications</li>
+      </ul>
+    </dd>
+
     <dt><strong>LuaSQL 2.5.0</strong> [14/Jun/2019]</dt>
     <dd>
       <ul>
@@ -152,7 +175,7 @@
         <li>Corrected bug avoiding duplicate access to stack</li>
     </ul>
     </dd>
-    
+
     <dt><strong><a href="http://www.keplerproject.org/luasql/2.0/">LuaSQL 2.0.2</a></strong> [26/Jun/2006]</dt>
     <dd>
     <ul>
@@ -227,4 +250,4 @@
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/us/index.html 2.7.0-1/doc/us/index.html
--- 2.6.0-3/doc/us/index.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/index.html	2025-04-23 23:51:04.000000000 +0000
@@ -11,9 +11,9 @@
 <div id="container">
 	
 <div id="product">
-	<div id="product_logo">
+	<div id="product_logo"><a href="https://github.com/lunarmodules/luasql">
 		<img alt="LuaSQL logo" src="luasql.png"/>
-	</div>
+	</a></div>
 	<div id="product_name"><big><strong>LuaSQL</strong></big></div>
 	<div id="product_description">Database connectivity for the Lua programming language</div>
 </div> <!-- id="product" -->
@@ -36,9 +36,9 @@
 		</li>
 		<li><a href="examples.html">Examples</a></li>
 		<li><a href="history.html">History</a></li>
-        <li><a href="http://github.com/keplerproject/luasql/">Project</a>
+        <li><a href="https://github.com/lunarmodules/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Issues</a></li>
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Issues</a></li>
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -67,32 +67,37 @@ as Lua 5.1.
 <h2><a name="status"></a>Status</h2>
 
 <p>
-LuaSQL version 2.5.0 (for Lua 5.X) is now available for <a href="#download">download</a>.
+LuaSQL version 2.7.0 (for Lua 5.X) is now available for <a href="#download">download</a>.
 For more details on the features list please check the product
 <a href="history.html">history</a>.
 </p>
 
 <h2><a name="download"></a>Download</h2>
 <p>
-LuaSQL can be installed via <a href="http://luarocks.org">LuaRocks</a>, using the 
+LuaSQL can be installed via <a href="https://luarocks.org">LuaRocks</a>, using the
 driver for your database of choice:
 
 <pre class="example">
-luarocks install luasql-sqlite3
-luarocks install luasql-postgres
+luarocks install luasql-firebird
 luarocks install luasql-mysql
-luarocks install luasql-sqlite
+luarocks install luasql-oci8
 luarocks install luasql-odbc
-luarocks install luasql-firebird
+luarocks install luasql-postgres
+luarocks install luasql-sqlite
+luarocks install luasql-sqlite3
 </pre>
 
-Source code for LuaSQL can be downloaded from its <a href=
-"http://github.com/keplerproject/luasql">GitHub</a> repository.
+Source code for LuaSQL can be downloaded from its <a href="https://github.com/lunarmodules/luasql">GitHub</a> repository.
 </p>
 
 <h2><a name="credits"></a>Credits</h2>
 
 <h4>LuaSQL 2.x</h4>
+
+<p>
+Version 2.7 introduces support for To-be-closed variables and all the Drivers are adapted to Lua version 5.4. <br>This was developed by Chaitanya Deshmukh (GSoC 2024) under the mentorship of Tomás Guisasola.
+</p>
+
 <p>
 Version 2.5 incorporates support in MySQL driver for seeking in the result set.
 </p>
@@ -104,14 +109,14 @@ This version works with Lua versions 5.1
 Version 2.3 is just an adaptation of the code to work with Lua 5.0, 5.1 and 5.2.
 </p>
 <p>
-Version 2.2 started a distributed development, with all project discussions happenign through the <a href="https://groups.google.com/forum/#!forum/kepler-project">Kepler's mailing list</a>.
-New developers: Hisham Muhammad, Ignacio Burgue&ntilde;o, Luis Eduardo Jason Santos, Marc Nijdam, Mauricio Bomfim and Scott Morgan.
+Version 2.2 started a distributed development, with all project discussions happening through the <a href="https://groups.google.com/forum/#!forum/kepler-project">Kepler's mailing list</a>.
+New developers: Hisham Muhammad, Ignacio Burgueño, Luis Eduardo Jason Santos, Marc Nijdam, Mauricio Bomfim and Scott Morgan.
 <p>
-Version 2.1 and 2.0 were redesigned by Roberto Ierusalimschy, Andr&eacute; Carregal
-and Tom&aacute;s Guisasola as part of the
+Version 2.1 and 2.0 were redesigned by Roberto Ierusalimschy, André Carregal
+and Tomás Guisasola as part of the
 <a href="http://www.keplerproject.org">Kepler Project</a>.
 The implementation was coded by
-Tom&aacute;s Guisasola, Eduardo Quint&atilde;o, Thiago Ponte, Fabio Mascarenhas and
+Tomás Guisasola, Eduardo Quintão, Thiago Ponte, Fabio Mascarenhas and
 Danilo Tuler, with many contributions from Michael Broughton, Tiago Dionizio, Leonardo Godinho, Pedro Maia, Klaus Ripke, Michael Roth and others.</p>
 
 <h4>LuaSQL 1.0</h4>
@@ -119,10 +124,10 @@ Danilo Tuler, with many contributions fr
 <p>LuaSQL was originally designed by Pedro Miller Rabinovitch and Roberto Ierusalimschy.
 The first implementation was compatible with Lua 4.0a.
 Many modifications were made but not distributed by Diego Nehab (ODBC),
-Carlos Cassino, Tom&aacute;s Guisasola and Eduardo Quint&atilde;o (PostgreSQL).</p>
+Carlos Cassino, Tomás Guisasola and Eduardo Quintão (PostgreSQL).</p>
 
-<p>LuaSQL development was sponsored by 
-<a href="http://www.fabricadigital.com.br">F&aacute;brica Digital</a>, FINEP and CNPq.</p>
+<p>LuaSQL development was sponsored by
+<a href="http://www.fabricadigital.com.br">Fábrica Digital</a>, FINEP and CNPq.</p>
 
 <h2><a name="contact"></a>Contact us</h2>
 
@@ -143,4 +148,4 @@ Comments are welcome!</p>
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/doc/us/license.html 2.7.0-1/doc/us/license.html
--- 2.6.0-3/doc/us/license.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/license.html	2025-04-23 23:51:04.000000000 +0000
@@ -30,8 +30,8 @@
 		<li><a href="history.html">History</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><strong>License</strong></li>
@@ -65,7 +65,7 @@ somewhere in your product or its documen
 The implementation is not derived from licensed software.</p>
 
 <hr/>
-<p>Copyright &copy; 2003-2019 The Kepler Project.</p>
+<p>Copyright &copy; 2003-2025 The Kepler Project.</p>
 
 <p>Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff -pruN 2.6.0-3/doc/us/manual.html 2.7.0-1/doc/us/manual.html
--- 2.6.0-3/doc/us/manual.html	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/doc/us/manual.html	2025-04-23 23:51:04.000000000 +0000
@@ -45,8 +45,8 @@
 		<li><a href="history.html">History</a></li>
         <li><a href="http://github.com/keplerproject/luasql">Project</a>
             <ul>
-                <li><a href="http://github.com/keplerproject/luasql/issues">Bug Tracker</a></li>
-                
+                <li><a href="https://github.com/lunarmodules/luasql/issues">Bug Tracker</a></li>
+
             </ul>
         </li>
 		<li><a href="license.html">License</a></li>
@@ -90,7 +90,7 @@ as Lua 5.1.
 a pair of common source and header files (<code>luasql.h</code> and <code>luasql.c</code>);
 and one source file for each driver.
 Each driver should be compiled with the luasql.c file to generate a library.
-This library can be linked to the application or dynamically loaded. 
+This library can be linked to the application or dynamically loaded.
 The initialization function is <code>luaopen_luasql<em>drivername</em></code> and it is a Lua
 <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require"><code>open-library</code></a> compatible function.
 </p>
@@ -176,11 +176,10 @@ local env = driver.odbc()
 	<dt><a name="env_close"></a><strong><code>env:close()</code></strong></dt>
 	<dd>Closes the environment <code>env</code>.
 	Only successful if all connections pertaining to it were closed first.<br/>
-	Returns: <code>true</code> in case of success; <code>false</code> when
-	the object is already closed.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	<dt><a name="env_connect"></a><strong><code>env:connect(sourcename[,username[,password]])</code></strong></dt>
-	<dd>Connects to a data source specified in <code>sourcename</code> using 
+	<dd>Connects to a data source specified in <code>sourcename</code> using
 	<code>username</code> and <code>password</code> if they are supplied.<br/>
 	The <code>sourcename</code> may vary according to each driver.
 	Some use a simple database name, like PostgreSQL, MySQL and SQLite;
@@ -208,7 +207,7 @@ method.</p>
 	<dt><a name="conn_close"></a><strong><code>conn:close()</code></strong></dt>
 	<dd>Closes the connection <code>conn</code>.
 	Only successful if all cursors pertaining to it have been closed and the connection is still open.<br/>
-	Returns: <code>true</code> in case of success and <code>false</code> in case of failure.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	
 	<dt><a name="conn_commit"></a><strong><code>conn:commit()</code></strong></dt>
@@ -261,8 +260,7 @@ and <a href="#oracle_extensions">Oracle<
 
 	<dt><a name="cur_close"></a><strong><code>cur:close()</code></strong></dt>
 	<dd>Closes this cursor.<br/>
-	Returns: <code>true</code> in case of success and <code>false</code> when
-	the object is already closed.</dd>
+	Returns: <code>true</code> in case of success and in case of failure it returns <code>false</code> with a <code>string message</code> stating the failure reason.</dd>
 	
 	
 	<dt><a name="cur_fetch"></a><strong><code>cur:fetch([table[,modestring]])</code></strong></dt>
@@ -388,7 +386,7 @@ the MySQL driver also offers these extra
   <dd>Retrieves the next result set, if another result is available (e.g. multiple statements)<br/>
     See also: <a href="#cursor_object">cursor objects</a><br/>
 	Returns: true, if next result was selected. false and -1 if no other result is available. false, errno and error message, if an error occured.<br/>
-	To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection. 
+	To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection.
 	Be aware that you need to iterate over all results otherwise you will receive an "out of sync" error.
   </dd>
 
@@ -397,15 +395,13 @@ the MySQL driver also offers these extra
   <dd>Checks if next result is available<br/>
     See also: <a href="#cursor_object">cursor objects</a><br/>
     Returns: true or false<br/>
-	To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection. 
+	To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection.
 	Be aware that you need to iterate over all results otherwise you will receive an "out of sync" error.
   </dd>
 </dl>
 
 <p>Notes:</p>
 
-<p>I </p>
-
 <p>This driver is compatible with versions 4.0, 4.1 and 5.0 of the
 MySQL API. Only from version 4.1 MySQL provides support for transactions by using
 BDB or INNODB tables.
@@ -433,7 +429,8 @@ the Oracle driver also offers this extra
 <p>Besides the basic functionality provided by all drivers,
 the SQLite3 driver also offers this extra feature:</p>
 
-<dt><strong><code>env:connect(sourcename[,locktimeout,readOnlyMode])</code></strong></dt>
+<dl class="reference">
+  <dt><strong><code>env:connect(sourcename[,locktimeout,readOnlyMode])</code></strong></dt>
   <dd>In the SQLite3 driver, this method adds an optional parameter
     that indicate the amount of milliseconds to wait for a write lock if one cannot be obtained immediately.
 	  To connect in readOnlyMode, set readOnlyMode to true.<br/>
@@ -446,7 +443,7 @@ the SQLite3 driver also offers this extr
     See also: Official documentation of function <a href="http://www.sqlite.org/c3ref/mprintf.html">sqlite3_mprintf</a><br/>
     Returns: the escaped string.
   </dd>
-
+</dl>
 </div> <!-- id="content" -->
 
 </div> <!-- id="main" -->
@@ -458,4 +455,4 @@ the SQLite3 driver also offers this extr
 </div> <!-- id="container" -->
 
 </body>
-</html> 
+</html>
diff -pruN 2.6.0-3/rockspec/luasql-firebird-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-firebird-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-firebird-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-firebird-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-Firebird"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Firebird driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://keplerproject.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   FB = {
+      header = "ibase.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.firebird"] = {
+       sources = { "src/luasql.c", "src/ls_firebird.c" },
+       libraries = { "fbclient" },
+       incdirs = { "$(FB_INCDIR)" },
+       libdirs = { "$(FB_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-firebird-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-firebird-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-firebird-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-firebird-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-Firebird"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Firebird driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   FB = {
+      header = "ibase.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.firebird"] = {
+       sources = { "src/luasql.c", "src/ls_firebird.c" },
+       libraries = { "fbclient" },
+       incdirs = { "$(FB_INCDIR)" },
+       libdirs = { "$(FB_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-mysql-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-mysql-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-mysql-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-mysql-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-MySQL"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (MySQL driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://www.keplerproject.org/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   MYSQL = {
+      header = "mysql.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.mysql"] = {
+       sources = { "src/luasql.c", "src/ls_mysql.c" },
+       libraries = { "mysqlclient" },
+       incdirs = { "$(MYSQL_INCDIR)" },
+       libdirs = { "$(MYSQL_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-mysql-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-mysql-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-mysql-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-mysql-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-MySQL"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (MySQL driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   MYSQL = {
+      header = "mysql.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.mysql"] = {
+       sources = { "src/luasql.c", "src/ls_mysql.c" },
+       libraries = { "mysqlclient" },
+       incdirs = { "$(MYSQL_INCDIR)" },
+       libdirs = { "$(MYSQL_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-oci8-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-oci8-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-oci8-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-oci8-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-OCI8"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Oracle driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://www.keplerproject.org/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   OCI8 = {
+      header = "oci.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.oci8"] = {
+       sources = { "src/luasql.c", "src/ls_oci8.c" },
+       libraries = { "z", "clntsh", },
+       incdirs = { "$(OCI8_INCDIR)" },
+       libdirs = { "$(OCI8_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-oci8-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-oci8-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-oci8-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-oci8-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-OCI8"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Oracle driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   OCI8 = {
+      header = "oci.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.oci8"] = {
+       sources = { "src/luasql.c", "src/ls_oci8.c" },
+       libraries = { "z", "clntsh", },
+       incdirs = { "$(OCI8_INCDIR)" },
+       libdirs = { "$(OCI8_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-odbc-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-odbc-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-odbc-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-odbc-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-ODBC"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (ODBC driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://www.keplerproject.org/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   ODBC = {
+      header = "sql.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.odbc"] = {
+       sources = { "src/luasql.c", "src/ls_odbc.c" },
+       libraries = { "odbc" },
+       incdirs = { "$(ODBC_INCDIR)" },
+       libdirs = { "$(ODBC_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-odbc-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-odbc-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-odbc-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-odbc-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,49 @@
+package = "LuaSQL-ODBC"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (ODBC driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   ODBC = {
+      header = "sql.h"
+   }
+}
+build = {
+   type = "builtin",
+   platforms = {
+     windows = { 
+       modules = {
+         ["luasql.odbc"] = {
+           sources = { "src/luasql.c", "src/ls_odbc.c" },  
+           incdirs = { "$(ODBC_INCDIR)" },
+           libdirs = { "$(ODBC_LIBDIR)" },
+           libraries = { "odbc32" }
+         }
+       }
+     },
+     unix = { 
+       modules = {
+         ["luasql.odbc"] = {
+           sources = { "src/luasql.c", "src/ls_odbc.c" },  
+           incdirs = { "$(ODBC_INCDIR)" },
+           libdirs = { "$(ODBC_LIBDIR)" },
+           libraries = { "odbc" }
+         }
+       }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-postgres-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-postgres-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-postgres-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-postgres-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-Postgres"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Postgres driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://keplerproject.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.0"
+}
+external_dependencies = {
+   PGSQL = {
+      header = "libpq-fe.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.postgres"] = {
+       sources = { "src/luasql.c", "src/ls_postgres.c" },
+       libraries = { "pq" },
+       incdirs = { "$(PGSQL_INCDIR)" },
+       libdirs = { "$(PGSQL_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-postgres-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-postgres-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-postgres-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-postgres-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-Postgres"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (Postgres driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.0"
+}
+external_dependencies = {
+   PGSQL = {
+      header = "libpq-fe.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.postgres"] = {
+       sources = { "src/luasql.c", "src/ls_postgres.c" },
+       libraries = { "pq" },
+       incdirs = { "$(PGSQL_INCDIR)" },
+       libdirs = { "$(PGSQL_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-sqlite-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-sqlite-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-sqlite-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-sqlite-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-SQLite"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (SQLite driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://www.keplerproject.org/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   SQLITE = {
+      header = "sqlite.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.sqlite"] = {
+       sources = { "src/luasql.c", "src/ls_sqlite.c" },
+       libraries = { "sqlite" },
+       incdirs = { "$(SQLITE_INCDIR)" },
+       libdirs = { "$(SQLITE_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-sqlite-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-sqlite-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-sqlite-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-sqlite-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-SQLite"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (SQLite driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   SQLITE = {
+      header = "sqlite.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.sqlite"] = {
+       sources = { "src/luasql.c", "src/ls_sqlite.c" },
+       libraries = { "sqlite" },
+       incdirs = { "$(SQLITE_INCDIR)" },
+       libdirs = { "$(SQLITE_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-sqlite3-2.6.0-2.rockspec 2.7.0-1/rockspec/luasql-sqlite3-2.6.0-2.rockspec
--- 2.6.0-3/rockspec/luasql-sqlite3-2.6.0-2.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-sqlite3-2.6.0-2.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-SQLite3"
+version = "2.6.0-2"
+source = {
+  url = "git+https://github.com/keplerproject/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (SQLite3 driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "http://www.keplerproject.org/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   SQLITE = {
+      header = "sqlite3.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.sqlite3"] = {
+       sources = { "src/luasql.c", "src/ls_sqlite3.c" },
+       libraries = { "sqlite3" },
+       incdirs = { "$(SQLITE_INCDIR)" },
+       libdirs = { "$(SQLITE_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-sqlite3-2.6.0-3.rockspec 2.7.0-1/rockspec/luasql-sqlite3-2.6.0-3.rockspec
--- 2.6.0-3/rockspec/luasql-sqlite3-2.6.0-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-sqlite3-2.6.0-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-SQLite3"
+version = "2.6.0-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (SQLite3 driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   SQLITE = {
+      header = "sqlite3.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.sqlite3"] = {
+       sources = { "src/luasql.c", "src/ls_sqlite3.c" },
+       libraries = { "sqlite3" },
+       incdirs = { "$(SQLITE_INCDIR)" },
+       libdirs = { "$(SQLITE_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/rockspec/luasql-sqlite3-2.6.1-3.rockspec 2.7.0-1/rockspec/luasql-sqlite3-2.6.1-3.rockspec
--- 2.6.0-3/rockspec/luasql-sqlite3-2.6.1-3.rockspec	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/rockspec/luasql-sqlite3-2.6.1-3.rockspec	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,35 @@
+package = "LuaSQL-SQLite3"
+version = "2.6.1-3"
+source = {
+  url = "git+https://github.com/lunarmodules/luasql.git",
+  branch = "2.6.0",
+}
+description = {
+   summary = "Database connectivity for Lua (SQLite3 driver)",
+   detailed = [[
+      LuaSQL is a simple interface from Lua to a DBMS. It enables a
+      Lua program to connect to databases, execute arbitrary SQL statements
+      and retrieve results in a row-by-row cursor fashion.
+   ]],
+   license = "MIT/X11",
+   homepage = "https://lunarmodules.github.io/luasql/"
+}
+dependencies = {
+   "lua >= 5.1"
+}
+external_dependencies = {
+   SQLITE = {
+      header = "sqlite3.h"
+   }
+}
+build = {
+   type = "builtin",
+   modules = {
+     ["luasql.sqlite3"] = {
+       sources = { "src/luasql.c", "src/ls_sqlite3.c" },
+       libraries = { "sqlite3" },
+       incdirs = { "$(SQLITE_INCDIR)" },
+       libdirs = { "$(SQLITE_LIBDIR)" }
+     }
+   }
+}
diff -pruN 2.6.0-3/src/ls_firebird.c 2.7.0-1/src/ls_firebird.c
--- 2.6.0-3/src/ls_firebird.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_firebird.c	2025-04-23 23:51:04.000000000 +0000
@@ -1,1101 +1,1119 @@
-/*
-** LuaSQL, Firebird driver
-** Authors: Scott Morgan
-** ls_firebird.c
-*/
-
-#include <ibase.h>	/* The Firebird API*/
-#include <time.h>	/* For managing time values */
-#include <stdlib.h>
-#include <string.h>
-
-/* Lua API */
-#include <lua.h>
-#include <lauxlib.h>
-
-#include "luasql.h"
-
-#define LUASQL_ENVIRONMENT_FIREBIRD "Firebird environment"
-#define LUASQL_CONNECTION_FIREBIRD "Firebird connection"
-#define LUASQL_CURSOR_FIREBIRD "Firebird cursor"
-
-typedef struct {
-	short closed;
-	ISC_STATUS status_vector[20];	/* for error results */
-	int lock;						/* lock count for open connections */
-} env_data;
-
-typedef struct {
-	short			closed;
-	env_data*		env;			/* the DB enviroment this is in */
-	isc_db_handle	db;				/* the database handle */
-	char			dpb_buffer[256];/* holds the database paramet buffer */
-	short			dpb_length;		/* the used amount of the dpb */
-	isc_tr_handle	transaction;	/* the transaction handle */
-	int				lock;			/* lock count for open cursors */
-	int				autocommit;		/* should each statement be commited */
-} conn_data;
-
-typedef struct {
-	short			closed;
-	env_data*		env;			/* the DB enviroment this is in */
-	conn_data*		conn;			/* the DB connection this cursor is from */
-	isc_stmt_handle stmt;			/* the statement handle */
-	int			stmt_type;			/* the type of the statment */
-	XSQLDA			*out_sqlda;		/* the cursor data array */
-} cur_data;
-
-/* How many fields to pre-alloc to the cursor */
-#define CURSOR_PREALLOC 10
-
-/* Macro to ease code reading */
-#define CHECK_DB_ERROR( X ) ( (X)[0] == 1 && (X)[1] )
-
-/* Use the new interpret API if available */
-#undef FB_INTERPRET
-#if FB_API_VER >= 20
-  #define FB_INTERPRET(BUF, LEN, VECTOR) fb_interpret(BUF, LEN, VECTOR)
-#else
-  #define FB_INTERPRET(BUF, LEN, VECTOR) isc_interpret(BUF, VECTOR)
-#endif
-
-#if LUA_VERSION_NUM>=503
-#define luasql_pushinteger lua_pushinteger
-#else
-#define luasql_pushinteger lua_pushnumber
-#endif
-
-/*
-** Returns a standard database error message
-*/
-static int return_db_error(lua_State *L, const ISC_STATUS *pvector)
-{
-	char errmsg[512];
-
-	lua_pushnil(L);
-	FB_INTERPRET(errmsg, 512, &pvector);
-	lua_pushstring(L, errmsg);
-	while(FB_INTERPRET(errmsg, 512, &pvector)) {
-		lua_pushstring(L, "\n * ");
-		lua_pushstring(L, errmsg);
-		lua_concat(L, 3);
-	}
-
-	return 2;
-}
-
-/*
-** Registers a given C object in the registry to avoid GC
-*/
-static void lua_registerobj(lua_State *L, int index, void *obj)
-{
-	lua_pushvalue(L, index);
-	lua_pushlightuserdata(L, obj);
-	lua_pushvalue(L, -2);
-	lua_settable(L, LUA_REGISTRYINDEX);
-	lua_pop(L, 1);
-}
-
-/*
-** Unregisters a given C object from the registry
-*/
-static void lua_unregisterobj(lua_State *L, void *obj)
-{
-	lua_pushlightuserdata(L, obj);
-	lua_pushnil(L);
-	lua_settable(L, LUA_REGISTRYINDEX);
-}
-
-/*
-** Free's up the memory alloc'd to the cursor data
-*/
-static void free_cur(cur_data* cur)
-{
-	int i;
-	XSQLVAR *var;
-
-	/* free the field memory blocks */
-	for (i=0, var = cur->out_sqlda->sqlvar; i < cur->out_sqlda->sqld; i++, var++) {
-		free(var->sqldata);
-		if(var->sqlind != NULL)
-			free(var->sqlind);
-	}
-
-	/* free the data array */
-	free(cur->out_sqlda);
-}
-
-/*
-** Shuts down a cursor
-*/
-static int cur_shut(lua_State *L, cur_data *cur)
-{
-	isc_dsql_free_statement(cur->env->status_vector, &cur->stmt,
-	                        DSQL_close);
-	if ( CHECK_DB_ERROR(cur->env->status_vector) ) {
-		return return_db_error(L, cur->env->status_vector);
-	}
-
-	/* free the cursor data */
-	free_cur(cur);
-
-	/* remove cursor from lock count and check if statment can be unregistered */
-	cur->closed = 1;
-	--cur->conn->lock;
-
-	/* check if connection can be unregistered */
-	if(cur->conn->lock == 0)
-		lua_unregisterobj(L, cur->conn);
-
-	return 0;
-}
-
-/*
-** Check for valid environment.
-*/
-static env_data *getenvironment (lua_State *L, int i) {
-	env_data *env = (env_data *)luaL_checkudata (L, i, LUASQL_ENVIRONMENT_FIREBIRD);
-	luaL_argcheck (L, env != NULL, i, "environment expected");
-	luaL_argcheck (L, !env->closed, i, "environment is closed");
-	return env;
-}
-
-/*
-** Check for valid connection.
-*/
-static conn_data *getconnection (lua_State *L, int i) {
-	conn_data *conn = (conn_data *)luaL_checkudata (L, i, LUASQL_CONNECTION_FIREBIRD);
-	luaL_argcheck (L, conn != NULL, i, "connection expected");
-	luaL_argcheck (L, !conn->closed, i, "connection is closed");
-	return conn;
-}
-
-/*
-** Check for valid cursor.
-*/
-static cur_data *getcursor (lua_State *L, int i) {
-	cur_data *cur = (cur_data *)luaL_checkudata (L, i, LUASQL_CURSOR_FIREBIRD);
-	luaL_argcheck (L, cur != NULL, i, "cursor expected");
-	luaL_argcheck (L, !cur->closed, i, "cursor is closed");
-	return cur;
-}
-
-/*
-** Returns the statement type
-*/
-static int get_statement_type(cur_data* cur)
-{
-	int length, type;
-	char type_item[] = { isc_info_sql_stmt_type };
-	char res_buffer[88], *pres;
-
-	pres = res_buffer;
-
-	isc_dsql_sql_info( cur->env->status_vector, &cur->stmt,
-						sizeof(type_item), type_item,
-						sizeof(res_buffer), res_buffer );
-	if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0)
-		return -1;
-
-	/* check the type of the statement */
-	if (*pres == isc_info_sql_stmt_type)
-	{
-		pres++;
-		length = isc_vax_integer(pres, 2);
-		pres += 2;
-		type = isc_vax_integer(pres, length);
-		pres += length;
-	} else
-		return -2;	/* should have had the isc_info_sql_stmt_type info */
-
-	return type;
-}
-
-/*
-** Return the number of rows affected by last operation
-*/
-static int count_rows_affected(cur_data* cur)
-{
-	int length, type, res=0;
-	int del_count = 0, ins_count = 0, upd_count = 0, sel_count = 0;
-	char type_item[] = { isc_info_sql_stmt_type, isc_info_sql_records };
-	char res_buffer[88], *pres;
-
-	pres = res_buffer;
-
-	isc_dsql_sql_info( cur->env->status_vector, &cur->stmt,
-						sizeof(type_item), type_item,
-						sizeof(res_buffer), res_buffer );
-	if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0)
-		return -1;
-
-	/* check the type of the statement */
-	if (*pres == isc_info_sql_stmt_type)
-	{
-		pres++;
-		length = isc_vax_integer(pres, 2);
-		pres += 2;
-		type = isc_vax_integer(pres, length);
-		pres += length;
-	} else
-		return -2;	/* should have had the isc_info_sql_stmt_type info */
-
-	if(type > 4)
-		return 0;	/* not a SELECT, INSERT, UPDATE or DELETE SQL statement */
-
-	if (*pres == isc_info_sql_records)
-	{
-		pres++;
-		length = isc_vax_integer(pres, 2); /* normally 29 bytes */
-        pres += 2;
-
-		while(*pres != 1) {
-			switch(*pres) {
-			case isc_info_req_select_count:
-				pres++;
-				length = isc_vax_integer(pres, 2);
-				pres += 2;
-				sel_count = isc_vax_integer(pres, length);
-				pres += length;
-				break;
-			case isc_info_req_insert_count:
-				pres++;
-				length = isc_vax_integer(pres, 2);
-				pres += 2;
-				ins_count = isc_vax_integer(pres, length);
-				pres += length;
-				break;
-			case isc_info_req_update_count:
-				pres++;
-				length = isc_vax_integer(pres, 2);
-				pres += 2;
-				upd_count = isc_vax_integer(pres, length);
-				pres += length;
-				break;
-			case isc_info_req_delete_count:
-				pres++;
-				length = isc_vax_integer(pres, 2);
-				pres += 2;
-				del_count = isc_vax_integer(pres, length);
-				pres += length;
-				break;
-			default:
-				pres++;
-				break;
-			}
-		}
-	} else
-		return -3;
-
-	switch(type) {
-	case isc_info_sql_stmt_select:
-		res = sel_count;
-		break;
-	case isc_info_sql_stmt_delete:
-		res = del_count;
-		break;
-	case isc_info_sql_stmt_update:
-		res = upd_count;
-		break;
-	case isc_info_sql_stmt_insert:
-		res = ins_count;
-		break;
-	}
-	return res;
-}
-
-static void *malloc_zero(size_t len)
-{
-	void *res = malloc(len);
-	memset(res, 0, len);
-	return res;
-}
-
-/*
-** Executes a SQL statement.
-** Returns
-**   cursor object: if there are results or
-**   row count: number of rows affected by statement if no results
-*/
-static int conn_execute (lua_State *L) {
-	conn_data *conn = getconnection(L,1);
-	const char *statement = luaL_checkstring(L, 2);
-	int dialect = (int)luaL_optnumber(L, 3, 3);
-
-	XSQLVAR *var;
-	long dtype;
-	int i, n, count;
-
-	cur_data cur;
-
-	cur.closed = 0;
-	cur.env = conn->env;
-	cur.conn = conn;
-	cur.stmt = 0;
-
-	cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(CURSOR_PREALLOC));
-	cur.out_sqlda->version = SQLDA_VERSION1;
-	cur.out_sqlda->sqln = CURSOR_PREALLOC;
-
-	/* create a statement to handle the query */
-	isc_dsql_allocate_statement(conn->env->status_vector, &conn->db, &cur.stmt);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-		free(cur.out_sqlda);
-		return return_db_error(L, conn->env->status_vector);
-	}
-
-	/* process the SQL ready to run the query */
-	isc_dsql_prepare(conn->env->status_vector, &conn->transaction, &cur.stmt, 0, (char*)statement, dialect, cur.out_sqlda);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-		free(cur.out_sqlda);
-		return return_db_error(L, conn->env->status_vector);
-	}
-
-	/* what type of SQL statement is it? */
-	cur.stmt_type = get_statement_type(&cur);
-	if(cur.stmt_type < 0) {
-		free(cur.out_sqlda);
-		return return_db_error(L, conn->env->status_vector);
-	}
-
-	/* an unsupported SQL statement (something like COMMIT) */
-	switch(cur.stmt_type) {
-	case isc_info_sql_stmt_select:
-	case isc_info_sql_stmt_insert:
-	case isc_info_sql_stmt_update:
-	case isc_info_sql_stmt_delete:
-	case isc_info_sql_stmt_ddl:
-	case isc_info_sql_stmt_exec_procedure:
-		break;
-	default:
-		free(cur.out_sqlda);
-		return luasql_faildirect(L, "unsupported SQL statement");
-	}
-
-	/* resize the result set if needed */
-	if (cur.out_sqlda->sqld > cur.out_sqlda->sqln)
-	{
-		n = cur.out_sqlda->sqld;
-		free(cur.out_sqlda);
-		cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n));
-		cur.out_sqlda->sqln = n;
-		cur.out_sqlda->version = SQLDA_VERSION1;
-		isc_dsql_describe(conn->env->status_vector, &cur.stmt, 1, cur.out_sqlda);
-		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-			free(cur.out_sqlda);
-			return return_db_error(L, conn->env->status_vector);
-		}
-	}
-
-	/* prep the result set ready to handle the data */
-	for (i=0, var = cur.out_sqlda->sqlvar; i < cur.out_sqlda->sqld; i++, var++) {
-		dtype = (var->sqltype & ~1); /* drop flag bit for now */
-		switch(dtype) {
-		case SQL_VARYING:
-			var->sqldata = (char *)malloc_zero(sizeof(char)*var->sqllen + 2);
-			break;
-		case SQL_TEXT:
-			var->sqldata = (char *)malloc_zero(sizeof(char)*var->sqllen);
-			break;
-		case SQL_SHORT:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_SHORT));
-			break;			
-		case SQL_LONG:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_LONG));
-			break;
-		case SQL_INT64:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_INT64));
-			break;
-		case SQL_FLOAT:
-			var->sqldata = (char *)malloc_zero(sizeof(float));
-			break;
-		case SQL_DOUBLE:
-			var->sqldata = (char *)malloc_zero(sizeof(double));
-			break;
-		case SQL_TYPE_TIME:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_TIME));
-			break;
-		case SQL_TYPE_DATE:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_DATE));
-			break;
-		case SQL_TIMESTAMP:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_TIMESTAMP));
-			break;
-		case SQL_BLOB:
-			var->sqldata = (char *)malloc_zero(sizeof(ISC_QUAD));
-			break;
-		/* TODO : add extra data type handles here */
-		}
-
-		if (var->sqltype & 1) {
-			/* allocate variable to hold NULL status */
-			var->sqlind = (short *)malloc(sizeof(short));
-		} else {
-			var->sqlind = NULL;
-		}
-	}
-
-	/* run the query */
-	isc_dsql_execute(conn->env->status_vector, &conn->transaction, &cur.stmt, 1, NULL);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-		free_cur(&cur);
-		return return_db_error(L, conn->env->status_vector);
-	}
-
-	/* if autocommit is set and it's a non SELECT query, commit change */
-	if(conn->autocommit != 0 && cur.stmt_type > 1) {
-		isc_commit_retaining(conn->env->status_vector, &conn->transaction);
-		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-			free_cur(&cur);
-			return return_db_error(L, conn->env->status_vector);
-		}
-	}
-
-	/* what do we return? a cursor or a count */
-	if(cur.out_sqlda->sqld > 0) { /* a cursor */
-		char cur_name[32];
-		cur_data* user_cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data));
-		luasql_setmeta (L, LUASQL_CURSOR_FIREBIRD);
-
-		sprintf(cur_name, "dyn_cursor_%p", (void *)user_cur);
-
-		/* open the cursor ready for fetch cycles */
-		isc_dsql_set_cursor_name(cur.env->status_vector, &cur.stmt, cur_name, 0);
-		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
-			lua_pop(L, 1);	/* the userdata */
-			free_cur(&cur);
-			return return_db_error(L, conn->env->status_vector);
-		}
-
-		/* copy the cursor into a new lua userdata object */
-		memcpy((void*)user_cur, (void*)&cur, sizeof(cur_data));
-
-		/* add cursor to the lock count */
-		lua_registerobj(L, 1, conn);
-		++conn->lock;
-	} else { /* a count */
-		if( (count = count_rows_affected(&cur)) < 0 ) {
-			free(cur.out_sqlda);
-			return return_db_error(L, conn->env->status_vector);
-		}
-
-		lua_pushnumber(L, count);
-
-		/* totaly finnished with the cursor */
-		isc_dsql_free_statement(conn->env->status_vector, &cur.stmt, DSQL_drop);
-		free(cur.out_sqlda);
-	}
-
-	return 1;
-}
-
-/*
-** Commits the current transaction
-*/
-static int conn_commit(lua_State *L) {
-	conn_data *conn = getconnection(L,1);
-
-	isc_commit_retaining(conn->env->status_vector, &conn->transaction);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) )
-		return return_db_error(L, conn->env->status_vector);
-
-	lua_pushboolean(L, 1);
-	return 1;
-}
-
-/*
-** Rolls back the current transaction
-** Lua Returns:
-**   1 if rollback is sucsessful
-**   nil and error message otherwise.
-*/
-static int conn_rollback(lua_State *L) {
-	conn_data *conn = getconnection(L,1);
-
-	isc_rollback_retaining(conn->env->status_vector, &conn->transaction);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) )
-		return return_db_error(L, conn->env->status_vector);
-
-	lua_pushboolean(L, 1);
-	return 1;
-}
-
-/*
-** Sets the autocommit state of the connection
-** Lua Returns:
-**   autocommit state (0:off, 1:on)
-**   nil and error message on error.
-*/
-static int conn_setautocommit(lua_State *L) {
-	conn_data *conn = getconnection(L,1);
-
-	if(lua_toboolean(L, 2))
-		conn->autocommit = 1;
-	else
-		conn->autocommit = 0;
-
-	lua_pushboolean(L, 1);
-	return 1;
-}
-
-/*
-** Closes a connection.
-** Lua Returns:
-**   1 if close was sucsessful, 0 if already closed
-**   nil and error message otherwise.
-*/
-static int conn_close (lua_State *L) {
-	conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD);
-	luaL_argcheck (L, conn != NULL, 1, "connection expected");
-
-	/* already closed */
-	if(conn->closed != 0) {
-		lua_pushboolean(L, 0);
-		return 1;
-	}
-
-	/* are all related cursors closed? */
-	if(conn->lock > 0)
-		return luasql_faildirect(L, "there are still open cursors");
-
-	if(conn->autocommit != 0)
-		isc_commit_transaction(conn->env->status_vector, &conn->transaction);
-	else
-		isc_rollback_transaction(conn->env->status_vector, &conn->transaction);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) )
-		return return_db_error(L, conn->env->status_vector);
-
-	isc_detach_database(conn->env->status_vector, &conn->db);
-	if ( CHECK_DB_ERROR(conn->env->status_vector) )
-		return return_db_error(L, conn->env->status_vector);
-
-	conn->closed = 1;
-	--conn->env->lock;
-
-	/* check environment can be GC'd */
-	if(conn->env->lock == 0)
-		lua_unregisterobj(L, conn->env);
-
-	lua_pushboolean(L, 1);
-	return 1;
-}
-
-/*
-** GCs an connection object
-*/
-static int conn_gc (lua_State *L) {
-	conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD);
-
-	if(conn->closed == 0) {
-		if(conn->autocommit != 0)
-			isc_commit_transaction(conn->env->status_vector, &conn->transaction);
-		else
-			isc_rollback_transaction(conn->env->status_vector, &conn->transaction);
-
-		isc_detach_database(conn->env->status_vector, &conn->db);
-
-		conn->closed = 1;
-		--conn->env->lock;
-
-		/* check environment can be GC'd */
-		if(conn->env->lock == 0)
-			lua_unregisterobj(L, conn->env);
-	}
-
-	return 0;
-}
-
-/*
-** Escapes a given string so that it can't break out of it's delimiting quotes
-*/
-static int conn_escape(lua_State *L) {
-	size_t len;
-	const char *from = luaL_checklstring (L, 2, &len);
-	char *res = malloc(len*sizeof(char)*2+1);
-	char *to = res;
-
-	if(res) {
-		while(*from != '\0') {
-			*(to++) = *from;
-			if(*from == '\'')
-				*(to++) = *from;
-
-			from++;
-		}
-		*to = '\0';
-
-		lua_pushstring(L, res);
-		free(res);
-		return 1;
-	}
-
-	luaL_error(L, "could not allocate escaped string");
-	return 0;
-}
-
-/*
-** Pushes the indexed value onto the lua stack
-*/
-static void push_column(lua_State *L, int i, cur_data *cur) {
-	int varcharlen;
-	struct tm timevar;
-	char timestr[256];
-	ISC_STATUS blob_stat;
-	isc_blob_handle blob_handle = 0;
-	ISC_QUAD blob_id;
-	luaL_Buffer b;
-	char *buffer;
-	unsigned short actual_seg_len;
-
-	if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) &&
-		(*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) {
-		/* a null field? */
-		lua_pushnil(L);
-	} else {
-		switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) {
-		case SQL_VARYING:
-			varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2);
-			lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen);
-			break;
-		case SQL_TEXT:
-			lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen);
-			break;
-		case SQL_SHORT:
-			luasql_pushinteger(L, *(ISC_SHORT*)(cur->out_sqlda->sqlvar[i].sqldata));
-			break;
-		case SQL_LONG:
-			luasql_pushinteger(L, *(ISC_LONG*)(cur->out_sqlda->sqlvar[i].sqldata));
-			break;
-		case SQL_INT64:
-			luasql_pushinteger(L, *(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata));
-			break;
-		case SQL_FLOAT:
-			lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata));
-			break;
-		case SQL_DOUBLE:
-			lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata));
-			break;
-		case SQL_TYPE_TIME:
-			isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
-			strftime(timestr, 255, "%X", &timevar);
-			lua_pushstring(L, timestr);
-			break;
-		case SQL_TYPE_DATE:
-			isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
-			strftime(timestr, 255, "%x", &timevar);
-			lua_pushstring(L, timestr);
-			break;
-		case SQL_TIMESTAMP:
-			isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
-			strftime(timestr, 255, "%x %X", &timevar);
-			lua_pushstring(L, timestr);
-			break;
-		case SQL_BLOB:
-			/* get the BLOB ID and open it */
-			memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD));
-			isc_open_blob2(	cur->env->status_vector,
-							&cur->conn->db, &cur->conn->transaction,
-							&blob_handle, &blob_id, 0, NULL );
-			/* fetch the blob data */
-			luaL_buffinit(L, &b);
-			buffer = luaL_prepbuffer(&b);
-
-			blob_stat = isc_get_segment(	cur->env->status_vector,
-											&blob_handle, &actual_seg_len,
-											LUAL_BUFFERSIZE, buffer );
-			while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) {
-				luaL_addsize(&b, actual_seg_len);
-				buffer = luaL_prepbuffer(&b);
-				blob_stat = isc_get_segment(	cur->env->status_vector,
-												&blob_handle, &actual_seg_len,
-												LUAL_BUFFERSIZE, buffer );
-			}
-
-			/* finnished, close the BLOB */
-			isc_close_blob(cur->env->status_vector, &blob_handle);
-			blob_handle = 0;
-
-			luaL_pushresult(&b);
-			break;
-		default:
-			lua_pushstring(L, "<unsupported data type>");
-			break;
-		}
-	}
-}
-
-/*
-** Returns a row of data from the query
-** Lua Returns:
-**   list of results or table of results depending on call
-**   nil and error message otherwise.
-*/
-static int cur_fetch (lua_State *L) {
-	ISC_STATUS fetch_stat;
-	int i, res;
-	cur_data *cur = (cur_data *)luaL_checkudata (L, 1, LUASQL_CURSOR_FIREBIRD);
-	const char *opts = luaL_optstring (L, 3, "n");
-	int num = strchr(opts, 'n') != NULL;
-	int alpha = strchr(opts, 'a') != NULL;
-
-	/* check cursor status */
-	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
-	if (cur->closed) {
-		return 0;
-	}
-
-	if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) {
-		if (lua_istable (L, 2)) {
-			/* remove the option string */
-			lua_settop(L, 2);
-
-			/* loop through the columns */
-			for (i = 0; i < cur->out_sqlda->sqld; i++) {
-				push_column(L, i, cur);
-
-				if (num) {
-					lua_pushnumber(L, i+1);
-					lua_pushvalue(L, -2);
-					lua_settable(L, 2);
-				}
-
-				if (alpha) {
-					lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length);
-					lua_pushvalue(L, -2);
-					lua_settable(L, 2);
-				}
-
-				lua_pop(L, 1);
-			}
-
-			/* returning given table */
-			res = 1;
-		} else {
-			for (i = 0; i < cur->out_sqlda->sqld; i++)
-				push_column(L, i, cur);
-
-			/* returning a list of values */
-			res = cur->out_sqlda->sqld;
-		}
-
-		/* close cursor for procedures/returnings as they (currently) only
-		   return one result, and error on subsequent fetches */
-		if (cur->stmt_type == isc_info_sql_stmt_exec_procedure) {
-			cur_shut(L, cur);
-		}
-
-		return res;
-	}
-
-	/* isc_dsql_fetch returns 100 if no more rows remain to be retrieved
-	   so this can be ignored */
-	if (fetch_stat != 100L)
-		return return_db_error(L, cur->env->status_vector);
-
-	/* last row has been fetched, close cursor */
-	isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop);
-	if ( CHECK_DB_ERROR(cur->env->status_vector) )
-		return return_db_error(L, cur->env->status_vector);
-
-	/* free the cursor data */
-	free_cur(cur);
-
-	cur->closed = 1;
-
-	/* remove cursor from lock count */
-	--cur->conn->lock;
-
-	/* return sucsess */
-	return 0;
-}
-
-/*
-** Returns a table of column names from the query
-** Lua Returns:
-**   a table of column names
-**   nil and error message otherwise.
-*/
-static int cur_colnames (lua_State *L) {
-	int i;
-	XSQLVAR *var;
-	cur_data *cur = getcursor(L,1);
-
-	lua_newtable(L);
-
-	for (i=1, var = cur->out_sqlda->sqlvar; i <= cur->out_sqlda->sqld; i++, var++) {
-		lua_pushnumber(L, i);
-		lua_pushlstring(L, var->aliasname, var->aliasname_length);
-		lua_settable(L, -3);
-	}
-
-	return 1;
-}
-
-/*
-** Returns a table of column types from the query
-** Lua Returns:
-**   a table of column types
-**   nil and error message otherwise.
-*/
-static int cur_coltypes (lua_State *L) {
-	int i;
-	XSQLVAR *var;
-	cur_data *cur = getcursor(L,1);
-
-	lua_newtable(L);
-
-	for (i=1, var = cur->out_sqlda->sqlvar; i <= cur->out_sqlda->sqld; i++, var++) {
-		lua_pushnumber(L, i);
-		switch(var->sqltype & ~1) {
-		case SQL_VARYING:
-		case SQL_TEXT:
-		case SQL_TYPE_TIME:
-		case SQL_TYPE_DATE:
-		case SQL_TIMESTAMP:
-		case SQL_BLOB:
-            lua_pushstring(L, "string");
-			break;
-		case SQL_SHORT:
-		case SQL_LONG:
-		case SQL_INT64:
-#if LUA_VERSION_NUM>=503
-            lua_pushstring(L, "integer");
-			break;
-#endif
-		case SQL_FLOAT:
-		case SQL_DOUBLE:
-            lua_pushstring(L, "number");
-			break;
-		default:
-            lua_pushstring(L, "unknown");
-			break;
-		}
-		lua_settable(L, -3);
-	}
-
-	return 1;
-}
-
-/*
-** Closes a cursor object
-** Lua Returns:
-**   1 if close was sucsessful, 0 if already closed
-**   nil and error message otherwise.
-*/
-static int cur_close (lua_State *L) {
-	cur_data *cur = (cur_data *)luaL_checkudata(L,1,LUASQL_CURSOR_FIREBIRD);
-	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
-	int shut_res;
-
-	if(cur->closed == 0) {
-		shut_res = cur_shut(L, cur);
-		if(shut_res > 0) {
-			return shut_res;
-		}
-
-		/* return sucsess */
-		lua_pushboolean(L, 1);
-		return 1;
-	}
-
-	lua_pushboolean(L, 0);
-	return 1;
-}
-
-/*
-** GCs a cursor object
-*/
-static int cur_gc (lua_State *L) {
-	cur_data *cur = (cur_data *)luaL_checkudata(L,1,LUASQL_CURSOR_FIREBIRD);
-	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
-
-	if(cur->closed == 0) {
-		cur_shut(L, cur);
-	}
-
-	return 0;
-}
-
-/*
-** Creates an Environment and returns it.
-*/
-static int create_environment (lua_State *L) {
-	int i;
-	env_data *env;
-
-	env = (env_data *)lua_newuserdata (L, sizeof (env_data));
-	luasql_setmeta (L, LUASQL_ENVIRONMENT_FIREBIRD);
-	/* fill in structure */
-	for(i=0; i<20; i++)
-		env->status_vector[i] = 0;
-	env->closed = 0;
-	env->lock = 0;
-
-	return 1;
-}
-
-/*
-** Creates and returns a connection object
-** Lua Input: source, user, pass
-**   source: data source
-**   user, pass: data source authentication information
-** Lua Returns:
-**   connection object if successfull
-**   nil and error message otherwise.
-*/
-static int env_connect (lua_State *L) {
-	char *dpb;
-	int i;
-	static char isc_tpb[] = {	isc_tpb_version3,
-								isc_tpb_write		};
-	conn_data conn;
-	conn_data* res_conn;
-
-	env_data *env = (env_data *) getenvironment (L, 1);
-	const char *sourcename = luaL_checkstring (L, 2);
-	const char *username = luaL_optstring (L, 3, "");
-	const char *password = luaL_optstring (L, 4, "");
-
-	conn.env = env;
-	conn.db = 0L;
-	conn.transaction = 0L;
-	conn.lock = 0;
-	conn.autocommit = 0;
-
-	/* Construct a database parameter buffer. */
-	dpb = conn.dpb_buffer;
-	*dpb++ = isc_dpb_version1;
-	*dpb++ = isc_dpb_num_buffers;
-	*dpb++ = 1;
-	*dpb++ = 90;
-
-	/* add the user name and password */
-	*dpb++ = isc_dpb_user_name;
-    *dpb++ = (char)strlen(username);
-	for(i=0; i<(int)strlen(username); i++)
-		*dpb++ = username[i];
-	*dpb++ = isc_dpb_password;
-    *dpb++ = (char)strlen(password);
-	for(i=0; i<(int)strlen(password); i++)
-		*dpb++ = password[i];
-
-	/* the length of the dpb */
-	conn.dpb_length = (short)(dpb - conn.dpb_buffer);
-
-	/* do the job */
-	isc_attach_database(env->status_vector, (short)strlen(sourcename), (char*)sourcename, &conn.db,
-						conn.dpb_length,	conn.dpb_buffer);
-
-	/* an error? */
-	if ( CHECK_DB_ERROR(conn.env->status_vector) )
-		return return_db_error(L, conn.env->status_vector);
-
-	/* open up the transaction handle */
-	isc_start_transaction(	env->status_vector, &conn.transaction, 1,
-							&conn.db, (unsigned short)sizeof(isc_tpb),
-							isc_tpb );
-
-	/* return NULL on error */
-	if ( CHECK_DB_ERROR(conn.env->status_vector) )
-		return return_db_error(L, conn.env->status_vector);
-
-	/* create the lua object and add the connection to the lock */
-	res_conn = (conn_data*)lua_newuserdata(L, sizeof(conn_data));
-	luasql_setmeta (L, LUASQL_CONNECTION_FIREBIRD);
-	memcpy(res_conn, &conn, sizeof(conn_data));
-	res_conn->closed = 0;   /* connect now officially open */
-
-	/* register the connection */
-	lua_registerobj(L, 1, env);
-	++env->lock;
-
-	return 1;
-}
-
-/*
-** Closes an environment object
-** Lua Returns:
-**   1 if close was sucsessful, 0 if already closed
-**   nil and error message otherwise.
-*/
-static int env_close (lua_State *L) {
-	env_data *env = (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_FIREBIRD);
-	luaL_argcheck (L, env != NULL, 1, "environment expected");
-	
-	/* already closed? */
-	if(env->closed == 1) {
-		lua_pushboolean(L, 0);
-		return 1;
-	}
-
-	/* check the lock */
-	if(env->lock > 0)
-		return luasql_faildirect(L, "there are still open connections");
-
-	/* unregister */
-	lua_unregisterobj(L, env);
-
-	/* mark as closed */
-	env->closed = 1;
-
-	lua_pushboolean(L, 1);
-	return 1;
-}
-
-/*
-** GCs an environment object
-*/
-static int env_gc (lua_State *L) {
-	/* nothing to be done for the FB envronment */
-	return 0;
-}
-
-/*
-** Create metatables for each class of object.
-*/
-static void create_metatables (lua_State *L) {
-	struct luaL_Reg environment_methods[] = {
-		{"__gc", env_gc},
-		{"close", env_close},
-		{"connect", env_connect},
-		{NULL, NULL},
-	};
-	struct luaL_Reg connection_methods[] = {
-		{"__gc", conn_gc},
-		{"close", conn_close},
-		{"execute", conn_execute},
-		{"commit", conn_commit},
-		{"rollback", conn_rollback},
-		{"setautocommit", conn_setautocommit},
-		{"escape", conn_escape},
-		{NULL, NULL},
-	};
-	struct luaL_Reg cursor_methods[] = {
-		{"__gc", cur_gc},
-		{"close", cur_close},
-		{"fetch", cur_fetch},
-		{"getcoltypes", cur_coltypes},
-		{"getcolnames", cur_colnames},
-		{NULL, NULL},
-	};
-	luasql_createmeta (L, LUASQL_ENVIRONMENT_FIREBIRD, environment_methods);
-	luasql_createmeta (L, LUASQL_CONNECTION_FIREBIRD, connection_methods);
-	luasql_createmeta (L, LUASQL_CURSOR_FIREBIRD, cursor_methods);
-	lua_pop (L, 3);
-}
-
-/*
-** Creates the metatables for the objects and registers the
-** driver open method.
-*/
-LUASQL_API int luaopen_luasql_firebird (lua_State *L) {
-	struct luaL_Reg driver[] = {
-		{"firebird", create_environment},
-		{NULL, NULL},
-	};
-	create_metatables (L);
-	lua_newtable (L);
-	luaL_setfuncs (L, driver, 0);
-	luasql_set_info (L);
-	return 1;
-} 
+/*
+** LuaSQL, Firebird driver
+** Authors: Scott Morgan
+** ls_firebird.c
+*/
+
+#include <ibase.h>	/* The Firebird API*/
+#include <time.h>	/* For managing time values */
+#include <stdlib.h>
+#include <string.h>
+
+/* Lua API */
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "luasql.h"
+
+#define LUASQL_ENVIRONMENT_FIREBIRD "Firebird environment"
+#define LUASQL_CONNECTION_FIREBIRD "Firebird connection"
+#define LUASQL_CURSOR_FIREBIRD "Firebird cursor"
+
+typedef struct {
+	short closed;
+	ISC_STATUS status_vector[20];	/* for error results */
+	int lock;						/* lock count for open connections */
+} env_data;
+
+typedef struct {
+	short			closed;
+	env_data*		env;			/* the DB environment this is in */
+	isc_db_handle	db;				/* the database handle */
+	char			dpb_buffer[256];/* holds the database parameter buffer */
+	short			dpb_length;		/* the used amount of the dpb */
+	isc_tr_handle	transaction;	/* the transaction handle */
+	int				lock;			/* lock count for open cursors */
+	int				autocommit;		/* should each statement be committed */
+} conn_data;
+
+typedef struct {
+	short			closed;
+	env_data*		env;			/* the DB environment this is in */
+	conn_data*		conn;			/* the DB connection this cursor is from */
+	isc_stmt_handle stmt;			/* the statement handle */
+	int			stmt_type;			/* the type of the statement */
+	XSQLDA			*out_sqlda;		/* the cursor data array */
+} cur_data;
+
+/* How many fields to pre-alloc to the cursor */
+#define CURSOR_PREALLOC 10
+
+/* Macro to ease code reading */
+#define CHECK_DB_ERROR( X ) ( (X)[0] == 1 && (X)[1] )
+
+/* Use the new interpret API if available */
+#undef FB_INTERPRET
+#if FB_API_VER >= 20
+  #define FB_INTERPRET(BUF, LEN, VECTOR) fb_interpret(BUF, LEN, VECTOR)
+#else
+  #define FB_INTERPRET(BUF, LEN, VECTOR) isc_interpret(BUF, VECTOR)
+#endif
+
+#if LUA_VERSION_NUM>=503
+#define luasql_pushinteger lua_pushinteger
+#else
+#define luasql_pushinteger lua_pushnumber
+#endif
+
+/*
+** Returns a standard database error message
+*/
+static int return_db_error(lua_State *L, const ISC_STATUS *pvector)
+{
+	char errmsg[512];
+
+	lua_pushnil(L);
+	FB_INTERPRET(errmsg, 512, &pvector);
+	lua_pushstring(L, errmsg);
+	while(FB_INTERPRET(errmsg, 512, &pvector)) {
+		lua_pushstring(L, "\n * ");
+		lua_pushstring(L, errmsg);
+		lua_concat(L, 3);
+	}
+
+	return 2;
+}
+
+/*
+** Registers a given C object in the registry to avoid GC
+*/
+static void lua_registerobj(lua_State *L, int index, void *obj)
+{
+	lua_pushvalue(L, index);
+	lua_pushlightuserdata(L, obj);
+	lua_pushvalue(L, -2);
+	lua_settable(L, LUA_REGISTRYINDEX);
+	lua_pop(L, 1);
+}
+
+/*
+** Unregisters a given C object from the registry
+*/
+static void lua_unregisterobj(lua_State *L, void *obj)
+{
+	lua_pushlightuserdata(L, obj);
+	lua_pushnil(L);
+	lua_settable(L, LUA_REGISTRYINDEX);
+}
+
+/*
+** Free's up the memory alloc'd to the cursor data
+*/
+static void free_cur(cur_data* cur)
+{
+	int i;
+	XSQLVAR *var;
+
+	/* free the field memory blocks */
+	for (i=0, var = cur->out_sqlda->sqlvar; i < cur->out_sqlda->sqld; i++, var++) {
+		free(var->sqldata);
+		if(var->sqlind != NULL)
+			free(var->sqlind);
+	}
+
+	/* free the data array */
+	free(cur->out_sqlda);
+}
+
+/*
+** Shuts down a cursor
+*/
+static int cur_shut(lua_State *L, cur_data *cur)
+{
+	isc_dsql_free_statement(cur->env->status_vector, &cur->stmt,
+	                        DSQL_close);
+	if ( CHECK_DB_ERROR(cur->env->status_vector) ) {
+		return return_db_error(L, cur->env->status_vector);
+	}
+
+	/* free the cursor data */
+	free_cur(cur);
+
+	/* remove cursor from lock count and check if statement can be unregistered */
+	cur->closed = 1;
+	--cur->conn->lock;
+
+	/* check if connection can be unregistered */
+	if(cur->conn->lock == 0)
+		lua_unregisterobj(L, cur->conn);
+
+	return 0;
+}
+
+/*
+** Check for valid environment.
+*/
+static env_data *getenvironment (lua_State *L, int i) {
+	env_data *env = (env_data *)luaL_checkudata (L, i, LUASQL_ENVIRONMENT_FIREBIRD);
+	luaL_argcheck (L, env != NULL, i, "environment expected");
+	luaL_argcheck (L, !env->closed, i, "environment is closed");
+	return env;
+}
+
+/*
+** Check for valid connection.
+*/
+static conn_data *getconnection (lua_State *L, int i) {
+	conn_data *conn = (conn_data *)luaL_checkudata (L, i, LUASQL_CONNECTION_FIREBIRD);
+	luaL_argcheck (L, conn != NULL, i, "connection expected");
+	luaL_argcheck (L, !conn->closed, i, "connection is closed");
+	return conn;
+}
+
+/*
+** Check for valid cursor.
+*/
+static cur_data *getcursor (lua_State *L, int i) {
+	cur_data *cur = (cur_data *)luaL_checkudata (L, i, LUASQL_CURSOR_FIREBIRD);
+	luaL_argcheck (L, cur != NULL, i, "cursor expected");
+	luaL_argcheck (L, !cur->closed, i, "cursor is closed");
+	return cur;
+}
+
+/*
+** Returns the statement type
+*/
+static int get_statement_type(cur_data* cur)
+{
+	int length, type;
+	char type_item[] = { isc_info_sql_stmt_type };
+	char res_buffer[88], *pres;
+
+	pres = res_buffer;
+
+	isc_dsql_sql_info( cur->env->status_vector, &cur->stmt,
+						sizeof(type_item), type_item,
+						sizeof(res_buffer), res_buffer );
+	if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0)
+		return -1;
+
+	/* check the type of the statement */
+	if (*pres == isc_info_sql_stmt_type)
+	{
+		pres++;
+		length = isc_vax_integer(pres, 2);
+		pres += 2;
+		type = isc_vax_integer(pres, length);
+		pres += length;
+	} else
+		return -2;	/* should have had the isc_info_sql_stmt_type info */
+
+	return type;
+}
+
+/*
+** Return the number of rows affected by last operation
+*/
+static int count_rows_affected(cur_data* cur)
+{
+	int length, type, res=0;
+	int del_count = 0, ins_count = 0, upd_count = 0, sel_count = 0;
+	char type_item[] = { isc_info_sql_stmt_type, isc_info_sql_records };
+	char res_buffer[88], *pres;
+
+	pres = res_buffer;
+
+	isc_dsql_sql_info( cur->env->status_vector, &cur->stmt,
+						sizeof(type_item), type_item,
+						sizeof(res_buffer), res_buffer );
+	if (cur->env->status_vector[0] == 1 && cur->env->status_vector[1] > 0)
+		return -1;
+
+	/* check the type of the statement */
+	if (*pres == isc_info_sql_stmt_type)
+	{
+		pres++;
+		length = isc_vax_integer(pres, 2);
+		pres += 2;
+		type = isc_vax_integer(pres, length);
+		pres += length;
+	} else
+		return -2;	/* should have had the isc_info_sql_stmt_type info */
+
+	if(type > 4)
+		return 0;	/* not a SELECT, INSERT, UPDATE or DELETE SQL statement */
+
+	if (*pres == isc_info_sql_records)
+	{
+		pres++;
+		length = isc_vax_integer(pres, 2); /* normally 29 bytes */
+        pres += 2;
+
+		while(*pres != 1) {
+			switch(*pres) {
+			case isc_info_req_select_count:
+				pres++;
+				length = isc_vax_integer(pres, 2);
+				pres += 2;
+				sel_count = isc_vax_integer(pres, length);
+				pres += length;
+				break;
+			case isc_info_req_insert_count:
+				pres++;
+				length = isc_vax_integer(pres, 2);
+				pres += 2;
+				ins_count = isc_vax_integer(pres, length);
+				pres += length;
+				break;
+			case isc_info_req_update_count:
+				pres++;
+				length = isc_vax_integer(pres, 2);
+				pres += 2;
+				upd_count = isc_vax_integer(pres, length);
+				pres += length;
+				break;
+			case isc_info_req_delete_count:
+				pres++;
+				length = isc_vax_integer(pres, 2);
+				pres += 2;
+				del_count = isc_vax_integer(pres, length);
+				pres += length;
+				break;
+			default:
+				pres++;
+				break;
+			}
+		}
+	} else
+		return -3;
+
+	switch(type) {
+	case isc_info_sql_stmt_select:
+		res = sel_count;
+		break;
+	case isc_info_sql_stmt_delete:
+		res = del_count;
+		break;
+	case isc_info_sql_stmt_update:
+		res = upd_count;
+		break;
+	case isc_info_sql_stmt_insert:
+		res = ins_count;
+		break;
+	}
+	return res;
+}
+
+static void *malloc_zero(size_t len)
+{
+	void *res = malloc(len);
+	memset(res, 0, len);
+	return res;
+}
+
+/*
+** Executes a SQL statement.
+** Returns
+**   cursor object: if there are results or
+**   row count: number of rows affected by statement if no results
+*/
+static int conn_execute (lua_State *L) {
+	conn_data *conn = getconnection(L,1);
+	const char *statement = luaL_checkstring(L, 2);
+	int dialect = (int)luaL_optnumber(L, 3, 3);
+
+	XSQLVAR *var;
+	long dtype;
+	int i, n, count;
+
+	cur_data cur;
+
+	cur.closed = 0;
+	cur.env = conn->env;
+	cur.conn = conn;
+	cur.stmt = 0;
+
+	cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(CURSOR_PREALLOC));
+	cur.out_sqlda->version = SQLDA_VERSION1;
+	cur.out_sqlda->sqln = CURSOR_PREALLOC;
+
+	/* create a statement to handle the query */
+	isc_dsql_allocate_statement(conn->env->status_vector, &conn->db, &cur.stmt);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+		free(cur.out_sqlda);
+		return return_db_error(L, conn->env->status_vector);
+	}
+
+	/* process the SQL ready to run the query */
+	isc_dsql_prepare(conn->env->status_vector, &conn->transaction, &cur.stmt, 0, (char*)statement, dialect, cur.out_sqlda);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+		free(cur.out_sqlda);
+		return return_db_error(L, conn->env->status_vector);
+	}
+
+	/* what type of SQL statement is it? */
+	cur.stmt_type = get_statement_type(&cur);
+	if(cur.stmt_type < 0) {
+		free(cur.out_sqlda);
+		return return_db_error(L, conn->env->status_vector);
+	}
+
+	/* an unsupported SQL statement (something like COMMIT) */
+	switch(cur.stmt_type) {
+	case isc_info_sql_stmt_select:
+	case isc_info_sql_stmt_insert:
+	case isc_info_sql_stmt_update:
+	case isc_info_sql_stmt_delete:
+	case isc_info_sql_stmt_ddl:
+	case isc_info_sql_stmt_exec_procedure:
+		break;
+	default:
+		free(cur.out_sqlda);
+		return luasql_faildirect(L, "unsupported SQL statement");
+	}
+
+	/* resize the result set if needed */
+	if (cur.out_sqlda->sqld > cur.out_sqlda->sqln)
+	{
+		n = cur.out_sqlda->sqld;
+		free(cur.out_sqlda);
+		cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n));
+		cur.out_sqlda->sqln = n;
+		cur.out_sqlda->version = SQLDA_VERSION1;
+		isc_dsql_describe(conn->env->status_vector, &cur.stmt, 1, cur.out_sqlda);
+		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+			free(cur.out_sqlda);
+			return return_db_error(L, conn->env->status_vector);
+		}
+	}
+
+	/* prep the result set ready to handle the data */
+	for (i=0, var = cur.out_sqlda->sqlvar; i < cur.out_sqlda->sqld; i++, var++) {
+		dtype = (var->sqltype & ~1); /* drop flag bit for now */
+		switch(dtype) {
+		case SQL_VARYING:
+			var->sqldata = (char *)malloc_zero(sizeof(char)*var->sqllen + 2);
+			break;
+		case SQL_TEXT:
+			var->sqldata = (char *)malloc_zero(sizeof(char)*var->sqllen);
+			break;
+		case SQL_SHORT:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_SHORT));
+			break;			
+		case SQL_LONG:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_LONG));
+			break;
+		case SQL_INT64:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_INT64));
+			break;
+		case SQL_FLOAT:
+			var->sqldata = (char *)malloc_zero(sizeof(float));
+			break;
+		case SQL_DOUBLE:
+			var->sqldata = (char *)malloc_zero(sizeof(double));
+			break;
+		case SQL_TYPE_TIME:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_TIME));
+			break;
+		case SQL_TYPE_DATE:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_DATE));
+			break;
+		case SQL_TIMESTAMP:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_TIMESTAMP));
+			break;
+		case SQL_BLOB:
+			var->sqldata = (char *)malloc_zero(sizeof(ISC_QUAD));
+			break;
+		/* TODO : add extra data type handles here */
+		}
+
+		if (var->sqltype & 1) {
+			/* allocate variable to hold NULL status */
+			var->sqlind = (short *)malloc(sizeof(short));
+		} else {
+			var->sqlind = NULL;
+		}
+	}
+
+	/* run the query */
+	isc_dsql_execute(conn->env->status_vector, &conn->transaction, &cur.stmt, 1, NULL);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+		free_cur(&cur);
+		return return_db_error(L, conn->env->status_vector);
+	}
+
+	/* if autocommit is set and it's a non SELECT query, commit change */
+	if(conn->autocommit != 0 && cur.stmt_type > 1) {
+		isc_commit_retaining(conn->env->status_vector, &conn->transaction);
+		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+			free_cur(&cur);
+			return return_db_error(L, conn->env->status_vector);
+		}
+	}
+
+	/* what do we return? a cursor or a count */
+	if(cur.out_sqlda->sqld > 0) { /* a cursor */
+		char cur_name[32];
+		cur_data* user_cur = (cur_data*)LUASQL_NEWUD(L, sizeof(cur_data));
+		luasql_setmeta (L, LUASQL_CURSOR_FIREBIRD);
+
+		sprintf(cur_name, "dyn_cursor_%p", (void *)user_cur);
+
+		/* open the cursor ready for fetch cycles */
+		isc_dsql_set_cursor_name(cur.env->status_vector, &cur.stmt, cur_name, 0);
+		if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
+			lua_pop(L, 1);	/* the userdata */
+			free_cur(&cur);
+			return return_db_error(L, conn->env->status_vector);
+		}
+
+		/* copy the cursor into a new lua userdata object */
+		memcpy((void*)user_cur, (void*)&cur, sizeof(cur_data));
+
+		/* add cursor to the lock count */
+		lua_registerobj(L, 1, conn);
+		++conn->lock;
+	} else { /* a count */
+		if( (count = count_rows_affected(&cur)) < 0 ) {
+			free(cur.out_sqlda);
+			return return_db_error(L, conn->env->status_vector);
+		}
+
+		lua_pushnumber(L, count);
+
+		/* totally finished with the cursor */
+		isc_dsql_free_statement(conn->env->status_vector, &cur.stmt, DSQL_drop);
+		free(cur.out_sqlda);
+	}
+
+	return 1;
+}
+
+/*
+** Commits the current transaction
+*/
+static int conn_commit(lua_State *L) {
+	conn_data *conn = getconnection(L,1);
+
+	isc_commit_retaining(conn->env->status_vector, &conn->transaction);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) )
+		return return_db_error(L, conn->env->status_vector);
+
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+/*
+** Rolls back the current transaction
+** Lua Returns:
+**   1 if rollback is successful
+**   nil and error message otherwise.
+*/
+static int conn_rollback(lua_State *L) {
+	conn_data *conn = getconnection(L,1);
+
+	isc_rollback_retaining(conn->env->status_vector, &conn->transaction);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) )
+		return return_db_error(L, conn->env->status_vector);
+
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+/*
+** Sets the autocommit state of the connection
+** Lua Returns:
+**   autocommit state (0:off, 1:on)
+**   nil and error message on error.
+*/
+static int conn_setautocommit(lua_State *L) {
+	conn_data *conn = getconnection(L,1);
+
+	if(lua_toboolean(L, 2))
+		conn->autocommit = 1;
+	else
+		conn->autocommit = 0;
+
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+/*
+** Closes a connection.
+** Lua Returns:
+**   1 if close was sucsessful, 0 if already closed
+**   nil and error message otherwise.
+*/
+static int conn_close (lua_State *L) {
+	conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD);
+	luaL_argcheck (L, conn != NULL, 1, "connection expected");
+
+	/* already closed */
+	if(conn->closed != 0) {
+		lua_pushboolean(L, 0);
+		lua_pushstring(L, "Connection is already closed");
+		return 2;
+	}
+
+	/* are all related cursors closed? */
+	if(conn->lock > 0)
+		return luasql_faildirect(L, "there are still open cursors");
+
+	if(conn->autocommit != 0)
+		isc_commit_transaction(conn->env->status_vector, &conn->transaction);
+	else
+		isc_rollback_transaction(conn->env->status_vector, &conn->transaction);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) )
+		return return_db_error(L, conn->env->status_vector);
+
+	isc_detach_database(conn->env->status_vector, &conn->db);
+	if ( CHECK_DB_ERROR(conn->env->status_vector) )
+		return return_db_error(L, conn->env->status_vector);
+
+	conn->closed = 1;
+	--conn->env->lock;
+
+	/* check environment can be GC'd */
+	if(conn->env->lock == 0)
+		lua_unregisterobj(L, conn->env);
+
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+/*
+** GCs an connection object
+*/
+static int conn_gc (lua_State *L) {
+	conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD);
+
+	if(conn->closed == 0) {
+		if(conn->autocommit != 0)
+			isc_commit_transaction(conn->env->status_vector, &conn->transaction);
+		else
+			isc_rollback_transaction(conn->env->status_vector, &conn->transaction);
+
+		isc_detach_database(conn->env->status_vector, &conn->db);
+
+		conn->closed = 1;
+		--conn->env->lock;
+
+		/* check environment can be GC'd */
+		if(conn->env->lock == 0)
+			lua_unregisterobj(L, conn->env);
+	}
+
+	return 0;
+}
+
+/*
+** Escapes a given string so that it can't break out of it's delimiting quotes
+*/
+static int conn_escape(lua_State *L) {
+	size_t len;
+	const char *from = luaL_checklstring (L, 2, &len);
+	char *res = malloc(len*sizeof(char)*2+1);
+	char *to = res;
+
+	if(res) {
+		while(*from != '\0') {
+			*(to++) = *from;
+			if(*from == '\'')
+				*(to++) = *from;
+
+			from++;
+		}
+		*to = '\0';
+
+		lua_pushstring(L, res);
+		free(res);
+		return 1;
+	}
+
+	luaL_error(L, "could not allocate escaped string");
+	return 0;
+}
+
+/*
+** Pushes the indexed value onto the lua stack
+*/
+static void push_column(lua_State *L, int i, cur_data *cur) {
+	int varcharlen;
+	struct tm timevar;
+	char timestr[256];
+	ISC_STATUS blob_stat;
+	isc_blob_handle blob_handle = 0;
+	ISC_QUAD blob_id;
+	luaL_Buffer b;
+	char *buffer;
+	unsigned short actual_seg_len;
+
+	if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) &&
+		(*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) {
+		/* a null field? */
+		lua_pushnil(L);
+	} else {
+		switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) {
+		case SQL_VARYING:
+			varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2);
+			lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen);
+			break;
+		case SQL_TEXT:
+			lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen);
+			break;
+		case SQL_SHORT:
+			luasql_pushinteger(L, *(ISC_SHORT*)(cur->out_sqlda->sqlvar[i].sqldata));
+			break;
+		case SQL_LONG:
+			luasql_pushinteger(L, *(ISC_LONG*)(cur->out_sqlda->sqlvar[i].sqldata));
+			break;
+		case SQL_INT64:
+			luasql_pushinteger(L, *(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata));
+			break;
+		case SQL_FLOAT:
+			lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata));
+			break;
+		case SQL_DOUBLE:
+			lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata));
+			break;
+		case SQL_TYPE_TIME:
+			isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
+			strftime(timestr, 255, "%X", &timevar);
+			lua_pushstring(L, timestr);
+			break;
+		case SQL_TYPE_DATE:
+			isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
+			strftime(timestr, 255, "%x", &timevar);
+			lua_pushstring(L, timestr);
+			break;
+		case SQL_TIMESTAMP:
+			isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
+			strftime(timestr, 255, "%x %X", &timevar);
+			lua_pushstring(L, timestr);
+			break;
+		case SQL_BLOB:
+			/* get the BLOB ID and open it */
+			memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD));
+			isc_open_blob2(	cur->env->status_vector,
+							&cur->conn->db, &cur->conn->transaction,
+							&blob_handle, &blob_id, 0, NULL );
+			/* fetch the blob data */
+			luaL_buffinit(L, &b);
+			buffer = luaL_prepbuffer(&b);
+
+			blob_stat = isc_get_segment(	cur->env->status_vector,
+											&blob_handle, &actual_seg_len,
+											LUAL_BUFFERSIZE, buffer );
+			while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) {
+				luaL_addsize(&b, actual_seg_len);
+				buffer = luaL_prepbuffer(&b);
+				blob_stat = isc_get_segment(	cur->env->status_vector,
+												&blob_handle, &actual_seg_len,
+												LUAL_BUFFERSIZE, buffer );
+			}
+
+			/* finished, close the BLOB */
+			isc_close_blob(cur->env->status_vector, &blob_handle);
+			blob_handle = 0;
+
+			luaL_pushresult(&b);
+			break;
+		default:
+			lua_pushstring(L, "<unsupported data type>");
+			break;
+		}
+	}
+}
+
+/*
+** Returns a row of data from the query
+** Lua Returns:
+**   list of results or table of results depending on call
+**   nil and error message otherwise.
+*/
+static int cur_fetch (lua_State *L) {
+	ISC_STATUS fetch_stat;
+	int i, res;
+	cur_data *cur = (cur_data *)luaL_checkudata (L, 1, LUASQL_CURSOR_FIREBIRD);
+	const char *opts = luaL_optstring (L, 3, "n");
+	int num = strchr(opts, 'n') != NULL;
+	int alpha = strchr(opts, 'a') != NULL;
+
+	/* check cursor status */
+	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
+	if (cur->closed) {
+		return 0;
+	}
+
+	if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) {
+		if (lua_istable (L, 2)) {
+			/* remove the option string */
+			lua_settop(L, 2);
+
+			/* loop through the columns */
+			for (i = 0; i < cur->out_sqlda->sqld; i++) {
+				push_column(L, i, cur);
+
+				if (num) {
+					lua_pushnumber(L, i+1);
+					lua_pushvalue(L, -2);
+					lua_settable(L, 2);
+				}
+
+				if (alpha) {
+					lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length);
+					lua_pushvalue(L, -2);
+					lua_settable(L, 2);
+				}
+
+				lua_pop(L, 1);
+			}
+
+			/* returning given table */
+			res = 1;
+		} else {
+			for (i = 0; i < cur->out_sqlda->sqld; i++)
+				push_column(L, i, cur);
+
+			/* returning a list of values */
+			res = cur->out_sqlda->sqld;
+		}
+
+		/* close cursor for procedures/returnings as they (currently) only
+		   return one result, and error on subsequent fetches */
+		if (cur->stmt_type == isc_info_sql_stmt_exec_procedure) {
+			int shut_res = cur_shut(L, cur);
+			if (shut_res != 0) {
+				return shut_res;
+			}
+		}
+
+		return res;
+	}
+
+	/* isc_dsql_fetch returns 100 if no more rows remain to be retrieved
+	   so this can be ignored */
+	if (fetch_stat != 100L)
+		return return_db_error(L, cur->env->status_vector);
+
+	/* last row has been fetched, close cursor */
+	isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop);
+	if ( CHECK_DB_ERROR(cur->env->status_vector) )
+		return return_db_error(L, cur->env->status_vector);
+
+	/* free the cursor data */
+	free_cur(cur);
+
+	cur->closed = 1;
+
+	/* remove cursor from lock count */
+	--cur->conn->lock;
+
+	/* return sucsess */
+	return 0;
+}
+
+/*
+** Returns a table of column names from the query
+** Lua Returns:
+**   a table of column names
+**   nil and error message otherwise.
+*/
+static int cur_colnames (lua_State *L) {
+	int i;
+	XSQLVAR *var;
+	cur_data *cur = getcursor(L,1);
+
+	lua_newtable(L);
+
+	for (i=1, var = cur->out_sqlda->sqlvar; i <= cur->out_sqlda->sqld; i++, var++) {
+		lua_pushnumber(L, i);
+		lua_pushlstring(L, var->aliasname, var->aliasname_length);
+		lua_settable(L, -3);
+	}
+
+	return 1;
+}
+
+/*
+** Returns a table of column types from the query
+** Lua Returns:
+**   a table of column types
+**   nil and error message otherwise.
+*/
+static int cur_coltypes (lua_State *L) {
+	int i;
+	XSQLVAR *var;
+	cur_data *cur = getcursor(L,1);
+
+	lua_newtable(L);
+
+	for (i=1, var = cur->out_sqlda->sqlvar; i <= cur->out_sqlda->sqld; i++, var++) {
+		lua_pushnumber(L, i);
+		switch(var->sqltype & ~1) {
+		case SQL_VARYING:
+		case SQL_TEXT:
+		case SQL_TYPE_TIME:
+		case SQL_TYPE_DATE:
+		case SQL_TIMESTAMP:
+		case SQL_BLOB:
+            lua_pushstring(L, "string");
+			break;
+		case SQL_SHORT:
+		case SQL_LONG:
+		case SQL_INT64:
+#if LUA_VERSION_NUM>=503
+            lua_pushstring(L, "integer");
+			break;
+#endif
+		case SQL_FLOAT:
+		case SQL_DOUBLE:
+            lua_pushstring(L, "number");
+			break;
+		default:
+            lua_pushstring(L, "unknown");
+			break;
+		}
+		lua_settable(L, -3);
+	}
+
+	return 1;
+}
+
+/*
+** Closes a cursor object
+** Lua Returns:
+**   1 if close was sucsessful, 0 if already closed
+**   nil and error message otherwise.
+*/
+static int cur_close (lua_State *L) {
+	cur_data *cur = (cur_data *)luaL_checkudata(L,1,LUASQL_CURSOR_FIREBIRD);
+	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
+	int shut_res;
+
+	if (cur->closed == 0) {
+		shut_res = cur_shut(L, cur);
+		if (shut_res > 0) {
+			return shut_res;
+		}
+
+		lua_pushboolean(L, 1);
+		return 1;
+	}
+
+	lua_pushboolean(L, 0);
+	lua_pushstring(L, "cursor is already closed");
+	return 2;
+}
+
+/*
+** GCs a cursor object
+*/
+static int cur_gc (lua_State *L) {
+	cur_data *cur = (cur_data *)luaL_checkudata(L,1,LUASQL_CURSOR_FIREBIRD);
+	luaL_argcheck (L, cur != NULL, 1, "cursor expected");
+
+	if(cur->closed == 0) {
+		int shut_res = cur_shut(L, cur);
+		if (shut_res > 0) {
+			return shut_res;
+		}
+	}
+
+	return 0;
+}
+
+/*
+** Creates an Environment and returns it.
+*/
+static int create_environment (lua_State *L) {
+	int i;
+	env_data *env;
+
+	env = (env_data *)LUASQL_NEWUD (L, sizeof (env_data));
+	luasql_setmeta (L, LUASQL_ENVIRONMENT_FIREBIRD);
+	/* fill in structure */
+	for(i=0; i<20; i++)
+		env->status_vector[i] = 0;
+	env->closed = 0;
+	env->lock = 0;
+
+	return 1;
+}
+
+/*
+** Creates and returns a connection object
+** Lua Input: source, user, pass
+**   source: data source
+**   user, pass: data source authentication information
+** Lua Returns:
+**   connection object if successful
+**   nil and error message otherwise.
+*/
+static int env_connect (lua_State *L) {
+	char *dpb;
+	int i;
+	static char isc_tpb[] = {	isc_tpb_version3,
+								isc_tpb_write		};
+	conn_data conn;
+	conn_data* res_conn;
+
+	env_data *env = (env_data *) getenvironment (L, 1);
+	const char *sourcename = luaL_checkstring (L, 2);
+	const char *username = luaL_optstring (L, 3, "");
+	const char *password = luaL_optstring (L, 4, "");
+
+	conn.env = env;
+	conn.db = 0L;
+	conn.transaction = 0L;
+	conn.lock = 0;
+	conn.autocommit = 0;
+
+	/* Construct a database parameter buffer. */
+	dpb = conn.dpb_buffer;
+	*dpb++ = isc_dpb_version1;
+	*dpb++ = isc_dpb_num_buffers;
+	*dpb++ = 1;
+	*dpb++ = 90;
+
+	/* add the user name and password */
+	*dpb++ = isc_dpb_user_name;
+    *dpb++ = (char)strlen(username);
+	for(i=0; i<(int)strlen(username); i++)
+		*dpb++ = username[i];
+	*dpb++ = isc_dpb_password;
+    *dpb++ = (char)strlen(password);
+	for(i=0; i<(int)strlen(password); i++)
+		*dpb++ = password[i];
+
+	/* the length of the dpb */
+	conn.dpb_length = (short)(dpb - conn.dpb_buffer);
+
+	/* do the job */
+	isc_attach_database(env->status_vector, (short)strlen(sourcename), (char*)sourcename, &conn.db,
+						conn.dpb_length,	conn.dpb_buffer);
+
+	/* an error? */
+	if ( CHECK_DB_ERROR(conn.env->status_vector) )
+		return return_db_error(L, conn.env->status_vector);
+
+	/* open up the transaction handle */
+	isc_start_transaction(	env->status_vector, &conn.transaction, 1,
+							&conn.db, (unsigned short)sizeof(isc_tpb),
+							isc_tpb );
+
+	/* return NULL on error */
+	if ( CHECK_DB_ERROR(conn.env->status_vector) )
+		return return_db_error(L, conn.env->status_vector);
+
+	/* create the lua object and add the connection to the lock */
+	res_conn = (conn_data*)LUASQL_NEWUD(L, sizeof(conn_data));
+	luasql_setmeta (L, LUASQL_CONNECTION_FIREBIRD);
+	memcpy(res_conn, &conn, sizeof(conn_data));
+	res_conn->closed = 0;   /* connect now officially open */
+
+	/* register the connection */
+	lua_registerobj(L, 1, env);
+	++env->lock;
+
+	return 1;
+}
+
+/*
+** Closes an environment object
+** Lua Returns:
+**   1 if close was sucsessful, 0 if already closed
+**   nil and error message otherwise.
+*/
+static int env_close (lua_State *L) {
+	env_data *env = (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_FIREBIRD);
+	luaL_argcheck (L, env != NULL, 1, "environment expected");
+	
+	/* already closed? */
+	if(env->closed) {
+		lua_pushboolean(L, 0);
+		lua_pushstring(L, "env is already closed");
+		return 2;
+	}
+
+	/* check the lock */
+/*
+	if(env->lock > 0)
+		return luasql_faildirect(L, "there are still open connections");
+*/
+	if(env->lock > 0) {
+		lua_pushboolean(L, 0);
+		lua_pushstring(L, "there are open connections");
+		return 2;
+	}
+
+	/* unregister */
+	lua_unregisterobj(L, env);
+
+	/* mark as closed */
+	env->closed = 1;
+
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+/*
+** GCs an environment object
+*/
+static int env_gc (lua_State *L) {
+	/* nothing to be done for the FB environment */
+	return 0;
+}
+
+/*
+** Create metatables for each class of object.
+*/
+static void create_metatables (lua_State *L) {
+	struct luaL_Reg environment_methods[] = {
+		{"__gc", env_gc},
+		{"__close", env_gc},
+		{"close", env_close},
+		{"connect", env_connect},
+		{NULL, NULL},
+	};
+	struct luaL_Reg connection_methods[] = {
+		{"__gc", conn_gc},
+		{"__close", conn_gc},
+		{"close", conn_close},
+		{"execute", conn_execute},
+		{"commit", conn_commit},
+		{"rollback", conn_rollback},
+		{"setautocommit", conn_setautocommit},
+		{"escape", conn_escape},
+		{NULL, NULL},
+	};
+	struct luaL_Reg cursor_methods[] = {
+		{"__gc", cur_gc},
+		{"__close", cur_gc},
+		{"close", cur_close},
+		{"fetch", cur_fetch},
+		{"getcoltypes", cur_coltypes},
+		{"getcolnames", cur_colnames},
+		{NULL, NULL},
+	};
+	luasql_createmeta (L, LUASQL_ENVIRONMENT_FIREBIRD, environment_methods);
+	luasql_createmeta (L, LUASQL_CONNECTION_FIREBIRD, connection_methods);
+	luasql_createmeta (L, LUASQL_CURSOR_FIREBIRD, cursor_methods);
+	lua_pop (L, 3);
+}
+
+/*
+** Creates the metatables for the objects and registers the
+** driver open method.
+*/
+LUASQL_API int luaopen_luasql_firebird (lua_State *L) {
+	struct luaL_Reg driver[] = {
+		{"firebird", create_environment},
+		{NULL, NULL},
+	};
+	create_metatables (L);
+	lua_newtable (L);
+	luaL_setfuncs (L, driver, 0);
+	luasql_set_info (L);
+	return 1;
+} 
diff -pruN 2.6.0-3/src/ls_mysql.c 2.7.0-1/src/ls_mysql.c
--- 2.6.0-3/src/ls_mysql.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_mysql.c	2025-04-23 23:51:04.000000000 +0000
@@ -325,7 +325,8 @@ static int cur_close (lua_State *L) {
 	luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
 	if (cur->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Cursor is already closed");
+		return 2;
 	}
 	cur_nullify (L, cur);
 	lua_pushboolean (L, 1);
@@ -339,7 +340,7 @@ static int cur_close (lua_State *L) {
 ** a reference to it on the cursor structure.
 */
 static void _pushtable (lua_State *L, cur_data *cur, size_t off) {
-	int *ref = (int *)((char *)cur + off);
+	int *ref = (int *)cur + off / sizeof(int);
 
 	/* If colnames or coltypes do not exist, create both. */
 	if (*ref == LUA_NOREF)
@@ -393,7 +394,7 @@ static int cur_seek (lua_State *L) {
 ** Create a new Cursor object and push it on top of the stack.
 */
 static int create_cursor (lua_State *L, MYSQL *my_conn, int conn, MYSQL_RES *result, int cols) {
-	cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
+	cur_data *cur = (cur_data *)LUASQL_NEWUD(L, sizeof(cur_data));
 	luasql_setmeta (L, LUASQL_CURSOR_MYSQL);
 
 	/* fill in structure */
@@ -431,9 +432,13 @@ static int conn_close (lua_State *L) {
 	luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
 	if (conn->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Connection is already closed");
+		return 2;
 	}
-	conn_gc (L);
+	/* Nullify structure fields. */
+	conn->closed = 1;
+	luaL_unref (L, LUA_REGISTRYINDEX, conn->env);
+	mysql_close (conn->my_conn);
 	lua_pushboolean (L, 1);
 	return 1;
 }
@@ -559,7 +564,7 @@ static int conn_getlastautoid (lua_State
 ** Create a new Connection object and push it on top of the stack.
 */
 static int create_connection (lua_State *L, int env, MYSQL *const my_conn) {
-	conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
+	conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
 	luasql_setmeta (L, LUASQL_CONNECTION_MYSQL);
 
 	/* fill in structure */
@@ -609,8 +614,11 @@ static int env_connect (lua_State *L) {
 **
 */
 static int env_gc (lua_State *L) {
-	env_data *env= (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_MYSQL);	if (env != NULL && !(env->closed))
+	env_data *env= (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_MYSQL);
+	if (env != NULL && !(env->closed)) {
 		env->closed = 1;
+		mysql_library_end();
+	}
 	return 0;
 }
 
@@ -623,10 +631,11 @@ static int env_close (lua_State *L) {
 	luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
 	if (env->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring(L, "Environment is already closed");
+		return 2;
 	}
-	mysql_library_end();
 	env->closed = 1;
+	mysql_library_end();
 	lua_pushboolean (L, 1);
 	return 1;
 }
@@ -637,25 +646,28 @@ static int env_close (lua_State *L) {
 */
 static void create_metatables (lua_State *L) {
     struct luaL_Reg environment_methods[] = {
-        {"__gc", env_gc},
-        {"close", env_close},
-        {"connect", env_connect},
+		{"__gc", env_gc},
+		{"__close", env_gc},
+		{"close", env_close},
+		{"connect", env_connect},
 		{NULL, NULL},
 	};
     struct luaL_Reg connection_methods[] = {
-        {"__gc", conn_gc},
-        {"close", conn_close},
-        {"ping", conn_ping},
-        {"escape", escape_string},
-        {"execute", conn_execute},
-        {"commit", conn_commit},
-        {"rollback", conn_rollback},
-        {"setautocommit", conn_setautocommit},
+		{"__gc", conn_gc},
+		{"__close", conn_gc},
+		{"close", conn_close},
+		{"ping", conn_ping},
+		{"escape", escape_string},
+		{"execute", conn_execute},
+		{"commit", conn_commit},
+		{"rollback", conn_rollback},
+		{"setautocommit", conn_setautocommit},
 		{"getlastautoid", conn_getlastautoid},
 		{NULL, NULL},
     };
     struct luaL_Reg cursor_methods[] = {
         {"__gc", cur_gc},
+		{"__close", cur_gc},
         {"close", cur_close},
         {"getcolnames", cur_getcolnames},
         {"getcoltypes", cur_getcoltypes},
@@ -677,7 +689,7 @@ static void create_metatables (lua_State
 ** Creates an Environment and returns it.
 */
 static int create_environment (lua_State *L) {
-	env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
+	env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
 	luasql_setmeta (L, LUASQL_ENVIRONMENT_MYSQL);
 
 	/* fill in structure */
diff -pruN 2.6.0-3/src/ls_oci8.c 2.7.0-1/src/ls_oci8.c
--- 2.6.0-3/src/ls_oci8.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_oci8.c	2025-04-23 23:51:04.000000000 +0000
@@ -24,7 +24,6 @@
 #define LUASQL_CONNECTION_OCI8 "Oracle connection"
 #define LUASQL_CURSOR_OCI8 "Oracle cursor"
 
-
 typedef struct {
 	short         closed;
 	int           conn_counter;
@@ -269,7 +268,7 @@ static int free_column_buffers (lua_Stat
 			break;
 		default:
 			luaL_error (L, LUASQL_PREFIX"unknown type");
-			/*printf("free_buffers(): Unknow Type: %d count: %d\n",cols.item[count].type, count );*/
+			/*printf("free_buffers(): Unknown Type: %d count: %d\n",cols.item[count].type, count );*/
 			break;
 	}
     return 0;
@@ -400,7 +399,8 @@ static int cur_close (lua_State *L) {
 	luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
 	if (cur->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Cursor is already closed");
+		return 2;
 	}
 
 	/* Deallocate buffers. */
@@ -522,10 +522,14 @@ static int conn_close (lua_State *L) {
 	luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
 	if (conn->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Connection is already closed");
+		return 2;
+	}
+	if (conn->cur_counter > 0){
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "There are open cursors");
+		return 2;
 	}
-	if (conn->cur_counter > 0)
-		return luaL_error (L, LUASQL_PREFIX"there are open cursors");
 
 	/* Nullify structure fields. */
 	conn->closed = 1;
@@ -554,7 +558,7 @@ static int conn_close (lua_State *L) {
 static int create_cursor (lua_State *L, int o, conn_data *conn, OCIStmt *stmt, const char *text) {
 	int i;
 	env_data *env;
-	cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
+	cur_data *cur = (cur_data *)LUASQL_NEWUD(L, sizeof(cur_data));
 	luasql_setmeta (L, LUASQL_CURSOR_OCI8);
 
 	conn->cur_counter++;
@@ -726,7 +730,7 @@ static int env_connect (lua_State *L) {
 	size_t userlen = (username) ? strlen(username) : 0;
 	size_t passlen = (password) ? strlen(password) : 0;
 	/* Alloc connection object */
-	conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
+	conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
 
 	/* fill in structure */
 	luasql_setmeta (L, LUASQL_CONNECTION_OCI8);
@@ -770,13 +774,17 @@ static int env_close (lua_State *L) {
 	luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
 	if (env->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Environment is already closed");
+		return 2;
+	}
+	if (env->conn_counter > 0){
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "There are open connections");
+		return 2;
 	}
-	if (env->conn_counter > 0)
-		return luaL_error (L, LUASQL_PREFIX"there are open connections");
 
 	env->closed = 1;
-	/* desalocar: env->errhp e env->envhp */
+	/* release resources */
 	if (env->envhp)
 		OCIHandleFree ((dvoid *)env->envhp, OCI_HTYPE_ENV);
 	if (env->errhp)
@@ -790,7 +798,7 @@ static int env_close (lua_State *L) {
 ** Creates an Environment and returns it.
 */
 static int create_environment (lua_State *L) {
-	env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
+	env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
 	luasql_setmeta (L, LUASQL_ENVIRONMENT_OCI8);
 	/* fill in structure */
 	env->closed = 0;
@@ -819,12 +827,14 @@ static int create_environment (lua_State
 static void create_metatables (lua_State *L) {
 	struct luaL_Reg environment_methods[] = {
 		{"__gc", env_close}, /* Should this method be changed? */
+		{"__close", env_close},
 		{"close", env_close},
 		{"connect", env_connect},
 		{NULL, NULL},
 	};
 	struct luaL_Reg connection_methods[] = {
 		{"__gc", conn_close}, /* Should this method be changed? */
+		{"__close", conn_close},
 		{"close", conn_close},
 		{"execute", conn_execute},
 		{"commit", conn_commit},
@@ -834,6 +844,7 @@ static void create_metatables (lua_State
 	};
 	struct luaL_Reg cursor_methods[] = {
 		{"__gc", cur_close}, /* Should this method be changed? */
+		{"__close", cur_close},
 		{"close", cur_close},
 		{"getcolnames", cur_getcolnames},
 		{"getcoltypes", cur_getcoltypes},
diff -pruN 2.6.0-3/src/ls_odbc.c 2.7.0-1/src/ls_odbc.c
--- 2.6.0-3/src/ls_odbc.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_odbc.c	2025-04-23 23:51:04.000000000 +0000
@@ -16,7 +16,7 @@
 #include <sqlext.h>
 #elif defined(INFORMIX)
 #include "infxcli.h"
-#elif defined(UNIXODBC)
+#else
 #include "sql.h"
 #include "sqltypes.h"
 #include "sqlext.h"
@@ -32,11 +32,11 @@
 #define LUASQL_STATEMENT_ODBC "ODBC statement"
 #define LUASQL_CURSOR_ODBC "ODBC cursor"
 
-/* holds data for paramter binding */
+/* holds data for parameter binding */
 typedef struct {
 	SQLPOINTER buf;
-	SQLINTEGER len;
-	SQLINTEGER type;
+	SQLLEN len;
+	SQLLEN type;
 } param_data;
 
 /* general form of the driver objects */
@@ -66,7 +66,7 @@ typedef struct {
 	SQLHSTMT      hstmt;              /* statement handle */
 	SQLSMALLINT   numparams;          /* number of input parameters */
 	int           paramtypes;         /* reference to param type table */
-	param_data    *params;            /* array of parater data */
+	param_data    *params;            /* array of parameter data */
 } stmt_data;
 
 typedef struct {
@@ -297,6 +297,9 @@ static const char *sqltypetolua (const S
         case SQL_DATE: case SQL_INTERVAL: case SQL_TIMESTAMP: 
         case SQL_LONGVARCHAR:
         case SQL_WCHAR: case SQL_WVARCHAR: case SQL_WLONGVARCHAR:
+#if (ODBCVER >= 0x0350)
+		case SQL_GUID:
+#endif
             return "string";
         case SQL_BIGINT: case SQL_TINYINT: 
         case SQL_INTEGER: case SQL_SMALLINT: 
@@ -324,7 +327,7 @@ static const char *sqltypetolua (const S
 **   hstmt: statement handle
 **   i: column number
 ** Returns:
-**   0 if successfull, non-zero otherwise;
+**   0 if successful, non-zero otherwise;
 */
 static int push_column(lua_State *L, int coltypes, const SQLHSTMT hstmt, 
         SQLUSMALLINT i) {
@@ -500,7 +503,8 @@ static int cur_close (lua_State *L)
 
 	if (cur->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Cursor is already closed");
+		return 2;
 	}
 
 	if((res = cur_shut(L, cur)) != 0) {
@@ -574,7 +578,7 @@ static int create_cursor (lua_State *L,
 
 	lock_obj(L, stmt_i, stmt);
 
-	cur = (cur_data *) lua_newuserdata(L, sizeof(cur_data));
+	cur = (cur_data *) LUASQL_NEWUD(L, sizeof(cur_data));
 	luasql_setmeta (L, LUASQL_CURSOR_ODBC);
 
 	/* fill in structure */
@@ -635,10 +639,13 @@ static int conn_close (lua_State *L)
 	luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
 	if (conn->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Connection is already closed");
+		return 2;
 	}
 	if (conn->lock > 0) {
-		return luaL_error (L, LUASQL_PREFIX"there are open statements/cursors");
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "There are open cursors");
+		return 2;
 	}
 
 	/* Decrement connection counter on environment object */
@@ -685,7 +692,7 @@ static int raw_execute(lua_State *L, int
 		return create_cursor(L, -1, stmt, numcols);
 	} else {
 		/* if action has no results (e.g., UPDATE) */
-		SQLINTEGER numrows;
+		SQLLEN numrows;
 		if(error(SQLRowCount(stmt->hstmt, &numrows))) {
 			return fail(L, hSTMT, stmt->hstmt);
 		}
@@ -697,7 +704,7 @@ static int raw_execute(lua_State *L, int
 
 static int set_param(lua_State *L, stmt_data *stmt, int i, param_data *data)
 {
-	static SQLINTEGER cbNull = SQL_NULL_DATA;
+	static SQLLEN cbNull = SQL_NULL_DATA;
 
 	switch(lua_type(L, -1)) {
 	case LUA_TNIL: {
@@ -774,7 +781,6 @@ static int set_param(lua_State *L, stmt_
 */
 static int raw_readparams_table(lua_State *L, stmt_data *stmt, int iparams)
 {
-	static SQLINTEGER cbNull = SQL_NULL_DATA;
 	SQLSMALLINT i;
 	param_data *data;
 	int res = 0;
@@ -802,7 +808,6 @@ static int raw_readparams_table(lua_Stat
 */
 static int raw_readparams_args(lua_State *L, stmt_data *stmt, int arg, int ltop)
 {
-	static SQLINTEGER cbNull = SQL_NULL_DATA;
 	SQLSMALLINT i;
 	param_data *data;
 	int res = 0;
@@ -911,7 +916,7 @@ static int conn_prepare(lua_State *L)
 		return ret;
 	}
 
-	stmt = (stmt_data *)lua_newuserdata(L, sizeof(stmt_data));
+	stmt = (stmt_data *)LUASQL_NEWUD(L, sizeof(stmt_data));
 	memset(stmt, 0, sizeof(stmt_data));
 
 	stmt->closed = 0;
@@ -1036,7 +1041,7 @@ static int conn_setautocommit (lua_State
 */
 static int create_connection (lua_State *L, int o, env_data *env, SQLHDBC hdbc)
 {
-	conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
+	conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
 
 	/* set auto commit mode */
 	SQLRETURN ret = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
@@ -1065,7 +1070,7 @@ static int create_connection (lua_State
 **   source: data source
 **   user, pass: data source authentication information
 ** Lua Returns:
-**   connection object if successfull
+**   connection object if successful
 **   nil and error message otherwise.
 */
 static int env_connect (lua_State *L) {
@@ -1095,6 +1100,26 @@ static int env_connect (lua_State *L) {
 }
 
 /*
+** Environment object collector function
+*/
+static int env_gc (lua_State *L)
+{
+	SQLRETURN ret;
+	env_data *env = (env_data *)luaL_checkudata(L, 1, LUASQL_ENVIRONMENT_ODBC);
+	if (env != NULL && !(env->closed)) {
+		env->closed = 1;
+		ret = SQLFreeHandle (hENV, env->henv);
+		if (error (ret)) {
+			int ret2 = fail (L, hENV, env->henv);
+			env->henv = NULL;
+			return ret2;
+		}
+	}
+	return 0;
+}
+
+
+/*
 ** Closes an environment object
 */
 static int env_close (lua_State *L)
@@ -1104,18 +1129,21 @@ static int env_close (lua_State *L)
 	luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
 	if (env->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Environment is already closed");
+		return 2;
 	}
 	if (env->lock > 0) {
-		return luaL_error (L, LUASQL_PREFIX"there are open connections");
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "There are open connections");
+		return 2;
 	}
 
 	env->closed = 1;
 	ret = SQLFreeHandle (hENV, env->henv);
 	if (error(ret)) {
-		int ret = fail(L, hENV, env->henv);
+		int ret2 = fail(L, hENV, env->henv);
 		env->henv = NULL;
-		return ret;
+		return ret2;
 	}
 	return pass(L);
 }
@@ -1126,13 +1154,15 @@ static int env_close (lua_State *L)
 */
 static void create_metatables (lua_State *L) {
 	struct luaL_Reg environment_methods[] = {
-		{"__gc", env_close}, /* Should this method be changed? */
+		{"__gc", env_gc},
+		{"__close", env_gc},
 		{"close", env_close},
 		{"connect", env_connect},
 		{NULL, NULL},
 	};
 	struct luaL_Reg connection_methods[] = {
 		{"__gc", conn_close}, /* Should this method be changed? */
+		{"__close", conn_close},
 		{"close", conn_close},
 		{"prepare", conn_prepare},
 		{"execute", conn_execute},
@@ -1143,13 +1173,15 @@ static void create_metatables (lua_State
 	};
 	struct luaL_Reg statement_methods[] = {
 		{"__gc", stmt_close}, /* Should this method be changed? */
+		{"__close", stmt_close},
 		{"close", stmt_close},
 		{"execute", stmt_execute},
 		{"getparamtypes", stmt_paramtypes},
 		{NULL, NULL},
 	};
 	struct luaL_Reg cursor_methods[] = {
-		{"__gc", cur_close}, /* Should this method be changed? */
+		{"__gc", cur_gc}, /* Should this method be changed? */
+		{"__close", cur_gc},
 		{"close", cur_close},
 		{"fetch", cur_fetch},
 		{"getcoltypes", cur_coltypes},
@@ -1183,7 +1215,7 @@ static int create_environment (lua_State
 		return ret;
 	}
 
-	env = (env_data *)lua_newuserdata (L, sizeof (env_data));
+	env = (env_data *)LUASQL_NEWUD (L, sizeof (env_data));
 	luasql_setmeta (L, LUASQL_ENVIRONMENT_ODBC);
 	/* fill in structure */
 	env->closed = 0;
diff -pruN 2.6.0-3/src/ls_postgres.c 2.7.0-1/src/ls_postgres.c
--- 2.6.0-3/src/ls_postgres.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_postgres.c	2025-04-23 23:51:04.000000000 +0000
@@ -172,9 +172,10 @@ static int cur_close (lua_State *L) {
 	luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
 	if (cur->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "cursor is already closed");
+		return 2;
 	}
-	cur_nullify (L, cur); /* == cur_gc (L); */
+	cur_nullify (L, cur);
 	lua_pushboolean (L, 1);
 	return 1;
 }
@@ -248,7 +249,7 @@ static void create_coltypes (lua_State *
 ** a reference to it on the cursor structure.
 */
 static void _pushtable (lua_State *L, cur_data *cur, size_t off, creator func) {
-	int *ref = (int *)((char *)cur + off);
+	int *ref = (int *)cur + off / sizeof(int);
 	if (*ref != LUA_NOREF)
 		lua_rawgeti (L, LUA_REGISTRYINDEX, *ref);
 	else {
@@ -292,7 +293,7 @@ static int cur_numrows (lua_State *L) {
 ** Create a new Cursor object and push it on top of the stack.
 */
 static int create_cursor (lua_State *L, int conn, PGresult *result) {
-	cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
+	cur_data *cur = (cur_data *)LUASQL_NEWUD(L, sizeof(cur_data));
 	luasql_setmeta (L, LUASQL_CURSOR_PG);
 
 	/* fill in structure */
@@ -351,9 +352,13 @@ static int conn_close (lua_State *L) {
 	luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
 	if (conn->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring(L, "Connection is already closed");
+		return 2;
 	}
-	conn_gc (L);
+	conn->closed = 1;
+	luaL_unref (L, LUA_REGISTRYINDEX, conn->env);
+	PQfinish (conn->pg_conn);
+
 	lua_pushboolean (L, 1);
 	return 1;
 }
@@ -482,7 +487,7 @@ static int conn_setautocommit (lua_State
 ** Create a new Connection object and push it on top of the stack.
 */
 static int create_connection (lua_State *L, int env, PGconn *const pg_conn) {
-	conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
+	conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
 	luasql_setmeta (L, LUASQL_CONNECTION_PG);
 
 	/* fill in structure */
@@ -547,9 +552,10 @@ static int env_close (lua_State *L) {
 	luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
 	if (env->closed) {
 		lua_pushboolean (L, 0);
-		return 1;
+		lua_pushstring (L, "Environment is already closed");
+		return 2;
 	}
-	env_gc (L);
+	env->closed = 1;
 	lua_pushboolean (L, 1);
 	return 1;
 }
@@ -562,12 +568,14 @@ static int env_close (lua_State *L) {
 static void create_metatables (lua_State *L) {
 	struct luaL_Reg environment_methods[] = {
 		{"__gc",    env_gc},
+		{"__close", env_gc},
 		{"close",   env_close},
 		{"connect", env_connect},
 		{NULL, NULL},
 	};
 	struct luaL_Reg connection_methods[] = {
 		{"__gc",          conn_gc},
+		{"__close", 	  conn_gc},
 		{"close",         conn_close},
 		{"escape",        conn_escape},
 		{"execute",       conn_execute},
@@ -578,6 +586,7 @@ static void create_metatables (lua_State
 	};
 	struct luaL_Reg cursor_methods[] = {
 		{"__gc",        cur_gc},
+		{"__close", 	cur_gc},
 		{"close",       cur_close},
 		{"getcolnames", cur_getcolnames},
 		{"getcoltypes", cur_getcoltypes},
@@ -595,7 +604,7 @@ static void create_metatables (lua_State
 ** Creates an Environment and returns it.
 */
 static int create_environment (lua_State *L) {
-	env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
+	env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
 	luasql_setmeta (L, LUASQL_ENVIRONMENT_PG);
 
 	/* fill in structure */
diff -pruN 2.6.0-3/src/ls_sqlite.c 2.7.0-1/src/ls_sqlite.c
--- 2.6.0-3/src/ls_sqlite.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_sqlite.c	2025-04-23 23:51:04.000000000 +0000
@@ -98,7 +98,7 @@ static void cur_nullify(lua_State *L, cu
 
 /*
 ** Finalizes the vm
-** Return nil + errmsg or nil in case of sucess
+** Return nil + errmsg or nil in case of success
 */
 static int finalize(lua_State *L, cur_data *cur) {
 	char *errmsg;
@@ -196,8 +196,9 @@ static int cur_close(lua_State *L) {
 	cur_data *cur = (cur_data *)luaL_checkudata(L, 1, LUASQL_CURSOR_SQLITE);
 	luaL_argcheck(L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
 	if (cur->closed) {
-		lua_pushboolean(L, 0);
-		return 1;
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "cursor is already closed");
+		return 2;
 	}
 	sqlite_finalize(cur->sql_vm, NULL);
 	cur_nullify(L, cur);
@@ -235,7 +236,7 @@ static int create_cursor(lua_State *L, i
 		sqlite_vm *sql_vm, int numcols, const char **col_info)
 {
 	int i;
-	cur_data *cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data));
+	cur_data *cur = (cur_data*)LUASQL_NEWUD(L, sizeof(cur_data));
 	luasql_setmeta (L, LUASQL_CURSOR_SQLITE);
 
 	/* increment cursor count for the connection creating this cursor */
@@ -278,10 +279,7 @@ static int create_cursor(lua_State *L, i
 static int conn_gc(lua_State *L) {
 	conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
 	if (conn != NULL && !(conn->closed)) {
-		if (conn->cur_counter > 0) {
-			return luaL_error (L, LUASQL_PREFIX"there are open cursors");
-		}
-
+		
 		/* Nullify structure fields. */
 		conn->closed = 1;
 		luaL_unref(L, LUA_REGISTRYINDEX, conn->env);
@@ -294,15 +292,25 @@ static int conn_gc(lua_State *L) {
 /*
 ** Close a Connection object.
 */
-static int conn_close(lua_State *L) {
+static int conn_close (lua_State *L) {
 	conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
 	luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
 	if (conn->closed) {
-		lua_pushboolean(L, 0);
-		return 1;
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "Connection is already closed");
+		return 2;
 	}
-	conn_gc(L);
-	lua_pushboolean(L, 1);
+	
+	if (conn->cur_counter > 0) {
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "There are open cursors");
+		return 2;
+	}
+	conn->closed = 1;
+	luaL_unref (L, LUA_REGISTRYINDEX, conn->env);
+	sqlite_close (conn->sql_conn);
+	
+	lua_pushboolean (L, 1);
 	return 1;
 }
 
@@ -331,7 +339,7 @@ static int conn_execute(lua_State *L) {
 		return 2;
 	}
 
-	/* process first result to retrive query information and type */
+	/* process first result to retrieve query information and type */
 	res = sqlite_step(vm, &numcols, NULL, &col_info);
 
 	/* real query? if empty, must have numcols!=0 */
@@ -447,7 +455,7 @@ static int conn_setautocommit(lua_State
 ** Create a new Connection object and push it on top of the stack.
 */
 static int create_connection(lua_State *L, int env, sqlite *sql_conn) {
-	conn_data *conn = (conn_data*)lua_newuserdata(L, sizeof(conn_data));
+	conn_data *conn = (conn_data*)LUASQL_NEWUD(L, sizeof(conn_data));
 	luasql_setmeta(L, LUASQL_CONNECTION_SQLITE);
 
 	/* fill in structure */
@@ -503,10 +511,12 @@ static int env_close (lua_State *L) {
 	env_data *env = (env_data *)luaL_checkudata(L, 1, LUASQL_ENVIRONMENT_SQLITE);
 	luaL_argcheck(L, env != NULL, 1, LUASQL_PREFIX"environment expected");
 	if (env->closed) {
-		lua_pushboolean(L, 0);
-		return 1;
+		lua_pushboolean (L, 0);
+		lua_pushstring (L, "Environment is already closed");
+		return 2;
 	}
-	env_gc(L);
+	env->closed = 1;
+
 	lua_pushboolean(L, 1);
 	return 1;
 }
@@ -530,12 +540,14 @@ static int conn_escape(lua_State *L) {
 static void create_metatables (lua_State *L) {
 	struct luaL_Reg environment_methods[] = {
 		{"__gc", env_gc},
+		{"__close", env_gc},
 		{"close", env_close},
 		{"connect", env_connect},
 		{NULL, NULL},
 	};
 	struct luaL_Reg connection_methods[] = {
 		{"__gc", conn_gc},
+		{"__close", conn_gc},
 		{"close", conn_close},
 		{"escape", conn_escape},
 		{"execute", conn_execute},
@@ -546,6 +558,7 @@ static void create_metatables (lua_State
 	};
 	struct luaL_Reg cursor_methods[] = {
 		{"__gc", cur_gc},
+		{"__close", cur_gc},
 		{"close", cur_close},
 		{"getcolnames", cur_getcolnames},
 		{"getcoltypes", cur_getcoltypes},
@@ -562,7 +575,7 @@ static void create_metatables (lua_State
 ** Creates an Environment and returns it.
 */
 static int create_environment (lua_State *L) {
-	env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
+	env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
 	luasql_setmeta(L, LUASQL_ENVIRONMENT_SQLITE);
 
 	/* fill in structure */
diff -pruN 2.6.0-3/src/ls_sqlite3.c 2.7.0-1/src/ls_sqlite3.c
--- 2.6.0-3/src/ls_sqlite3.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/ls_sqlite3.c	2025-04-23 23:51:04.000000000 +0000
@@ -104,7 +104,7 @@ static void cur_nullify(lua_State *L, cu
 
 /*
 ** Finalizes the vm
-** Return nil + errmsg or nil in case of sucess
+** Return nil + errmsg or nil in case of success
 */
 static int finalize(lua_State *L, cur_data *cur) {
   const char *errmsg;
@@ -235,9 +235,12 @@ static int cur_close(lua_State *L)
   cur_data *cur = (cur_data *)luaL_checkudata(L, 1, LUASQL_CURSOR_SQLITE);
   luaL_argcheck(L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
   if (cur->closed) {
-    lua_pushboolean(L, 0);
-    return 1;
+    lua_pushboolean (L, 0);
+    lua_pushstring(L, "cursor is already closed");
+    return 2;
   }
+
+  cur->closed = 1;
   sqlite3_finalize(cur->sql_vm);
   cur_nullify(L, cur);
   lua_pushboolean(L, 1);
@@ -276,7 +279,7 @@ static int create_cursor(lua_State *L, i
 			 sqlite3_stmt *sql_vm, int numcols)
 {
   int i;
-  cur_data *cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data));
+  cur_data *cur = (cur_data*)LUASQL_NEWUD(L, sizeof(cur_data));
   luasql_setmeta (L, LUASQL_CURSOR_SQLITE);
 
   /* increment cursor count for the connection creating this cursor */
@@ -324,9 +327,6 @@ static int conn_gc(lua_State *L)
   conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
   if (conn != NULL && !(conn->closed))
     {
-      if (conn->cur_counter > 0)
-        return luaL_error (L, LUASQL_PREFIX"there are open cursors");
-
       /* Nullify structure fields. */
       conn->closed = 1;
       luaL_unref(L, LUA_REGISTRYINDEX, conn->env);
@@ -344,11 +344,21 @@ static int conn_close(lua_State *L)
   conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
   luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
   if (conn->closed)
-    {
-      lua_pushboolean(L, 0);
-      return 1;
-    }
-  conn_gc(L);
+  {
+    lua_pushboolean(L, 0);
+    lua_pushstring(L, "Connection is already closed");
+    return 2;
+  }
+  
+  if (conn->cur_counter > 0)
+  {
+    lua_pushboolean(L, 0);
+    lua_pushstring(L, "There are open cursors");
+    return 2;
+  }
+  
+  conn->closed = 1;
+  
   lua_pushboolean(L, 1);
   return 1;
 }
@@ -369,6 +379,109 @@ static int conn_escape(lua_State *L)
   return 1;
 }
 
+
+/*
+** Bind one parameter.
+** Supported are the data types nil, string, boolean, number.
+*/
+static int set_param(lua_State *L, sqlite3_stmt *vm, int param_nr, int arg)
+{
+  int tt = lua_type(L, arg);
+  int rc = 0;
+
+  switch (tt) {
+    case LUA_TNIL:
+    rc = sqlite3_bind_null(vm, param_nr);
+    break;
+
+    case LUA_TSTRING: {
+      size_t s_len;
+      const char *s = lua_tolstring(L, arg, &s_len);
+      rc = sqlite3_bind_null(vm, param_nr);
+      rc = sqlite3_bind_text(vm, param_nr, s, s_len, SQLITE_TRANSIENT);
+      break;
+    }
+
+    case LUA_TBOOLEAN: {
+      int val = lua_tointeger(L, arg);
+      rc = sqlite3_bind_int(vm, param_nr, val);
+      break;
+    }
+
+    case LUA_TNUMBER: {
+#if defined(lua_isinteger)
+      if (lua_isinteger(L, arg)) {
+        lua_Integer val = lua_tointeger(L, arg);
+        rc = sqlite3_bind_int64(vm, param_nr, val);
+      } else {
+#endif
+        double val = lua_tonumber(L, arg);
+        rc = sqlite3_bind_double(vm, param_nr, val);
+#if defined(lua_isinteger)
+      }
+#endif
+      break;
+    }
+
+    default:
+    luaL_error(L, LUASQL_PREFIX"unhandled data type %s in parameter binding",
+      lua_typename(L, tt));
+  }
+
+  return rc;
+}
+
+static int raw_readparams_args(lua_State *L, sqlite3_stmt *vm, int arg, int ltop)
+{
+  int param_count, param_nr, rc = 0;
+
+  param_count = sqlite3_bind_parameter_count(vm);
+  if (ltop - arg + 1 != param_count)
+    luaL_error(L, LUASQL_PREFIX"wrong number of parameters: expected=%d, given=%d",
+      param_count, ltop - arg + 1);
+
+  for (param_nr=1; param_nr <= param_count; param_nr ++, arg ++) {
+    rc = set_param(L, vm, param_nr, arg);
+    if (rc)
+      break;
+  }
+
+  return rc;
+}
+
+/*
+** Bind all parameters from the given table.
+** The table indices can be integers or strings.
+** Unbound parameters, or duplicate bindings are not detected.
+*/
+static int raw_readparams_table(lua_State *L, sqlite3_stmt *vm, int arg)
+{
+  int param_nr, rc = 0, tt;
+
+  lua_pushnil(L);
+
+  while (lua_next(L, arg)) {		// [arg]=table, [-2]=key, [-1]=val
+    tt = lua_type(L, -2);
+#if defined(lua_isinteger)
+    if (tt == LUA_TNUMBER && lua_isinteger(L, -2)) {
+      param_nr = lua_tointeger(L, -2);
+    } else {
+#endif
+      const char *param_name = lua_tostring(L, -2);
+      param_nr = sqlite3_bind_parameter_index(vm, param_name);
+      if (param_nr == 0)
+        luaL_error(L, LUASQL_PREFIX"binding to invalid parameter name %s\n",
+          param_name);
+#if defined(lua_isinteger)
+    }
+#endif
+    set_param(L, vm, param_nr, -1);
+    lua_pop(L, 1);
+  }
+
+  return rc;
+}
+
 /*
 ** Execute an SQL statement.
 ** Return a Cursor object if the statement is a query, otherwise
@@ -395,7 +508,21 @@ static int conn_execute(lua_State *L)
       return luasql_faildirect(L, errmsg);
     }
 
-  /* process first result to retrive query information and type */
+  /* Bind parameters (if any) */
+  int ltop = lua_gettop(L);
+  if (ltop > 2) {
+    if (ltop == 3 && lua_type(L, 3) == LUA_TTABLE) {
+      res = raw_readparams_table(L, vm, 3);
+    } else if (ltop >= 3) {
+      res = raw_readparams_args(L, vm, 3, ltop);
+    } else {
+      luaL_error(L, LUASQL_PREFIX"parameters are either one table or positional");
+    }
+    if (res)
+      return res;
+  }
+
+  /* process first result to retrieve query information and type */
   res = sqlite3_step(vm);
   numcols = sqlite3_column_count(vm);
 
@@ -522,7 +649,7 @@ static int conn_setautocommit(lua_State
 */
 static int create_connection(lua_State *L, int env, sqlite3 *sql_conn)
 {
-  conn_data *conn = (conn_data*)lua_newuserdata(L, sizeof(conn_data));
+  conn_data *conn = (conn_data*)LUASQL_NEWUD(L, sizeof(conn_data));
   luasql_setmeta(L, LUASQL_CONNECTION_SQLITE);
 
   /* fill in structure */
@@ -616,9 +743,12 @@ static int env_close (lua_State *L)
   luaL_argcheck(L, env != NULL, 1, LUASQL_PREFIX"environment expected");
   if (env->closed) {
     lua_pushboolean(L, 0);
-    return 1;
+    lua_pushstring(L, "env is already closed");
+		return 2;
   }
-  env_gc(L);
+  
+  env->closed = 1;
+
   lua_pushboolean(L, 1);
   return 1;
 }
@@ -642,14 +772,17 @@ static void create_metatables (lua_State
 {
   struct luaL_Reg environment_methods[] = {
     {"__gc", env_gc},
+    {"__close", env_gc},
     {"close", env_close},
     {"connect", env_connect},
     {NULL, NULL},
   };
   struct luaL_Reg connection_methods[] = {
     {"__gc", conn_gc},
+    {"__close", conn_gc},
     {"close", conn_close},
     {"escape", conn_escape},
+//    {"prepare", conn_prepare},
     {"execute", conn_execute},
     {"commit", conn_commit},
     {"rollback", conn_rollback},
@@ -659,6 +792,7 @@ static void create_metatables (lua_State
   };
   struct luaL_Reg cursor_methods[] = {
     {"__gc", cur_gc},
+    {"__close", cur_gc},
     {"close", cur_close},
     {"getcolnames", cur_getcolnames},
     {"getcoltypes", cur_getcoltypes},
@@ -676,7 +810,7 @@ static void create_metatables (lua_State
 */
 static int create_environment (lua_State *L)
 {
-  env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
+  env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
   luasql_setmeta(L, LUASQL_ENVIRONMENT_SQLITE);
 
   /* fill in structure */
diff -pruN 2.6.0-3/src/luasql.c 2.7.0-1/src/luasql.c
--- 2.6.0-3/src/luasql.c	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/luasql.c	2025-04-23 23:51:04.000000000 +0000
@@ -122,12 +122,12 @@ LUASQL_API void luasql_setmeta (lua_Stat
 */
 LUASQL_API void luasql_set_info (lua_State *L) {
 	lua_pushliteral (L, "_COPYRIGHT");
-	lua_pushliteral (L, "Copyright (C) 2003-2020 Kepler Project");
+	lua_pushliteral (L, "Copyright (C) 2003-2025 Kepler Project");
 	lua_settable (L, -3);
 	lua_pushliteral (L, "_DESCRIPTION");
 	lua_pushliteral (L, "LuaSQL is a simple interface from Lua to a DBMS");
 	lua_settable (L, -3);
 	lua_pushliteral (L, "_VERSION");
-	lua_pushliteral (L, "LuaSQL 2.6.0 (for "LUA_VERSION")");
+	lua_pushliteral (L, "LuaSQL 2.7.0 (for "LUA_VERSION")");
 	lua_settable (L, -3);
 }
diff -pruN 2.6.0-3/src/luasql.h 2.7.0-1/src/luasql.h
--- 2.6.0-3/src/luasql.h	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/src/luasql.h	2025-04-23 23:51:04.000000000 +0000
@@ -24,6 +24,13 @@
 #define LUASQL_CONNECTION "Each driver must have a connection metatable"
 #define LUASQL_CURSOR "Each driver must have a cursor metatable"
 
+// Macro to handle userdata creation across Lua versions
+#if LUA_VERSION_NUM >= 504                        
+#define LUASQL_NEWUD(L, size) lua_newuserdatauv(L, size, 0)
+#else
+#define LUASQL_NEWUD(L, size) lua_newuserdata(L, size)
+#endif
+
 LUASQL_API int luasql_faildirect (lua_State *L, const char *err);
 LUASQL_API int luasql_failmsg (lua_State *L, const char *err, const char *m);
 LUASQL_API int luasql_createmeta (lua_State *L, const char *name, const luaL_Reg *methods);
diff -pruN 2.6.0-3/tests/firebird.lua 2.7.0-1/tests/firebird.lua
--- 2.6.0-3/tests/firebird.lua	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/tests/firebird.lua	2025-04-23 23:51:04.000000000 +0000
@@ -11,7 +11,7 @@ local orig_create_table = create_table
 local orig_drop_table = drop_table
 
 ---------------------------------------------------------------------
--- New metadata needs to be commited before it is used
+-- New metadata needs to be committed before it is used
 ---------------------------------------------------------------------
 function create_table ()
 	orig_create_table()
@@ -20,7 +20,7 @@ end
 
 function drop_table ()
 	-- Firebird prefers to keep DDL stuff (CREATE TABLE, etc.) 
-	-- seperate. So we need a new transaction i.e. connection
+	-- separate. So we need a new transaction i.e. connection
 	-- to work in
 	assert(CONN:close ())
 	CONN = assert(ENV:connect (datasource, username, password))
diff -pruN 2.6.0-3/tests/mysql.lua 2.7.0-1/tests/mysql.lua
--- 2.6.0-3/tests/mysql.lua	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/tests/mysql.lua	2025-04-23 23:51:04.000000000 +0000
@@ -2,7 +2,7 @@
 -- MySQL specific tests and configurations.
 ---------------------------------------------------------------------
 
-QUERYING_STRING_TYPE_NAME = "binary(65535)"
+QUERYING_STRING_TYPE_NAME = "binary(262140)"
 
 ---------------------------------------------------------------------
 -- Seeks to an arbitrary row in a query result set.
@@ -21,6 +21,8 @@ function seek ()
     assert2('c', cur:fetch())
     assert2(nil, cur:fetch())
     cur:close()
+	-- Delete inserted rows
+	assert2 (3, CONN:execute"delete from t", "Couldn't delete inserted rows!")
 
 	io.write (" seek")
 end
diff -pruN 2.6.0-3/tests/odbc.lua 2.7.0-1/tests/odbc.lua
--- 2.6.0-3/tests/odbc.lua	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/tests/odbc.lua	2025-04-23 23:51:04.000000000 +0000
@@ -4,7 +4,7 @@
 
 QUERYING_STRING_TYPE_NAME = "string"
 -- The CREATE_TABLE_RETURN_VALUE and DROP_TABLE_RETURN_VALUE works
--- with -1 on MS Acess Driver, and 0 on SQL Server Driver
+-- with -1 on MS Access Driver, and 0 on SQL Server Driver
 CREATE_TABLE_RETURN_VALUE = -1
 DROP_TABLE_RETURN_VALUE = -1
 
diff -pruN 2.6.0-3/tests/test.lua 2.7.0-1/tests/test.lua
--- 2.6.0-3/tests/test.lua	2020-09-09 15:28:53.000000000 +0000
+++ 2.7.0-1/tests/test.lua	2025-04-23 23:51:04.000000000 +0000
@@ -130,6 +130,7 @@ function basic_test ()
 	assert2 (false, ENV:close())
 	-- Reopen the environment.
 	ENV = ENV_OK (luasql[driver] ())
+
 	-- Check connection object.
 	local conn, err = ENV:connect (datasource, username, password)
 	assert (conn, (err or '').." ("..datasource..")")
@@ -172,6 +173,7 @@ end
 function create_table ()
 	-- Check SQL statements.
 	CONN = CONN_OK (ENV:connect (datasource, username, password))
+	CONN:execute"drop table t"
 	-- Create t.
 	local cmd = define_table(TOTAL_FIELDS)
 	assert2 (CREATE_TABLE_RETURN_VALUE, CONN:execute (cmd))
@@ -181,6 +183,9 @@ end
 -- Fetch 2 values.
 ---------------------------------------------------------------------
 function fetch2 ()
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 	-- insert a record.
 	assert2 (1, CONN:execute ("insert into t (f1, f2) values ('b', 'c')"))
 	-- retrieve data.
@@ -209,6 +214,9 @@ function fetch2 ()
 	assert2 (false, cur:close())
 	-- remove records.
 	assert2 (2, CONN:execute ("delete from t where f1 in ('b', 'd')"))
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 end
 
 ---------------------------------------------------------------------
@@ -216,6 +224,9 @@ end
 -- indexing.
 ---------------------------------------------------------------------
 function fetch_new_table ()
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 	-- insert elements.
 	assert2 (1, CONN:execute ("insert into t (f1, f2, f3, f4) values ('a', 'b', 'c', 'd')"))
 	assert2 (1, CONN:execute ("insert into t (f1, f2, f3, f4) values ('f', 'g', 'h', 'i')"))
@@ -232,7 +243,7 @@ function fetch_new_table ()
 	assert2 (nil, row.f3)
 	assert2 (nil, row.f4)
 	row, err = cur:fetch(fetch_table())
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 ('f', row[1])
 	assert2 ('g', row[2])
 	assert2 ('h', row[3])
@@ -249,7 +260,7 @@ function fetch_new_table ()
 	io.write ("reusing a table...")
 	cur = CUR_OK (CONN:execute ("select f1, f2, f3, f4 from t order by f1"))
 	local row, err = cur:fetch(fetch_table())
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 ('a', row[1])
 	assert2 ('b', row[2])
 	assert2 ('c', row[3])
@@ -259,7 +270,7 @@ function fetch_new_table ()
 	assert2 (nil, row.f3)
 	assert2 (nil, row.f4)
 	row, err = cur:fetch (row)
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 ('f', row[1])
 	assert2 ('g', row[2])
 	assert2 ('h', row[3])
@@ -276,7 +287,7 @@ function fetch_new_table ()
 	io.write ("with alpha keys...")
 	cur = CUR_OK (CONN:execute ("select f1, f2, f3, f4 from t order by f1"))
 	local row, err = cur:fetch (fetch_table(), "a")
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 (nil, row[1])
 	assert2 (nil, row[2])
 	assert2 (nil, row[3])
@@ -303,7 +314,7 @@ function fetch_new_table ()
 	io.write ("with both keys...")
 	cur = CUR_OK (CONN:execute ("select f1, f2, f3, f4 from t order by f1"))
 	local row, err = cur:fetch (fetch_table(), "an")
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 ('a', row[1])
 	assert2 ('b', row[2])
 	assert2 ('c', row[3])
@@ -313,7 +324,7 @@ function fetch_new_table ()
 	assert2 ('c', row.f3)
 	assert2 ('d', row.f4)
 	row, err = cur:fetch (row, "an")
-	assert (type(row), "table", err)
+	assert2 (type(row), "table", err)
 	assert2 ('f', row[1])
 	assert2 ('g', row[2])
 	assert2 ('h', row[3])
@@ -327,12 +338,18 @@ function fetch_new_table ()
 	assert2 (false, cur:close())
 	-- clean the table.
 	assert2 (2, CONN:execute ("delete from t where f1 in ('a', 'f')"))
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 end
 
 ---------------------------------------------------------------------
 -- Fetch many values
 ---------------------------------------------------------------------
 function fetch_many ()
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 	-- insert values.
 	local fields, values = "f1", "'v1'"
 	for i = 2, TOTAL_FIELDS do
@@ -395,11 +412,17 @@ function fetch_many ()
 	assert2 (false, cur:close(), MSG_CURSOR_NOT_CLOSED)
 	-- clean the table.
 	assert2 (1, CONN:execute ("delete from t where f1 = 'v1'"))
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 end
 
 ---------------------------------------------------------------------
 ---------------------------------------------------------------------
 function rollback ()
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 	-- begin transaction
 	assert2 (true, CONN:setautocommit (false), "couldn't disable autocommit")
 	-- insert a record and commit the operation.
@@ -476,7 +499,8 @@ function column_info ()
 	for i = 1, table.getn(names) do
 		assert2 ("f"..i, string.lower(names[i]), "incorrect column names table")
 		local type_i = types[i]
-		assert (type_i == QUERYING_STRING_TYPE_NAME, "incorrect column types table")
+		type_i = string.lower(type_i)
+		assert2 (QUERYING_STRING_TYPE_NAME, type_i, "incorrect column types table")
 	end
 	-- check if the tables are being reused.
 	local n2, t2 = cur:getcolnames(), cur:getcoltypes()
@@ -504,16 +528,20 @@ function escape ()
 	local s1 = string.rep("'", n)
 	local s2 = CONN:escape(s1)
 	local s3 = s1:gsub ("'", "\\'")
-	assert (s1:len() == n)
-	assert (s2:len() == 2*n)
+	assert2 (n, s1:len(), "incorrect escaping of '"..s1.."': expected "..n.." bytes, but got "..s1:len())
+	assert2 (2*n, s2:len(), "incerrect escaping of '"..s2.."': expected "..(2*n).." bytes, but got "..s2:len())
 	assert (s2 == s1..s1 or s2 == s3)
 
 	io.write (" escape")
 end
 
 ---------------------------------------------------------------------
+-- Check closing of various objects.
 ---------------------------------------------------------------------
 function check_close()
+	local cur0 = CUR_OK(CONN:execute"select count(*) from t")
+	assert2 (0, tonumber(cur0:fetch()))
+	cur0:close()
 	-- an object with references to it can't be closed
 	local cmd = "select * from t"
 	local cur = CUR_OK(CONN:execute (cmd))
@@ -537,20 +565,68 @@ function check_close()
 	collectgarbage ()
 	assert2(nil, a.CONN, "connection not collected")
 
-	-- check cursor integrity after trying to close a connection
+	-- check cursor integrity after trying to close its connection
 	local conn = CONN_OK (ENV:connect (datasource, username, password))
 	assert2 (1, conn:execute"insert into t (f1) values (1)", "could not insert a new record")
 	local cur = CUR_OK (conn:execute (cmd))
-	local ok, err = pcall (conn.close, conn)
+	local ok, err, msg = pcall (conn.close, conn)
+	assert2 (true, ok, "couldn´t try to close the connection")
+	-- err could be true if the driver DOESN'T care about closing a connection
+	--	that has open cursors
+	-- err could be false if the driver DOES care about closing a connection
+	--	that has open cursors
 	CUR_OK (cur)
 	assert (cur:fetch(), "corrupted cursor")
 	cur:close ()
 	conn:close ()
+	-- The following check is failing in Firebird
+    --local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+    --assert2 (1, tonumber (cur0:fetch()))
+	--cur0:close()
+
+	-- check connection integrity after trying to close an environment
+	local conn = CONN_OK (ENV:connect (datasource, username, password))
+	local closed = ENV:close()
+	--assert2 (true, ENV:close(), "couldn't close the environment!")
+	if closed then
+		-- Some drivers can close the environment with open connections
+		CONN_OK (conn)
+		local cmd = "select * from t"
+		local cur = CUR_OK(CONN:execute (cmd))
+		assert2 ('1', cur:fetch(), "couldn't retrieve a row from `t`")
+		assert2 (true, cur:close(), "couldn't close the cursor!")
+    local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+    assert2 (1, tonumber (cur0:fetch()))
+	cur0:close()
+
+		assert2 (true, conn:close(), "couldn't close the connection!")
+		ENV = ENV_OK (luasql[driver] ())
+	else
+		-- Some drivers cannot close the environment with open connections
+		conn:close()
+		ENV:close()
+	end
+end
+
+---------------------------------------------------------------------
+-- Check support for to-be-closed variables.
+-- Since this feature depends on a syntax construction not available
+-- in versions prior to 5.4, this check should be written in another
+-- file (or in a string).
+---------------------------------------------------------------------
+function to_be_closed_support ()
+	assert (loadfile"to_be_closed_support.lua")()
 end
 
 ---------------------------------------------------------------------
 ---------------------------------------------------------------------
 function drop_table ()
+	-- check number of lines
+	-- The following check is failing with Firebird
+	--local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	--assert2 (1, tonumber (cur0:fetch()))
+	--assert2 (true, cur0:close(), "couldn't close the cursor")
+
 	assert2 (true, CONN:setautocommit(true), "couldn't enable autocommit")
 	-- Postgres retorns 0, ODBC retorns -1, sqlite returns 1
 	assert2 (DROP_TABLE_RETURN_VALUE, CONN:execute ("drop table t"))
@@ -559,8 +635,8 @@ end
 ---------------------------------------------------------------------
 ---------------------------------------------------------------------
 function close_conn ()
-	assert (true, CONN:close())
-	assert (true, ENV:close())
+	assert2 (true, CONN:close())
+	assert2 (true, ENV:close())
 end
 
 ---------------------------------------------------------------------
@@ -575,9 +651,17 @@ end
 EXTENSIONS = {
 }
 function extensions_test ()
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
+
 	for i, f in ipairs (EXTENSIONS) do
 		f ()
 	end
+
+	-- check number of lines
+	local cur0 = CUR_OK (CONN:execute ("select count(*) from t"))
+	assert2 (0, tonumber (cur0:fetch()))
 end
 
 ---------------------------------------------------------------------
@@ -663,6 +747,7 @@ tests = {
 	{ "get column information", column_info },
 	{ "extensions", extensions_test },
 	{ "close objects", check_close },
+-- to-be-closed variables could be inserted here
 	{ "drop table", drop_table },
 	{ "close connection", close_conn },
 	{ "finalization", finalization },
@@ -677,6 +762,9 @@ if string.find(_VERSION, " 5.0") then
 	end
 else
 	luasql = require ("luasql."..driver)
+	if string.find(_VERSION, " 5.4") then
+		table.insert (tests, 10, { "to-be-closed support", to_be_closed_support })
+	end
 end
 assert (luasql, "Could not load driver: no luasql table.")
 io.write (luasql._VERSION.." "..driver)
diff -pruN 2.6.0-3/tests/to_be_closed_support.lua 2.7.0-1/tests/to_be_closed_support.lua
--- 2.6.0-3/tests/to_be_closed_support.lua	1970-01-01 00:00:00.000000000 +0000
+++ 2.7.0-1/tests/to_be_closed_support.lua	2025-04-23 23:51:04.000000000 +0000
@@ -0,0 +1,14 @@
+---------------------------------------------------------------------
+-- Lua 5.4 support to to-be-closed variables.
+---------------------------------------------------------------------
+
+assert(CONN, "Unable to access CONN variable with a connection object!")
+
+local cursor <close> = CONN:execute("select * from t")
+CUR_OK (cursor)
+
+local connection <close> = ENV:connect (datasource, username, password)
+CONN_OK (connection)
+
+local environment <close> = luasql[driver] () 
+ENV_OK (environment)
\ No newline at end of file
