PDO update column based on its current value not working - sql

I have this PDO statement:
parent::$db->custom('UPDATE users_credits SET availabe = availabe - :reward_credits, used = used + :reward_credits WHERE user_id = :user_id', array(
'reward_credits' => $reward_credits,
'user_id' => $user_id
));
For some reasons it simply does not work. I tried the very same query on the DB manually and it works.
What's wrong with PDO and how do I achieve the very same result I would achieve normally?
Thanks for any suggestion

First of all. There is nothing wrong with PDO and never has been.
It is some your own custom code to blame.
Simple checklist to solve any PDO related problem
Make sure you can see all the PHP errors.
Configure PDO to throw exceptions in SQL errors, by calling this after connect
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Debug your code.

Related

Creating a Sequelize Dialect for new Database

I'm pretty new to sequelize, though I've worked on node previously I did not use any ORM framework. At present I'm using new SQL DB(which is not supported by sequelize ) and want to connect it using node.js and sequelize( popular ORM for node.js ) by prototyping the existing dialects
The configuration is correct as I've tried it wihtout ORM.
The problem is after configuring the connection with properties the
sequelize.authenticate() doesn't throw any error but doesn't return a promise back
/**
* Test the connection by trying to authenticate
*
* #error 'Invalid credentials' if the authentication failed (even if the database did not respond at all...)
* #return {Promise}
*/
authenticate(options) {
return this.query('SELECT 1+1 AS result', _.assign({ raw: true, plain: true }, options)).return();
}
The return statement doesn't return anything. I've read this post how to create a new dialect. Though it says it is not encouraged to create a new dialect and throws an error if we try to, I think there must be a way to create because if it can be created for other SQL databases then may be there should be a way to do it. This is an open source project on github. Did anyone previously work on this any help is appreciated. Thanks in Advance
Only the 5 dialects are supported and an error will be thrown if you try and use NewSQL.
There is a lot of code in Sequelize to construct queries based on the dialect, so even if you could get past the error (such as forking the repo and changing it) the likelihood of everything working as you expect (or as is documented) is low.
I suggest posting an issue on GitHub to bring that dialect to the project.

How do I check the result of a Fat Free Mapper call to save a DB record?

I'm using the SQL Mapper to update records in my MYSQL DB which is working ok - but I can't see how to check what the outcome of the update was from the call to save() or update().
Update seems to return the entire mapper object which doesn't offer an obvious way of checking if the update failed. Should I be checking the return code or catching an exception?
Any help appreciated!
Matt
libregeek is right, you should enable PDO exceptions and catch them:
$db=new \DB\SQL($dsn,$user,$pwd,[
\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION]
);
$mytable=new \DB\SQL\Mapper($db,'mytable');
try {
$mytable->copyfrom($input);
$mytable->save();
echo 'Data successfully saved';
} catch(\PDOException $e) {
echo 'Something went wrong';
// let's find what exactly:
$err=$e->errorInfo;
echo $err[0];// PDO error code
echo $err[2];// driver specific error message
}
See also this topic.
All mappers extend Cursor. The problem is cursor methods save() and update() return this.
Related: see this issue on Github: https://github.com/ikkez/f3-cortex/issues/3
The way out may be to use hooks such as aftersave or beforesave:
$mapper->aftersave(function($self,$pkeys){
//do something after inserting or updating
// Maybe validate
});
Hope this helps.
You could get PDO style exceptions if you enable it while initializing the DB object.
Refer https://fatfreeframework.com/3.6/sql
PDO Exception reference:
http://php.net/manual/en/class.pdoexception.php
P.S: I haven't tried them, so not sure how much they are useful.

Sphinx enable STP_MATCH_EXTENDED for PDO connection

