LuaSQL: Conectividade de banco de dados para a linguagem de programação Lua

LuaSQL
Conectividade de banco de dados para a linguagem de programação Lua

## Introdução

LuaSQL é uma interface simples entre Lua e diversos sistemas gerenciadores de bancos de dados (DBMS) populares (atualmente PostgreSQL, ODBC, JDBC, MySQL, SQLite, Oracle e ADO; Interbase e Sybase estão nos nossos planos). LuaSQL define uma API orientada a objetos. Todos os drivers devem implementar essa API comum, mas cada um é livre para oferecer extensões.

LuaSQL define uma única variável global: uma tabela chamada `luasql`. Essa tabela é usada para armazenar os métodos de inicialização dos drivers instalados. Esses métodos são usados para criar um ambiente, o qual é usado para criar uma conexão. A conexão pode executar comandos SQL e, eventualmente, criar um cursor, utilizado para recuperar dados.

LuaSQL é um software livre e usa a mesma licença do Lua 5.0.

## Compilando

LuaSQL é distribuído como um conjunto de arquivos fonte C – um arquivo fonte e um arquivo cabeçalho comuns a todos os drivers (`luasql.h` e `luasql.c`) – e um arquivo fonte para cada driver. Cada driver deve ser compilado juntamente com o arquivo `luasql.c` para gerar uma biblioteca. Essa biblioteca pode ser linkada à aplicação ou carregada dinamicamente. A função de inicialização é `luaopen_luasqlnomedriver` e é compatível com o formato `open-library` de Lua.

## Instalação

Todos os drivers LuaSQL seguem a proposta de pacotes para Lua 5.1. Logo, esse pacote deve ser "instalado". Consulte a seção de configuração do Compat-5.1 para saber como instalar os pacotes binários da maneira correta. As bibliotecas compiladas devem ser instaladas em um diretório chamado `luasql` no seu LUA_CPATH.

Para usar LuaSQL com o JDBC, certifique-se que:

- Lua está rodando com LuaJava
- O jar do LuaSQL está na classpath da máquina virtual do Java
- O driver JDBC do banco de dados desejado também está na classpath da máquina virtual

Para usar LuaSQL com ADO, certifique-se que Lua está rodando com LuaCOM 1.3

## Tratamento de erros

LuaSQL é apenas uma camada abstrata de comunicação entre Lua e um sistema de banco de dados. Portanto, erros podem ocorrem em ambos os níveis: no cliente do banco de dados ou no driver LuaSQL.

Erros como comandos SQL mal formados, nomes de tabela desconhecidos etc., chamados erros de banco de dados, serão reportados pelo retorno de `nil` pela função/método, seguido de uma mensagem de erro enviada pelo sistema de banco de dados. Erros como parâmetros inválidos, ausência de conexão, objetos inválidos etc., chamados erros de API, são usualmente erros de programação e geram erros Lua.

Esse comportamento vale para todas as funções/métodos descritos neste documento, a menos que seja especificado de outra forma.

## Drivers

Um driver LuaSQL permite o uso da API LuaSQL com um determinado banco de dados. Para usar um driver, este deve ser carregado na tabela `luasql`. O exemplo abaixo

    require "luasql.odbc"

carrega o driver ODBC na tabela `luasql`. Note que pode-se ter mais de um driver carregado usando-se algo como:

    require "luasql.odbc"
    require "luasql.oci8"

Este exemplo também mostra que o nome do driver nem sempre corresponde ao nome do banco de dados, mas sim ao nome do driver no sistema de arquivos. Dado que o driver Oracle se refere à API OCI8, ele recebe o nome de `oci8` ao invés de `oracle`.

Alguns drivers, tais como o MySQL, tem bibliotecas para versões diferentes do banco de dados MySQL mas utilizam o mesmo nome de arquivo (`mysql`). Neste caso não é possível carregar mais de uma versão do driver MySQL na tabela `luasql`.

## Ambiente

Um ambiente é criado chamando a função de inicialização do driver que está armazenada na tabela `luasql` com o mesmo nome do driver (odbc, postgres etc). Por exemplo,

    env = luasql.odbc()

tentará criar um ambiente usando o driver ODBC. A única exceção é o driver JDBC, que precisa saber que driver interno utilizar. Logo, quando se cria um ambiente, deve-se passar o nome da classe do driver como primeiro parâmetro para a função `luasql.jdbc`. Por exemplo:

    env = luasql.jdbc ("com.mysql.jdbc.Driver")

#### Métodos

`env:close()`
  Fecha o ambiente `env`. Só é bem sucedido se todas as suas conexões já tiverem sido fechadas anteriormente.
  Retorna: `true`, em caso de sucesso; `false`, quando o ambiente já estiver fechado.
`env:connect(sourcename[,username[,password]])`
  Conecta à fonte de dados especificada em `sourcename` usando `username` e `password` se eles são fornecidos.
  O `sourcename` pode variar de acordo com cada driver. Alguns usam simplesmente o nome do banco de dados, como PostgreSQL, MySQL e SQLite; o driver ODBC recebe o nome de DSN; o driver Oracle recebe o nome do serviço; e o driver JDBC recebe um comando como `"jdbc:<database system>://<database name>"`, o qual é específico para cada driver.
  Veja também: PostgreSQL e MySQL.
  Retorna: uma conexão.

## Conexão

Uma conexão contém atributos e parâmetros específicos de uma única conexão de base de dados. Uma conexão é criada chamando o método `environment:connect`.

#### Métodos

