== Classe == A classe que é utilizada nos processos de Workflow para fazer conexão com o banco de dados é a wf_db. Esta classe faz uso do [http://adodb.sourceforge.net ADOdb] como camada de abstração de banco de dados. A documentação da classe pode ser vista neste [http://doc.workflow.celepar.parana/api/Workflow/local/wf_db.html link] Os métodos básicos da classe são: * ''connect'' - conecta-se ao banco de dados (por padrão, conecta-se ao banco de dados onde da base de dados do processo de Workflow); * ''disconnect'' - desconecta-se do banco de dados; * ''query'' - executa um comando SQL no banco de dados. == Objeto == Oobjetodaclassewf_dbjávemcriadoporpadrãonodesenvolvimentoutilizandooMVCproposto-[wiki:WF/MetodologiadeDesenvolvimento] . Ele pode ser acessado em qualquer classe model através do atributo {{$this->model}} == Bind == A versão atual do ADOdb utilizada permite a utilização de bind para a execução de queries. A idéia do bind é aproveitar o mesmo plano de execução para as mesmas ações. Na utilização do bind os valores (inseridos, atualizados ou de consulta) são separados da query. Exemplo de utilização de bind: {{{ /* SEM BIND */ $this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(1, 'João')"); //plano de execução 1 $this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(2, 'Maria')"); //plano de execução 2 /* COM BIND */ $this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(1, 'João')); //plano de execução 3 $this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(2, 'Maria')); //plano de execução 3 }}} Repare que utilizando o bind, o plano de execução para as queries é o mesmo pois, a única coisa que muda são dos dados, a query é a mesma. Já sem a utilização de bind, as queries são diferentes, uma vez que os dados fazem parte da query, gerando diferentes queries para diferentes dados. Outras vantagens de se utilizar o bind sobre o método "tradicional" são: * O parser do banco de dados não precisa analisar queries que podem ser de grande tamanho devido aos dados que estão sendo inseridos (e.g. inserção de arquivos em banco, neste caso a query terá praticamente o tamanho do arquivo inserido); * Proteção prática e robusta contra [http://en.wikipedia.org/wiki/SQL_injection SQL Injection]. Como pode ser visto no exemplo, ao invés de se inserir os valores na query, utiliza-se {{?}} para cada valor e, depois os valores são passados em uma {{array}} como segundo parâmetro do método query. Os itens da array seguem a ordem das {{?}} utilizadas. == Utilização == Antes de utilizar o objeto para acesso ao Banco de Dados, é necessário conectá-lo ao banco. Para isto, basta chamar o método {{connect}}. Caso o banco que se quer conectar é o banco do próprio processo, não é necessário passar parâmetros, sendo a chamada realizada da seguinte maneira: {{{ $this->DAO->connect(); }}} Em todos os exemplos vamos considerar que a conexão com o Banco de Dados já foi feita. === SELECT === {{{ /* Exemplo 01 */ $resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario'); $data = array(); while ($row = $resultSet->fetchRow()) $data[] = $row; /* a variável $data será uma array com os valores selecionados */ echo $data[0]['nome']; //exemplo de acesso aos dados (nome do primeiro registro retornado) /* Exemplo 02 */ $resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario WHERE (nome = ?)', array('José')); $data = array(); while ($row = $resultSet->fetchRow()) $data[] = $row; }}} === INSERT === {{{ $result = $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(1, 'DISER')); if ($result) echo "OK"; else echo "Erro na execução da query"; }}} === UPDATE === {{{ /* troca o nome do usuário José para Joselito $result = $this->DAO->query("UPDATE usuario SET nome = ? WHERE (nome = ?)", array('Joselito', 'José')); }}} === DELETE === {{{ /* apaga o usuário cujo ID é 3 */ $result = $this->DAO->query("DELETE FROM usuario WHERE (usuario_id = ?)", array(3)); }}} === Casos Especiais === ==== Inserção de Arquivos no Banco de Dados ==== O procedimento para inserir o conteúdo de um arquivo no Banco de Dados, requer uma pequena modificação que faz o tratamento do conteúdo antes de inseri-lo. Este tratamento é feito através da chamada ao método {{escapeBytea}}: {{{ /* supondo que $bin possua o conteúdo do arquivo */ $bin = $this->DAO->escapeBytea($bin); $result = $this->DAO->query("INSERT INTO tabela_arquivo(nome, conteudo) VALUES(?, ?)", array('arquivo.dat', $bin)); }}} ==== Transações ==== Em alguns casos, é vital a utilização de transações. Sua utilização é muito simples, como pode ser visto abaixo: {{{ /* neste exemplo criamos uma área e tentamos colocar o funcionário José nesta nova área. * Em caso de erro, esta área não deverá ser criada. */ $result = true; $this->DAO->startTrans(); $result = $result && $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(10, 'NOVA ÁREA')); $result = $result && $this->DAO->query("UPDATE funcionario SET area_id = ? WHERE (nome = ?)", array(10, 'José')); if ($result) $this->DAO->completeTrans(); // faz o commit das alterações else $this->DAO->failTrans(); // faz o rollback das alterações }}}