I fixed a serious BC issue that I introduced in the last releases of the MySQL drivers, that would cause issues with servers that do not support InnoDB. I switched to forcing the InnoDB table handler. The fix is to simply not force any table handler and use the server default. There were also some minor bug fixes in several of the other drivers. More importantly however I am pretty happy with the nested transaction API as well as improvements to the debug callback mechanism.
I have mentioned the nested transaction support previously. Since then we have added support for SAVEPOINTs. This feature allows you to define a savepoint within a transaction to which you can rollback to, instead of rolling back the entire transaction. By default the nested transaction API will automatically use SAVEPOINTs to give really tight control in an entirely transparent fashion.
I have also discussed the debug callback mechanism before. This time I have expanded the debug callback mechanism to enable passing more context information to the debug callback. So for example when calling beginTransaction it will pass the optional $savepoint parameter to the callback. More importantly I have added a debug() call at the end of the _doQuery(), prepare() and execute() methods. In order to differntiate the call at the beginning from the call at the end I am passing a context key "time" (not entirely happy with this naming .. suggestions welcome) with "pre" or "post" as the value. This enables people to for example implement query benchmarking. This could be useful to implement a portable MySQL style slow query log. Note that in order to not break BC for older debug handlers I have added a new option "debug_expanded_output" which needs to be set to true to get this additional context information and to get "post" callback calls.
The only two bug reports I am currently hoping to get resolved before the next release are:
Patches welcome :) Expect the new releases in the next week or so.
Hi Lucas,
I am using MDb2 2.1 with MySQL 5.0, INNODB engine, EUC_JP character set and find out that MDB2 2.1 always return an empty page, no error occurs when the MySQL server is down. PEAR::isError can not catch this kind of situation.
<?php require_once("../library/pear/PEAR.php"); require_once '../library/pear/MDB2.php'; $db_engine = 'mysql'; $db_user = 'user'; //Username $db_pass = 'pass'; //Password $db_host = 'localhost'; //Host $db_name = 'db_name'; //Database name $dsn = $db_engine.'://'. $db_user.':'. $db_pass.'@'. $db_host.'/'. $db_name; $mdb2 = &MDB2::factory($dsn); if (PEAR::isError($mdb2)) { echo "Server seems to be down or your user/pass is not valid"; var_dump($mdb2); } ?>
Is it a bug or am I missing something?
If you pass thew "debug" option as true in the factory call like so:
<?php $mdb2 =& MDB2::factory($dsn, array('debug' = true)); ?>
You would find out that there are problems with including the driver files. This is due to the fact that you seem to not have setup your include_path setting according to PEAR standards: http://pear.php.net/manual/en/installation.shared.php (I did not quickly find a better page that explains it. Scroll to the buttom. There it explains how to set the include path at runtime. Alternatively you can modify the include path setting in your php.ini)
In my production code, I have set ini like this
);
And it works smoothly until I shut down MYSQL Server. Before that, I can make queries, generate SQL error....
I tried to run my code in Zend IDE debug mode and found that if I made a call to $mdb2 = &MDB2::factory($dsn); then no error would be caught until I used that $mdb2 to call a query API like query($sql) then the code would run to line 332 (MDB2/Driver/mysql.php)
[php] $connection = @call_user_func_array($connect_function, $params); @ini_restore('track_errors'); if (!$connection) { if (($err = @mysql_error()) != ) { return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, $err); } else { return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, $php_errormsg); } }
[/php]
The error will be caught in
if (($err = @mysql_error()) != )
But this error will be only caught if I make a call to a query API explicitly. Therefore:
///...... }
can not used to check if I can make a connection to mysql server with provided dsn
So
echo "Can not connect to the database server"; $mdb2->errorMessage(); }
wil work for my purpose.
Is it a bug or a desired behaviour?
Thanks Lucas Smith
Regards,
Dinh
If I replace factory() or singleton() with connect() then I can check connection error with
if (PEAR::isError($mdb2)) {
Regards
Yes this is the desired behaviour. MDB2 by default uses what is called as "lazy connect". That means a connection is only established as soon as you actually need one. By calling connect() or query() for example.
Another name idea for your time context key: 'when' And the values: 'before', 'after'
Consider automatic paramaterization. So instead of $db->queryOne("select * from table where id = ".$db->quote($id));
you can do:
$db->queryOne(array("select * from table where id = ?",$id));
it promotes the use of parameterization and is more readable. I have lazy programers that like to write things like:
$db->queryOne("select * from table where id = ".$id)
which is, of course, dangerous.
Also please fix STRICT warnings.
I can send you a diff, but it's pretty easy to do yourself.
Thanks,
Ryan
This is already supported via the Extended module and the get*() methods:
<?php $mdb2->loadModule('Extended'); $query = 'select name, create_date from table where id = ?'; $mdb2->extended->getOne($query, array('text', 'timestamp'), array(42), array('integer')); ?>
What's the MDB2 equivalent to the mysql_error() and mysql_errno() functions? When something goes wrong with my query, all I'm getting is "MDB2 Error: syntax error"