`conn:close()`
  Fecha a conexão `conn`. Só é bem sucedido se todos os seus cursores tiverem sido fechados anteriormente e se a conexão ainda estiver aberta.
  Retorna: `true`, em caso de sucesso; `false` em caso de fracasso.
`conn:commit()`
  Efetua a transação corrente. Esse atributo pode não funcionar em sistemas de banco de dados que não implementam transações.
  Retorna: `true`, em caso de sucesso; `false`, quando a operação não pode ser realizada ou não está implementada.
`conn:execute(statement)`
  Executa o `statement` SQL dado.
  Retorna: o cursor, se houver resultados, ou o número de registros alterados pelo comando.
`conn:rollback()`
  Desfaz a transação corrente. Esse atributo pode não funcionar em sistemas de banco de dados que não implementam transações.
  Retorna: `true`, em caso de sucesso; `false`, quando a operação não pode ser realizada ou não está implementada.
`conn:setautocommit(boolean)`
  Ativa ou desativa o modo "auto commit". Esse atributo pode não funcionar em sistemas de banco de dados que não implementam transações. Em sistemas de banco de dados que não trabalham com o conceito de "modo auto commit", mas que implementam transações, esse mecanismo é implementado pelo driver.
  Retorna: `true`, em caso de sucesso; `false`, quando a operação não pode ser realizada ou não está implementada.

## Cursores

Um cursor contém métodos para recuperar dados resultantes de um comando executado. Um cursor é criado por meio de uma função `connection:execute`. Veja também: PostgreSQL e Oracle.

#### Métodos

`cur:close()`
  Fecha esse cursor.
  Retorna: `true`, em caso de sucesso; `false`, quando o cursor já está fechado.
`cur:fetch([table[,modestring]])`
  Recupera o próximo registro do resultado.
  Se `fetch` é chamado sem parâmetros, os resultados consistem em uma lista de valores. Se `fetch` é chamado com uma tabela, os resultados são copiados para a tabela e a tabela é retornada. Neste caso, pode ser usado um parâmetro opcional de modo (`modestring`): uma seqüência de caracteres indicando como deve ser construída a tabela de resultados. A seqüência de caracteres do modo pode conter:
  "n"
    a tabela resultante terá índices numéricos (padrão)
  "a"
    a tabela resultante terá índices alfanuméricos
  Os índices numéricos representam as posições dos campos no comando SELECT; os índices alfanuméricos representam os nomes dos campos.
  A tabela opcional (`table`) será usada para armazenar o próximo registro. Isso permite o uso de uma única tabela para várias chamadas, o que pode melhorar o desempenho geral.
  Não existe garantia sobre os tipos dos resultados: eles podem ou não ser convertidos pelo driver para os tipos Lua adequados. Na implementação atual, os drivers PostgreSQL e MySQL retornam todos os valores como strings, enquanto os drivers ODBC e Oracle convertem esses valores em tipos Lua.
  Retorna: dados, como descrito acima, ou `nil` se não existem mais registros. Note que esse método pode retornar `nil` como um resultado válido.
`cur:getcolnames()`
  Retorna: uma tabela com os nomes das colunas.
`cur:getcoltypes()`
  Retorna: uma tabela com os tipos das colunas.

## PostgreSQL

Além das funcionalidades básicas oferecidas por todos os drivers, o driver Postgres oferece as seguintes funcionalidades adicionais:

`env:connect(sourcename[,username[,password[,hostname[,port]]]])`
  No driver PostgreSQL este método tem mais dois parâmetros opcionais que indicam o `hostname` e a `port` a serem utilizados na conexão. Além disso, o primeiro parâmetro também pode conter todas as informações de conexão, como é dito na documentação para a função `PQconnectdb` no manual do PostgreSQL (ex. `environment:connect("dbname=<name> user=<username>")`)
  Veja também: ambiente
  Retorna: uma conexão
`cur:numrows()`
  Veja também: cursores
  Retorna: o número de registros no resultado da busca.

## MySQL

Além das funcionalidades básicas oferecidas por todos os drivers, o driver MySQL ainda oferece as seguintes funcionalidades adicionais:

`env:connect(sourcename[,username[,password[,hostname[,port]]]])`
  No driver MySQL, esse método tem mais dois parâmetros opcionais que indicam o `hostname` e a `port` a serem utilizados na conexão. Veja também: ambiente
  Retorna: uma conexão
`cur:numrows()`
  Veja também: cursores
  Retorna: o número de registros no resultado da busca.

Nota: Este driver é compatível com as versões 4.0, 4.1 e 5.0 da API MySQL. Apenas as versões a partir de 4.1 oferecem suporte para transações, através de tabelas BDB ou INNODB. Com a versão 4.0 ou sem um desses tipos de tabelas, os métodos `commit`, `rollback` e `setautocommit` não funcionam.

## Oracle

Além das funcionalidades básicas oferecidas por todos os drivers, o driver Oracle ainda oferece uma funcionalidade adicional:

`cur:numrows()`
  Veja também: cursores
  Retorna: o número de registros no resultado da pesquisa.

## SQLite3

Além das funcionalidades básicas oferecidas por todos os drivers, o driver para SQLite3 ainda oferece uma funcionalidade adicional:

`env:connect(sourcename[,locktimeout])`
  No driver para SQLite3, este método tem mais um parâmetro opcional que indica a quantidade de milissegundos para esperar por uma trava de escrita no banco de dados, se ela não for obtida de imediato.
  Veja também: ambiente
  Retorna: uma conexão

$Id: manual.html,v 1.11 2008/06/11 00:26:13 jasonsantos Exp $