ZF2 PostgreSQL db adapter bug - php

Has anyone encountered a bug with table names using the PostgreSQL adapter in ZF2?
I have a column named UserId and when I try to update/delete a row based on this I get this error:
ERROR: column 'userid' does not exist
as opposed to UserId.
This is my code:
$delete = $this->delete(
'Users'
, array(
'UserId = ?' => $UserId
)
);
Might have something to do with autoQuoteIdentifiers but I couldn't find much online about it.
Any ideas?

The problem was that camel cased column names need to be enclosed in double quotes so the array should be:
array('"UserId" = ?' => $UserId)

Related

updateAll stripping quotes from fields [duplicate]

I have an images table with a column called type. I simply want to update all the rows to change the type to gallery where the user_id matches a particular user.
I am using this code
$this->Image->updateAll(array('Image.type' => 'gallery'),
array('Image.user_id' => $this->Auth->user('id')));
But I get this error: SQL Error: 1054: Unknown column 'gallery' in 'field list'
Why is gallery being added to the field list ?
Isn't the syntax supposed to set type to gallery?
Thanks!
Found this on the manual:
The $fields array accepts SQL expressions. Literal values should be quoted manually.
Thus, the following should work:
$this->Image->updateAll(
array('Image.type' => "'gallery'"),
array('Image.user_id' => $this->Auth->user('id'))
);
In your model do something like this in your method ....
public function saveImage($type='')
{
// I would add a test for $type
$db = $this->getDataSource();
$fields = array('type' => $db->value($type, 'string')); // $db->value() will format strings needed for updateAll()
$condition = array('user_id' => $this->Auth->user('id'));
// I would add a test for user id before running updateAll()
$this->updateAll($fields, $conditions);
}

Escaping a dot in a field name in Zend Framework

I have a problem in writing a query with Zend 1.11.3. I'm not able to get a field whose name contains a dot. Since I cannot edit the table I tried escaping the name, with no success.
My code is the following:
<?php
class RoomsTable extends Zend_Db_Table_Abstract {
...
function getRecord($id)
{
$fields = array(
'id' => 'id',
...
'attrib.floor' => 'attrib.floor',
...
);
$Select = $this->select()
->from($this->_name, $fields)
->where('id = ?',$id);
$list = $Select->query()->fetchAll();
}
}
?>
When I call:
$rooms_table = new RoomsTable();
$first_room = $rooms_table->getRecord(1);
I get:
Zend_Db_Table_Select_Exception: Select query cannot join with another table
So, the attrib.floor field is interpreted as an attempt to get a field from a different table, while it is an actual field name from this table.
I tried with the following without success:
'attrib\.floor' => 'attrib\.floor',
'`attrib.floor`' => '`attrib.floor`',
'"attrib.floor"' => '"attrib.floor"',
Do somebody know how to escape the dot, so that Zend allows me to get that field?
http://framework.zend.com/issues/browse/ZF-953 in the comments:
Identifiers that contain a dot (".") character are automatically split on the dot(s), and each piece quoted separately. Thus identifiers support the "schema"."table" or "table"."column" syntax.
If you have a database design that has table names or column names containing a dot character, this should be a very uncommon case, and it is not recommended. But you can work around it by using Zend_Db_Expr and quote the identifier yourself.
http://framework.zend.com/apidoc/1.9/Zend_Db/Expr/Zend_Db_Expr.html
So in this case the right way to write the field would be:
'attrib.floor' => new Zend_Db_Expr('`attrib.floor`')

Cakephp SQL Error 1054 Unknown Column In The Field List

I am trying to update multiple records in one field in my database. For some reason I keep getting SQL Error: 1054: Unknown column '520947b9' in 'field list'. 502947B9 is apart of my ID. Im not understanding why that value is being seen as a field list. Here is my code. That said, Im not sure Im updating these records correctly. If Im not please point it out to me. Thanks!!
public function findPolicyIds($coverageId = null) {
$policyid = $this->Policy->find('all', array(
'recursive' => -1,
'conditions' => array('Policy.coverage_id' => $coverageId),
'fields' => array('Policy.id')));
foreach($policyid as $id) {
$all[] = $id['Policy']['id'];
foreach ($all as $key) {
$this->Policy->Declination->updateAll(
array('Declination.policy_id' => $key),
array('Declination.coverage_id <=' => $coverageId)
);
}
}
}
Here are my errors
Query: UPDATE declinations AS Declination LEFT JOIN policies AS Policy ON (Declination.policy_id = Policy.id) SET Declination.policy_id = 520947b9-0210-4067-94ea-70f8ae78509d WHERE Declination.coverage_id <= '520947b9-1fa0-45db-992e-70f8ae78509d'
Query: UPDATE declinations AS Declination LEFT JOIN policies AS Policy ON (Declination.policy_id = Policy.id) SET Declination.policy_id = 520947b9-0694-4724-b353-70f8ae78509d WHERE Declination.coverage_id <= '520947b9-1fa0-45db-992e-70f8ae78509d'
By the looks of your query, updateAll is not recognizing $key as a string. Either cast it as such, or add the ' characters yourself. Example:
$this->Policy->Declination->updateAll(
array('Declination.policy_id' => "'".$key."'"),
array('Declination.coverage_id <=' => $coverageId)
);
That's the SQL error.
Now
"That said, Im not sure Im updating these records correctly."
... Well, what do you want to do? Reading your code, You are getting an array of Policy's ids and updating all Declinations with a coverage_id <= $coverageId, which doesn't make much sense, since that foreach is updating the policy_id for that same condition, so in the end you will perceive the last change: last policy_id of the foreach on every Declination with coverage_id equal or less than $coverage_id.... Doesn't make much sense to me, even not knowing what you need to do.
Based on the SQL and assuming you are using an ORM, it appears to me that policy_id is defined as an numeric field in your Declination model when it really needs to be a string. Coverage_id field is working correctly, so compare the two definitions.

