CakePHP doing auto lower casing in Query - cakephp

Below is a part of my query which filters based on like operator in a specific format
$baseQuery->where(
["DATE_FORMAT(`CallRequests`.`updated_date`, '%m/%d/%Y %l:%i %p') like" => $string . '%'],
['updated_date' => 'string']
);
But for some reason CakePHP is auto-lowercasing %Y before query execution.
Below is the related part in the query from the debug dump:
DATE_FORMAT(`CallRequests`.`created_date`, '%m/%d/%y %l:%i %p') like :c0'
I am aware that this can be avoided using raw queries.
But is there a workaround for this behaviour without using raw queries?

You're not supposed to put SQL snippets in the key of a key => value condition. The key side is ment to hold an identifier, and optionally an operator, separated by whitespace. When processed, the right hand side of the whitespace, ie the operator part, is being lowercased, hence what you're experiencing.
You're already using raw SQL, so it's not a big leap to going a step further and use a single value condition to provide a complete raw SQL snippet, and use bindings to inject your value:
$baseQuery
->where([
"DATE_FORMAT(`CallRequests`.`updated_date`, '%m/%d/%Y %l:%i %p') like :date",
])
->bind(':date', $string . '%', 'string');
Alternatively you can use expressions, both for the DATE_FORMAT() function and the LIKE comparison:
$baseQuery->where(
function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $query
) use ($string) {
$dateFormat = $query->func()->DATE_FORMAT([
$query->identifier('CallRequests.updated_date'),
'%m/%d/%Y %l:%i %p'
]);
return [
$exp->like($dateFormat, $string . '%')
];
}
);
See also
Cookbook > Database Access & ORM > Query Builder > Binding Values
Cookbook > Database Access & ORM > Query Builder > Using SQL Functions
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions

Related

CakePHP 3.x case statement on order

I am trying to use a CASE statement on the order of a MySQL statement in CakePHP 3.x app. The simple select is as follows:
$articles = $this->Articles->find()
->where($conditions)
->order(function ($exp, $q) {
return $exp->addCase(
[
$q->newExpr()->gt('Articles.modified', (new Time())->subDays(365)) // article has been updated in the last x days
],
['priority'], # values matching conditions
['string'] # type of each value
);
})
->limit(15)
->all();
The following SQL is generated:
SELECT `Articles`.`id` AS `Articles__id`, ....
FROM `articles` `Articles`
WHERE (`publish` < :c0 AND `Articles`.`publish` > :c1)
ORDER BY CASE WHEN `Articles`.`modified` > :c2 THEN :param3 END LIMIT 15
The case statement is not correct because it is missing the DESC order which should come after the 'END' - see this fiddle:
http://sqlfiddle.com/#!9/8df161/5
I'm not sure if this is a limitation with how CakePHP handles CASE?
Further I require a second order after the case statement to order by 'publish' desc.
Expressions passed to Query::order() must generate everything required by the ORDER BY clause, including the direction keyword.
If the expression that you're using doesn't support that, then you can use Query::oderAsc() or Query::oderDesc(), which will append the respective direction keyword accordingly.
$query = $this->Articles->find();
$query
->where($conditions)
->orderDesc(
$query->newExpr()->addCase(/* ... */)
)
// ...
See also
Cookbook > Database Access & ORM > Query Builder > Selecting Data

How to dump the query in Phalcon Framework using Model

$content = Content::findFirst([
'conditions' => 'state = :state: AND URLid = :url: AND city = :city:',
'bind' => [
'state' => $geodata_usstates->statecode,
'url' => $company,
'city' => $geodata_geocity->city
]
]);
I want to dump the query generated for this. If I were using Laravel, I would simply do
$content->toSql();
But here I'm using Phalcon. How can I achieve the same thing in Phalcon?
Query is not available in your model. Query is build based on model using query builder, passed to Query instance and executed against your db connection.
What you could do is use the events manager and read using the db:beforeQuery event
Example here https://forum.phalconphp.com/discussion/18371/check-the-connection-before-querying-into-database
I don't believe you can output the complete query, because it's a prepared query - thus the best you'd get is:
SELECT * FROM `content` WHERE state = ? AND URLid = ? AND city = ? LIMIT 1
Personally, I don't bother trying to log queries in code. I've enabled the query log on my MariaDB server, and just check the log. The query logged is guaranteed to be the query run.

Cakephp How to use SQL month function in cakephp find method

