| 1 | == Classe == |
| 2 | 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. |
| 3 | |
| 4 | A documentação da classe pode ser vista neste [http://doc.workflow.celepar.parana/api/Workflow/local/wf_db.html link] |
| 5 | |
| 6 | Os métodos básicos da classe são: |
| 7 | |
| 8 | * ''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); |
| 9 | |
| 10 | * ''disconnect'' - desconecta-se do banco de dados; |
| 11 | |
| 12 | * ''query'' - executa um comando SQL no banco de dados. |
| 13 | |
| 14 | |
| 15 | |
| 16 | == Objeto == |
| 17 | |
| 18 | Oobjetodaclassewf_dbjávemcriadoporpadrãonodesenvolvimentoutilizandooMVCproposto-[wiki:WF_MetodologiadeDesenvolvimento] |
| 19 | . |
| 20 | |
| 21 | Ele pode ser acessado em qualquer classe model através do atributo {{$this->model}} |
| 22 | |
| 23 | |
| 24 | |
| 25 | == Bind == |
| 26 | |
| 27 | 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: |
| 28 | |
| 29 | {{{ |
| 30 | |
| 31 | /* SEM BIND */ |
| 32 | |
| 33 | $this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(1, 'João')"); //plano de execução 1 |
| 34 | |
| 35 | $this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(2, 'Maria')"); //plano de execução 2 |
| 36 | |
| 37 | |
| 38 | |
| 39 | /* COM BIND */ |
| 40 | |
| 41 | $this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(1, 'João')); //plano de execução 3 |
| 42 | |
| 43 | $this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(2, 'Maria')); //plano de execução 3 |
| 44 | |
| 45 | }}} |
| 46 | |
| 47 | 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: |
| 48 | |
| 49 | * 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); |
| 50 | |
| 51 | * Proteção prática e robusta contra [http://en.wikipedia.org/wiki/SQL_injection SQL Injection]. |
| 52 | |
| 53 | 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. |
| 54 | |
| 55 | |
| 56 | |
| 57 | == Utilização == |
| 58 | |
| 59 | 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: |
| 60 | |
| 61 | {{{ |
| 62 | |
| 63 | $this->DAO->connect(); |
| 64 | |
| 65 | }}} |
| 66 | |
| 67 | Em todos os exemplos vamos considerar que a conexão com o Banco de Dados já foi feita. |
| 68 | |
| 69 | === SELECT === |
| 70 | |
| 71 | {{{ |
| 72 | |
| 73 | /* Exemplo 01 */ |
| 74 | |
| 75 | $resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario'); |
| 76 | |
| 77 | $data = array(); |
| 78 | |
| 79 | while ($row = $resultSet->fetchRow()) |
| 80 | |
| 81 | $data[] = $row; |
| 82 | |
| 83 | /* a variável $data será uma array com os valores selecionados */ |
| 84 | |
| 85 | echo $data[0]['nome']; //exemplo de acesso aos dados (nome do primeiro registro retornado) |
| 86 | |
| 87 | |
| 88 | |
| 89 | /* Exemplo 02 */ |
| 90 | |
| 91 | $resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario WHERE (nome = ?)', array('José')); |
| 92 | |
| 93 | $data = array(); |
| 94 | |
| 95 | while ($row = $resultSet->fetchRow()) |
| 96 | |
| 97 | $data[] = $row; |
| 98 | |
| 99 | }}} |
| 100 | |
| 101 | |
| 102 | |
| 103 | === INSERT === |
| 104 | |
| 105 | {{{ |
| 106 | |
| 107 | $result = $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(1, 'DISER')); |
| 108 | |
| 109 | if ($result) |
| 110 | |
| 111 | echo "OK"; |
| 112 | |
| 113 | else |
| 114 | |
| 115 | echo "Erro na execução da query"; |
| 116 | |
| 117 | }}} |
| 118 | |
| 119 | |
| 120 | |
| 121 | === UPDATE === |
| 122 | |
| 123 | {{{ |
| 124 | |
| 125 | /* troca o nome do usuário José para Joselito |
| 126 | |
| 127 | $result = $this->DAO->query("UPDATE usuario SET nome = ? WHERE (nome = ?)", array('Joselito', 'José')); |
| 128 | |
| 129 | }}} |
| 130 | |
| 131 | |
| 132 | |
| 133 | === DELETE === |
| 134 | |
| 135 | {{{ |
| 136 | |
| 137 | /* apaga o usuário cujo ID é 3 */ |
| 138 | |
| 139 | $result = $this->DAO->query("DELETE FROM usuario WHERE (usuario_id = ?)", array(3)); |
| 140 | |
| 141 | }}} |
| 142 | |
| 143 | |
| 144 | |
| 145 | === Casos Especiais === |
| 146 | |
| 147 | ==== Inserção de Arquivos no Banco de Dados ==== |
| 148 | |
| 149 | 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}}: |
| 150 | |
| 151 | {{{ |
| 152 | |
| 153 | /* supondo que $bin possua o conteúdo do arquivo */ |
| 154 | |
| 155 | $bin = $this->DAO->escapeBytea($bin); |
| 156 | |
| 157 | $result = $this->DAO->query("INSERT INTO tabela_arquivo(nome, conteudo) VALUES(?, ?)", array('arquivo.dat', $bin)); |
| 158 | |
| 159 | }}} |
| 160 | |
| 161 | |
| 162 | |
| 163 | ==== Transações ==== |
| 164 | |
| 165 | Em alguns casos, é vital a utilização de transações. Sua utilização é muito simples, como pode ser visto abaixo: |
| 166 | |
| 167 | {{{ |
| 168 | |
| 169 | /* neste exemplo criamos uma área e tentamos colocar o funcionário José nesta nova área. |
| 170 | |
| 171 | * Em caso de erro, esta área não deverá ser criada. |
| 172 | |
| 173 | */ |
| 174 | |
| 175 | $result = true; |
| 176 | |
| 177 | $this->DAO->startTrans(); |
| 178 | |
| 179 | $result = $result && $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(10, 'NOVA ÁREA')); |
| 180 | |
| 181 | $result = $result && $this->DAO->query("UPDATE funcionario SET area_id = ? WHERE (nome = ?)", array(10, 'José')); |
| 182 | |
| 183 | if ($result) |
| 184 | |
| 185 | $this->DAO->completeTrans(); // faz o commit das alterações |
| 186 | |
| 187 | else |
| 188 | |
| 189 | $this->DAO->failTrans(); // faz o rollback das alterações |
| 190 | |
| 191 | }}} |