If my PDO connection is as below:
$sphinx = new PDO('mysql:dbname=db;host=127.0.0.1;port=9306;charset=utf8', 'user', 'pass');
$sphinx->exec('SET CHARACTER SET utf8');
$sphinx->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$sphinx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
And my query is:
$array = $sphinx->prepare("select * from `indexname` where MATCH #(title,body) hello world");
What is the correct way to enable SPH_MATCH_EXTENDED?
If I add:
require ("sphinxapi.php");
$sphinx = new SphinxClient();
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
$sphinx->SetArrayResult(true);
Under the PDO connection, is this the correct way to enable stp_match_extended for PDO?
What is the correct way to enable SPH_MATCH_EXTENDED?
SphinxQL uses Extended Match Mode by default.
Don't need to do anything to use it.
You can change to use a different match mode if really want, but its NOT recommended. Internally Sphinx only (now!) implements Extended match mode, the others are all emulated.

Share sqlite2 database with Yii webapp

Hi I've got a sqlite2 database that is being used by a PHP webapp and I want a Yii webapp to access it. At the moment I copied the db file to a local server and I've changed config/main.php to:
'db'=>array(
'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/thedatabase.db',
),
When I run the Gii model generator I get:
CDbException
CDbCommand failed to execute the SQL statement: CDbCommand failed to prepare the SQL statement: SQLSTATE[HY000]: General error: 26 file is encrypted or is not a database. The SQL statement executed was: SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'
BTW I am able to convert the database to SQL using
Exporting sqlite2 database to SQL
Though I want the database to stay as an sqlite2 database so that the Yii app can access up to date user info.
After some thought it looks like it would be simpler to just use some code from the old PHP project in the Yii project...
$db = sqlite_open($databasefilename, 0666, $sqliteerror);
$query = sqlite_query($db, "SELECT password FROM user WHERE username='$username'");
$row = sqlite_fetch_array($query);
if ($row) {
return $row[password];
}
Edit:
When using that code I get the following error:
undefined function sqlite_open()
I'm using PHP Version 5.4.7...
http://au1.php.net/manual/en/function.sqlite-open.php
Here it says:
PHP 5 < 5.4.0
I got it working with the sqlite2 database by using 'sqlite2:' instead of 'sqlite:'
'db2'=>array(
'class'=>'CDbConnection',
'connectionString' => 'sqlite2:'.dirname(__FILE__).'/../../../thedatabase.db',
),
I can do queries like this:
Yii::app()->db2->createCommand($sql)->queryAll());
To stop Error 500 Object configuration must be an array containing a "class" element 'class'=>'CDbConnection' is required in config/main.php. I think that info is already included in the first database connection somewhere.

PHP error_log errors to MySQL

In a previous ticket i asked about logging PHP errors in MySQL which gives me:
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
// mysql connect etc here...
$sql = "INSERT INTO `error_log` SET
`number` = ".mysql_real_escape_string($errno).",
`string` = ".mysql_real_escape_string($errstr).",
`file` = ".mysql_real_escape_string($errfile).",
`line` = ".mysql_real_escape_string($errline);
mysql_query($sql);
// Don't execute PHP internal error handler
return true;
}
// set to the user defined error handler
$new_error_handler = set_error_handler("myErrorHandler");
I can make this work but only if it is triggerred like this:
trigger_error("message here");
However, I also want the error handler to be called for all errors such as syntax errors like:
echo "foo;
But these errors are just outputted to the screen, what am i doing wrong?
You can only handle runtime errors with a custom error handler. The echo "foo error in your example happens when parsing (i.e. reading in) the source. Since PHP can not fully parse the code, it can also not run your error handler on this error.
If You're forced to test if syntax is correct, You can use php_check_syntax function, with filename parameter PHP Manual php_check_syntax
php_check_syntax also provides second parameter, witch when used will be populated by the error string, as far as i remember
That's indeed terrible way of error logging
You don't need not a single advantage of a database. Would you make a database lookup for the certain line number? Or order your results by file name?
database is a subject of many errors itself.
You've been told already that it's impossible to catch a parse error at the program logic level, because a syntactically wrong program will never run.
Let's take your code as an example. It will raise a MySQL error (because of poorly formed query) which you will never see. As well as any other errors occurred. That's what I am talking about.