I have a query like
SELECT count(id),DATE_FORMAT(created,'%M') from searches group by month(created)
The output that I got like
count(id) DATE_FORMAT(created,'%M')
16 August
2 September
I applied this query in cakephp find method like below
$total = $this->Searches->find('count',[
'fields'=>['Searches.id',DATE_FORMAT('created','%M')],
'group' =>[month('Searches.created')]
]);
1st I am getting error date_format() expects parameter 1. How can I apply my top sql query in cakephp find method ?
I am using cakephp 3 version.
The query builder has a func() method that allows you to use SQL functions.
http://book.cakephp.org/3.0/en/orm/query-builder.html#using-sql-functions
$time = $query->func()->date_format([
'created' => 'identifier',
"'%M'" => 'literal'
]);
You can then use that $time variable in your query.

Want to add to database, but not showing/Working

this code keeps saying that the "Record has been Added", yet it's no where to be seen on phpmyadmin...Any thoughts?
phpmyadmin: localhost>summative>Data
$con = mysql_connect("localhost", "root", "") or die(mysql_error());
if(!$con)(die("could not connect " . mysql_error()));
mysql_select_db("summative") or die(mysql_error());
mysql_query("INSERT INTO Data(First Assister) VALUES('$_GET[assist1]')");
if("INSERT INTO Data(First Assister) VALUES('$_GET[assist1]'");
{
echo "Record Added";
}
?>
1.) mysql is now deprecated use mysqli... from http://us2.php.net/manual/en/intro.mysql.php
This extension is deprecated as of PHP 5.5.0, and is not recommended
for writing new code as it will be removed in the future. Instead,
either the mysqli or PDO_MySQL extension should be used. See also the
MySQL API Overview for further help while choosing a MySQL API.
2.) Are you seriously setting $_GET data into your database?
3.) Are you seriously setting $_GET data into your database without escaping it? ALWAYS escape user provided data when putting it into your databse unless you enjoy getting hacked by Chinese government sponsored hackers (or Russian, or Netherlands, or Brazil... or lesser common countries, but those are the most common as far as I've been hack attempted)
See the docs for mysqli_real_escape_string: http://us2.php.net/manual/en/mysqli.real-escape-string.php
2.) Where are you getting that INSERT format from? In MySQL the format is:
INSERT INTO table_name VALUES (value1, value2, value3,...)
From: http://www.w3schools.com/php/php_mysql_insert.asp
Personally, I prefer the other INSERT format:
INSERT [LOW_PRIORITY |
DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
4.) What is your table name? I see a DB name, and I THINK a column name, and then a value...
So I'd change your INSERT statement to this:
$value = mysqli_real_escape_string($_GET['param']);
$sql = 'INSERT INTO `table_name` SET `column`="'.$value.'";';
$result = mysqli_query($sql);

Returning MSSQL data using plperl function in PostgreSQL

I have a PostgreSQL database in use for a complex php web site (And VB.Net/C# management applications) which require access to execute stored procedures on a Microsoft SQL Server 2008 database. The method chosen to perform this interaction is to use plperl functions within the PostgreSQL database to wrap access to the MSSQL stored procedures.
We are using the perl DBI module to handle the data retrieval from MSSQL database.
I am a neophyte when it comes to perl in general and specifically when using it with PostgreSQL. I have created the function shown below to return a set of composite type
CREATE TYPE "public"."permissions_return" AS (
"rolename" TEXT,
"roledescription" TEXT,
"permissionname" TEXT,
"permissiondescription" TEXT
);
The stored proc called from within the function works fine and returns data when run through a slightly different perl script run from the command-line, or directly from the MSSQL Server. I have not been able to figure out how to return data from my function when using:
SELECT * FROM fn_perltest(153);
The result is always an empty set.
CREATE FUNCTION fn_perltest(integer) RETURNS SETOF permissions_return AS $$
use strict;
use DBI;
my $data_source = q/dbi:ODBC:Production/;
my $user = q/afunkyusername/;
my $password = q/afunkierpassword/;
my $dbh = DBI->connect($data_source, $user, $password);
my $sth = $dbh->prepare(q/up_DCORsel_getUserPermissionByUserID $1 ;/);
$sth->execute();
while ( defined ( my $row = $sth->fetchrow_array() )) {
return next ({
rolename => $row->{RoleName},
roledescription => $row->{RoleDescription},
permissionname => $row->{PermissionName},
permissiondescription => $row->{PermissionDescription}
});
}
return;
$$ LANGUAGE 'plperlu'
If this helps, Postgres is running on a Fedora 13 server. Access to MSSQL Server is configured using unixODBC with the freetds driver. Access to the MSSQL server has been tested and works fine using the isql command-line tool and a simple perl script.
Any ideas would be greatly appreciated. I'm concerned I may run out of hair to pull out.
Regards
Shane
This doesn't answer your question directly, but I have used dblink when attempting to have one database query data in another database. It seemed to work well. Obvious plperlu has a lot more power than dblink, but I don't have any experience with it (just perl and postgresql :-)
dblink can be found in postgresql's contrib directory.

Resources