Strange behaviour with uppercase Column Names in Doctrine 1.1 resulting in Exception

I have a problem with the case of a column name in Doctrine version 1.1.0.
I have a record (entity) with this definition:
abstract class BaseProductsXsell extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('products_xsell');
$this->hasColumn('ID', 'integer', 4, array('type' => 'integer', 'length' => 4, 'primary' => true, 'autoincrement' => true));
$this->hasColumn('products_id', 'integer', 4, array('type' => 'integer', 'length' => 4, 'unsigned' => 1, 'default' => '1', 'notnull' => true));
// and so on...
}
}
In the MySQL database table the column name of "ID" is upper case, too.
But when I try to fetch the column names after a query with this:
$query = Doctrine_Query::create()->select('m.*')->from("ProductsXsell m");
$collection = $query->execute();
$columns = $collection->getTable()->getColumnNames();
print_r($columns);
The output looks like this:
Array
(
[0] => id
[1] => products_id
...
)
I have not set the case attribute of the doctrine connection anywhere, so it should be the default value (Doctrine::CASE_NATURAL).
This results in the following error:
Fatal error: Uncaught exception 'Doctrine_Record_UnknownPropertyException' with message 'Unknown record property / related component "id" on "ProductsXsell"' in /opt/hocatec/bin/libs/Doctrine/Doctrine/Record/Filter/Standard.php:55
Stack trace:
#0 /opt/hocatec/bin/libs/Doctrine/Doctrine/Record.php(1282): Doctrine_Record_Filter_Standard->filterGet(Object(ProductsXsell), 'id')
#1 /opt/hocatec/bin/libs/Doctrine/Doctrine/Record.php(1240): Doctrine_Record->_get('id', true)
#2 /opt/hocatec/bin/libs/Doctrine/Doctrine/Access.php(117): Doctrine_Record->get('id')
#3 /opt/hocatec/bin/models/HocaSync.php(368): Doctrine_Access->offsetGet('id')
The name of the field that you want to select from your database must to be the same that you defined in your model. Is case sensitive.
You can read more about this here. The first part talk about "Columns" and explain that.
One problem with database compatibility is that many databases differ
in their behavior of how the result set of a query is returned. MySQL
leaves the field names unchanged, which means if you issue a query of
the form "SELECT myField FROM ..." then the result set will contain
the field myField.
Unfortunately, this is just the way MySQL and some other databases do
it. Postgres for example returns all field names in lowercase whilst
Oracle returns all field names in uppercase. “So what? In what way
does this influence me when using Doctrine?”, you may ask.
Fortunately, you don’t have to bother about that issue at all.
Doctrine takes care of this problem transparently. That means if you
define a derived Record class and define a field called myField you
will always access it through $record->myField (or $record['myField'],
whatever you prefer) no matter whether you’re using MySQL or Postgres
or Oracle etc.
In short: You can name your fields however you want, using
under_scores, camelCase or whatever you prefer.
NOTE: In Doctrine columns and column aliases are case sensitive. So when you are using columns in your DQL queries, the column/field names must match the case in your model definition.

find by column name cakePHP

Hello I have been trying to understand how to get data from model by the name of field. I am using cakePHP, and I need to retreive a column's data from a table. The syntax is
> "select name from permissions"
So I tried to find out on book.cakephp.org, so I got the field function, but that only gives me the first value, while I have more than one values for this.
I tried do a
$this->Model->find(array('fields'=>'Model.fieldName'));
but I understood that the syntax itself is flawed.
Can somebody let me know what is the method to query based on column name.
$this->Model->find(array('fields'=>'Model.fieldName'))
You forgot the array function. Also:
$this->Model->find(array('fields'=>array('Model.fieldName')))
will work.
findAllBy will find all records based on the field name.
$this->Model->findAllBy<fieldName>(string $value, array $fields, array $order, int $limit, int $page, int $recursive);
For eaxample:
$this->Permission->findAllByName('Some Name');
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#findallby
Found it... hope it will help someone.
$workshop_lists = ClassRegistry::init('Workshop')->find('all',array(
'fields'=>array('user_id', 'title')
),
array(
'conditions' => array('user_id' => $this->Auth->user('id')),
'group' => 'Workshop.user_id',
'order' => 'posted DESC',
));
There is no way you can query out based on column name using one of the cake methods. You have to use the query method.
Syntax: $this->Model->('Select columnname from table');
$this->Model->find('all',array('fields'=>array('Model.fieldName')))
it works for me everytime.
If I understood well and you want not only 1 value but the whole values in the column 'name' from the table 'permissions'. In that case you could use:
$this->Model->find('list',$params);
(see explanation for 'find' here)
for the '$params' part you would use:
$params=array('fields'=>array('name'));
or putting all in a single line:
$arrayOfNames= $this->Model->find('list',array('fields'=>array('name')));
This will give you an array '$arrayOfNames' wich key is the 'id' (primary key) in 'permissions' table and wich value is the corresponding name in the field 'name' from the same table. This is the array would be something like:
'id'=>'name'
[23]=>'name1'
[28]=>'name2'
[29]=>'name3'
............
very much like I think you want. Hope it helps.
$this->Model->find('list', ['valueField' => 'fieldName']);

Categories