Re: [PDO] Re: [PHP-DEV] [PATCH] New PDO methods for PostgreSQL driver
[email protected] (Denis Gasparin) Tue, 25 May 2010 11:56:12 +0200 (CEST)
| Newsgroups | php.pdo |
|---|---|
| Message-ID | <33528933.35408.1274781372025.JavaMail.root@mailserver.edistar.com> |
> Lester Caine schrieb:
> > Christopher Jones wrote:
> >> Also I haven't seen anything to explain your earlier comment to
> >> Lester that
> >> "In particular you'll need two database connections (one with the
> >> original driver and one with PDO) in order to use the native copy*
> >> functions.".
> >
> > I see my name, but not connection with the quote ...
> >
> > But in addition to Denis's examples of where you need two database
> > connections, 2 phase commit across multiple databases has been part
> > of Firebird for
> > many years, and other databases are now copying it. This requires
> > combining database connections in the one transaction, and is
> > something that PDO is unable to handle at all? It's one of the items
> > on http://wiki.php.net/internals/pdo/brainstorming?s[]=pdo ... as is
> > the question "Is the goal to eventually replace the native
> > extensions?"
> >
> I see several possible ways without a complete new userland API to
> handle several database connections in PDO:
>
> A basic driver specific dsn to handle several databases. Then you only
> need a driver specific handle switch function.
> beginTransaction would default to all databases in your DSN.
>
> PDO::firebirdUseDatabase();
>
> + Keeps the whole logic in the driver, can use optimized ways to
> handle transactions.
> - Driver specific, the dsn gets very long.
> - Removes the concept of PDO being a database instance.
>
> A firebird specific pool driver could be used as well:
>
> $dbh1 = new PDO(..);
> $dbh2 = new PDO(..);
>
> $dbhpool = new PDO('firebird:pool');
>
> $dbhpool->firebirdAttachChild($dbh1);
> $dbhpool->firebirdAttachChild($dbh2); $dbhpool->beginTransaction()
>
Another way could be to maintain a generic PDO driver with a standard dsn (for example "username:password@host/dbname" or the PDO standard "db:host=..,dbname=...") and then to inject a "strategy" to use for database connection and other specific DBMS functions.
For example:
$fbDb = new PDOFirebirdDatabase();
$dbhpool = new PDO('user:pwd@pool/dbname',$fbDb);
$dbhpool->db->attachChild(new PDOFirebirdConnection(..));
$dbhpool->db->attachChild(new PDOFirebirdConnection(..));
$dbhpool->db->beginTransaction());
Another example:
$pgDb = new PDOPostgreSQLDatabase();
$dbh = new PDO('user:pwd@pool/dbname',$pgDb);
$dbh->db->connectionStatus();
$dbh->db->copyFromFile(...);
The strategy could also be determined automatically by the PDO main class using a prefix as mysql:, pgsql:, firebird: etc.
This is how the current PDO object works.
In order to check if a method is defined/supported by the PDO object, it is possible to determine via object type ($dbhpool->db instanceof PDOFirebirdDatabase) or checking via reflection.
Example:
$dbh = new PDO('pgsql:host=pool;user=username;password=password;dbname=dbname');
if($dbh->db instanceof PDOPostgreSQLDatabase) {
$dbh->db->copyFromFile(...);
}
else {
$dbh->beginTransaction();
$f = fgetcsv(...);
foreach($f as $r) {
$dbh->exec(..);
}
$dbh->commitTransaction();
}
Just my two cents
Denis
> + Separates the basic usage from the advance usage, for most people
> PDO still will be one database handle.
>
> The other route would be a dummy driver for all drivers:
> Could be a bit problematical if you mix database drivers.
>
> $dbhpool = new PDO('pool:');
> $dbhpool->poolAttach($dbh1); $dbhpool->poolAttach($dbh2);
>
> $dbhpool->beginTransaction();
>
> + With some emulation it may work across Servers and Drivers via
> transaction save points?
> + Allows one instance to have less good transaction support in the
> pool, will get commit first, then the others...
> - Not easy to handle, needs several hacks to hijack
> beginTransaction/commit - Against the low level design of PDO
>
> Or the same as transaction object...
>
> $tobj = new PDOCrossTransaction();
> $tobj->attach($dbh1); $tobj->attach($dbh2);
> $tobj->beginTransaction($options);
>
> + Can change the function declaration for transaction options
>
> So I don't think there is a really a need to change fundamental all
> stuff of PDO to support this...
>
> Oskar Eisemuth
>
>
> -- PDO Working Group Mailing List (http://pdo.php.net)
> To unsubscribe, visit: http://www.php.net/unsub.php