Tradução de http://www.phpied.com/db-2-mdb2/
Recentemente eu tive de migrar um projeto do PEAR:DB para o PEAR::MDB2 - a nova abstração de banco de dados. Eu fiz algumas anotações sobre as partes de código que eu precisei mudar, e espero que eles possam ser úteis para alguém que esteja fazendo o mesmo. Muito obrigado ao Lukas Smith, o desenvolvedor líder que sempre respondeu muito rápido aos meus relatórios e questionamentos na lista do PEAR.
Uma coisa a ser notada no MDB2 é que ele tenta não fazer qualquer trabalho desnecessário e faz muitas coisas sob demanda. Por exemplo, quando você cria um objeto, isso não significa que uma conexão tenha sido feita. Ela é feita somente quando você faz o primeiro acesso real a um banco de dados, como por exemplo, um SELECT.
Eu assumo que você já tem uma base do PEAR::DB, desde que esse texto ilustra uma comparação entre o DB e o MDB2 , mas mesmo que você não o conheça, espero que esse texto seja uma introdução interessante ao DB e ao MDB2.
Primeiramente, incluindo as bibliotecas (Eu assumo que você já tem o PEAR na sua máquina).
<?
require_once 'DB.php';
require_once 'MDB2.php'
?>
Uma coisa a ser notada é que a instalação do MDB2 não inclui os drivers MDB2 de banco de dados. Assim, se você vai usar o MySQL, por exemplo, você precisa instalar o wrapper separadamente: pear install MDB2_Driver_mysql em adição a pear install MDB2
A seguir, a string de conexão. É a mesma para o MDB2 e para o DB.
<?php
$dsn = 'mysql://root@localhost/db2mdb2';
?>
A propósito, tando o MDB2 e o DB aceitam um array com todos os detalhes da conexão.
<?php
$db =& DB::connect($dsn);
$mdb2 =& MDB2::factory($dsn)
?>
O MDB2 dispõe também de um método de fábrica para criar uma instância. Nesse momento, a conexão com o banco ainda não é feita. O MDB2 também dispõe de um método singleton() para criar uma instância.
É o mesmo em ambos, apenas observe o prefixo da constante.
<?
// set fetchmode
$db->setFetchMode(DB_FETCHMODE_ASSOC);
$mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
?>
Esses são métodos para selecionar uma linha, uma coluna, uma célula e uma porção de registros.o DB usa o prefixo get, e o MDB2 usa query.
<?php
// seleciona alguns rrgistros e os traz em um array
$all = $db->getAll('SELECT * FROM people');
$all = $mdb2->queryAll('SELECT * FROM people');
// seleciona uma célula
$one = $db->getOne('SELECT name FROM people WHERE id = 1');
$one = $mdb2->queryOne('SELECT name FROM people WHERE id = 1');
// uma linha
$row = $db->getRow('SELECT * FROM people WHERE id = 1');
$row = $mdb2->queryRow('SELECT * FROM people WHERE id = 1');
// uma coluna
$col = $db->getCol('SELECT name FROM people');
$col = $mdb2->queryCol('SELECT name FROM people')
?>
No DB, o método sugerido para adicionar aspas é o quoteSmart(). NoMDB2 é o quote() e ele aceita um segundo parâmetro que diz qual o tipo do valor a receber as aspas. Se o segundo parâmetro é omitido, o , MDB2 irá tentar adivinhar o tipo.
$one = $mdb2->queryOne(
'SELECT name FROM people WHERE id = '
. $db->quote(1, 'integer')
)
?>
Se você usa tabelas de sequência, ambas as bibliotecas dipões de um método nextId():
<?php
echo $db->nextId('people_db');
echo $mdb2->nextId('people_mdb2');
?>
A única diferença é que quando o DB cria uma tabela sequência(com um campo e um valor), o nome do campo é id, onde o MDB2 irá usar sequence. Se você está movendo um projeto existente para o MDB2 como eu, e já tam as tabelas sequência criadas pelo DB, você tem a opção de renomear essa campo no banco de dados para todas as tabelas sequência, ou você or you can set an MDB2 option and you're good to go.
<?php
$mdb2->setOption('seqcol_name','id');
?>
Digamos que você tenha os dados:
<?php
$data = array('id' => 5, 'name' => 'Cameron');
?>
Para auto-inserir, usando o DB , você faria:
<?php
$db->autoExecute('people', $data, DB_AUTOQUERY_INSERT);
?>
Para o MDB2, a auto execução é provavelmente considerada uma característica usada frequentemente, então não faz parte da instãncia base. Você precisa carregar um módulo adicionar para ter acesso a isso:
<?php
$mdb2->loadModule('Extended');
?>
Agora você pode:
<?php
$mdb2->autoExecute('people', $data, MDB2_AUTOQUERY_INSERT);
?>
O exemplo acima vai funcionar em PHP5 somente. Em PHP4, devido ao suporte limitado a sobrecarga de objetos (Obrigado de novo Lukas por esclarecer isso!), você precisaria fazer:
<?php
$mdb2->extended->autoExecute('people', $data, MDB2_AUTOQUERY_INSERT);
?>
Perceba que a segunda forma irá funcionar em PHP5 também.
No DB:
<?php
$statement = $db->prepare('INSERT INTO people VALUES (?, ?)');
$data = array(6, 'Chris');
$db->execute($statement, $data);
$db->freePrepared($statement);
?>
No MDB é quase da mesma forma, o que muda é que o statement se torna um objeto e você pode chamar seus métodos para executar e liberar a memória (no lugar dos métodos do MDB2)
<?php
$statement = $mdb2->prepare('INSERT INTO people VALUES (?, ?)');
$data = array(7, 'Dave');
$statement->execute($data);
$statement->free();
?>
O mesmo se aplica para a execução de uma declaração com diversas linhas de dados em um array. O executeMultiple() está no módulo estendido do MDB2 module, então você irá precisar carregá-lo:
DB:
<?php
$statement = $db->prepare('INSERT INTO people VALUES (?, ?)');
$data = array(
array(8, 'James'),
array(9, 'Cliff')
);
$db->executeMultiple($statement, $data);
$db->freePrepared($statement);
?>
MDB2:
<?php
$statement = $mdb2->prepare('INSERT INTO people VALUES (?, ?)');
$data = array(
array(10, 'Kirk'),
array(11, 'Lars')
);
$mdb2->loadModule('Extended');
$mdb2->extended->executeMultiple($statement, $data);
$statement->free();
?>
No DB:
<?php
$db->autoCommit();
$result = $db->query('DELETE people'); // will cause an error
if (PEAR::isError($result)) {
$db->rollback(); //echo 'rollback';
} else {
$db->commit(); //echo 'commit';
}
?>
No MDB2 você precisa verificar se transações são suportadas no seu banco de dados. Então, durante a transação. você pode sempre verificar: "Eu estou numa transação?"
<?php
if ($mdb2->supports('transactions')) {
$mdb2->beginTransaction();
}
$result = $mdb2->query('DELETE people');
if (PEAR::isError($result)) {
if ($mdb2->in_transaction) {
$mdb2->rollback(); // echo 'rollback';
}
} else {
if ($mdb2->in_transaction) {
$mdb2->commit(); // echo 'commit';
}
}
?>
Script exemplo
Você pode baixar um script que tem os exemplos acima e testá-los. Segue também o arquivo sql para recriar o banco de dados: