CakePHP: HABTM not performing join properly on habtmDelete call - php

We are upgrading from Cake 1.2 to 1.3.8, and using the ExtendedAssociations behavior.
One of the problems we are having, is in our Store model, which has a HABTM relationship to Module via stores_modules.
Retrieving the data is all good, but one issue moving to 1.3.8 seems to have introduced is that when we want to delete all Modules from the Store - in the Stores model
$this->habtmDeleteAll('Module', $this->id);
The problem is that this produces the following SQL query (as it is SELECTING all stores_modules first, to see what to delete)
SELECT StoresModule.module_id FROM stores_modules AS StoresModule WHERE StoresModule.store_id = 1 AND Module.system_default = 0
_
2011-03-29 18:27:46 Warning: Warning (512): SQL Error: 1054: Unknown column 'Module.system_default' in 'where clause' in [/usr/lib/cakephp_1.3.8/cake/libs/model/datasources/dbo_source.php, line 684]
So it appears the problem is that the above SQL statement is not adding the JOIN to the modules table.. hence it cannot fine Module.system_default
Any help on this would be great, it's really got me stumped :)
Chris.

I'm not totally sure I understand, but it appears you are not calling your models correctly. If you need to delete all associated model records, you would probably do something like this:
$this->Store->Modules->deleteAll(array('Store.id' => $id), true, false);
NOT TESTED!

Related

Duplicate query issue in yii2

I am working on one module in yii2 and please count me as a noob in this. I usually work in Laravel.
My query looks as below.
$query = SomeModel::find()
->joinWith(['relation1 s', 'relation2 r','relation3','relation4 c'])
->where(some where contions)
->where(some where contions);
The issue is in the view the yii2 debugger (Database Queries) shows "187 duplicated queries found."
My model doesn't have any loop around the query.
I have tried with removing joinWith relations but it will increase the duplicate queries to 220.
The query which gets repeated is one SELECT query
SELECT * FROM `relation4` WHERE `id`= 2159
I have checked the "relation4" model but it has nothing suspicious in it.
What should I do or where should I look to resolve this issue??

CodeIgniter/sqlsrv/MSSQL Update-Queries contain Id-column - Error

I have a hard time migrating a WebApp from a Unix/Apache/MySQL System to Win2012/Apache/MSSQL. First I installed the sqlsrv-stuff you need and the connection works.
BUT:
update queries cause error mesages like
A Database Error Occurred
Error Number: 42000/8102
[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Die
id-Identitätsspalte kann nicht aktualisiert werden." The last part
basically means "The ID-identy column may not be updated."
The generated update-query looks like this:
UPDATE "dbo"."table" SET "id" = 1, "someStuff" = 5 WHERE "id" = 1
My models use statements like:
$data = array (
'someStuff' => (int) $stuff
);
$this->db->update('table',$data,"id = ".$itemID);
I understand the message as the statement contains a SET "id" which is obviously irrelevant as the id-field is an auto-increment thing generated in mssql - and as you see, I am not including it in my model. How do I get Codeigniter to reduce the UPDATE-statement to not contain primary keys? Or is there another easy way to resolve this?
If it helps, I might as well modify Codeigniter to check if the internally generated query contains an id field in order to skip these, as they are always auto-incremented primary keys, but my attempts to do so weren't successful.
If id is an auto-increment field, don't include it in the Codeigniter Insert/Update query. It should be added automatically. Just Insert/Update the other values on the DB
Rem: Auto-increment attribute is set on the Database level not on the Codeigniter.
As I found out, someone made undocumented last-minute changes during the migration and found out that the data-array did not contain the id - and for a reason I'll never understand he thought it would be a great idea to put them in.
Sorry sorry for the confusion!
Lessons learned:
CI works fine even with SQLSRV,
I'll have to make sure that the code I create is uploaded as I wanted it to be.

Missing rows when querying table with Doctrine (Symfony2)

I'm encountering a strange issue with Doctrine.
I need to query a simple table with only 1 inner join, which I something I have already done many times. But in this case something's odd: there are a lot of rows missing.
I have an entity called Policy. It is linked to a table on my Oracle database. There are 81k+ rows in this table. When querying this entity with the Doctrine query builder, I only get 5k results. I made this query as simple as possible for testing :
$qb = $em->createQueryBuilder();
$qb->select('p')->from('ErwMonitoringExtranetBundle:Policy', 'p');
$query = $qb->getQuery();
$policiesFull = $query->getResult();
The $policiesFull variable only contains 5k elements. There are no duplicates in the table.
The SQL query that is generated by Doctrine looks like this :
SELECT
r0_.node_group_name AS NODE_GROUP_NAME0,
r0_.policy_name AS POLICY_NAME1,
r0_.policy_description AS POLICY_DESCRIPTION2,
r0_.policy_group_name AS POLICY_GROUP_NAME3,
r0_.policy_type_name AS POLICY_TYPE_NAME4,
r0_.policy_name_on_agent AS POLICY_NAME_ON_AGENT5,
r0_.date_last_maj AS DATE_LAST_MAJ6,
r0_.om_name AS OM_NAME7,
r0_.id_node AS ID_NODE8
FROM
ewintranet.ref_monitored_ci;
Running the same exact query on Oracle returns the full table content.
Counting results through a doctrine query returns the correct number of rows :
$qb = $em->createQueryBuilder();
$qb->select('count(p)')->from('ErwMonitoringExtranetBundle:Policy', 'p');
$query = $qb->getQuery();
echo $query->getSingleScalarResult();
This returns 81k.
Does anybody know why all these rows disappear after using getResult() ?
This is what I would do:
Check the result using createQuery or createNativeQuery
Run the query from simple php script outside of symfony
If with all 3 methods you get the same issue then it might be problem with the size of data limitation.
I would start with max_execution_time and memory_limit settings in php.ini
I found also some oracle limitations that might be set at:
oci8.statement_cache_size in php.ini or in file oraaccess.xml in Oracle directory. It is also significant if you use APC for query caching.
Anyway what does app_dev.php say?
Okay, I found out what was causing my issue. The primary ID was wrong in my Entity declaration.
The oracle table had a composed primary key while in my entity the ID was only on one column. GetResult was making a DISTINCT on this column.

Doctrine 2.1: Getting and assigning COUNT(t.id) from a subquery?

I have two entities in Doctrine 2.1: Category and Site each category has many sites and each site has a parent category.
I would like to make a single update query (in DQL) which will update a field called count of the Category entity with the number of related sites.
So in SQL I would do something like this:
UPDATE categories c SET c.count = (SELECT COUNT(s.id) FROM sites s WHERE s.category_id = c.id);
This would work beautifuly, in DQL it might something like this:
UPDATE PackageNameBundle:Category c SET c.count = (SELECT COUNT(s.id) FROM PackageNameBundle:Site s WHERE s.category = c)
Such attempt raises [Syntax Error] line 0, col 61: Error: Expected Literal, got 'SELECT'.
Subqueries DO work in DQL, but the problem here (as far as I see it) is that Doctrine cannot assign the returned value from the subquery, to the c.count. This is understandable since I might fetch more than 1 field in the subquery and even more than one row. It magicaly works in MySQL since it sees one row, one field and for convenience returns a single integer value. Doctrine on the other hand has to be object oriented and has to work with different engines where such convertions might not be supported.
Finally, my question is:
What is the best way to do this in Doctrine, should I go with Native SQL or it can be done with DQL and how?
Thanks in advance!
EDIT: I just found this quote in the DQL Docs:
References to related entities are only possible in the WHERE clause and using sub-selects.
So, I guess assigning anything but a scalar value is impossible?
The main question remains though..
You can use native sql queries in Doctrine also, for that kind of specific queries. DQL is powerful in its own way, but it's also limited due to performance constraints. Using native sql queries and mapping the results will achieve the same thing, and there is no disadvantage in doing that.
The documentation explains it in detail.

Behavior Difference between find('count') and find('all') cakePHP

I am having an odd problem in CakePHP where
$this->something->find('count');
works perfectly, yet
$this->something->find('all');
returns nothing (not even an empty array, any errors, or anything).
edit: turns out I am getting an sql error: "SQL Error: 1054: Unknown column" - for a column that does indeed exist. (users.display_name in the sql query below):
SELECT item.id, item.name, item.description, item.user_id, users.display_name FROM item LEFT JOIN users ON (item.user_id = users.id);
I also tried using findAllBy as well as paginate (paginate is actually what I am trying to do - although from what I've gathered, paginate and find('all') are pretty similar in functionality).
The odd thing is that find('all') works everywhere else - it's just in this specific controller that it is acting odd. I am not getting any errors, simply an empty result.
I'm thinking that I may be overlooking something quite simple, but any help is appreciated. Thanks!
So, as per our discussion, the problem you're having is with the virtual fields. Have a look at the documentation, more specifically at the virtual fields and model aliases and limitation of virtualFields sections.
From your description above, it looks like you have a join specified your virtual field which would be causing the error you're seeing because it'll add the JOIN before the FROM. If you insist on using the virtual field, I'd suggest you rewrite it to use a subquery. Make sure your subquery only returns 1 column.
Example: (http://web-development-blog.co.uk/2011/03/08/cakephp-virtual-field-count-another-modeltable/)
public $virtualFields = array(
'count' => 'SELECT COUNT(*) FROM stacks Stack'
);
Alternatively, you can use the Model::beforeFind to bind the necessary models (if necessary) and change the query parameters.
If you can't figure it out, please post your model and I'll help you.
The specific problem you're having with the difference in behaviour is that find('count') will run a basic COUNT(*) query on your database to determine the number of rows.
find('all'), however, runs a different query, and if the SQL you've provided is what it's trying to use, it's invalid:
SELECT item.id, item.name, item.description, item.user_id, users.display_name LEFT JOIN users ON (item.user_id = users.id);
There's no FROM declaration (SELECT from what, exactly?), and if you've not customised your Item or User or App models, (setting $useTable = false maybe?) you're dealing with an unusual error.
One thing to look out for, if these models work fine in other controllers, is any alteration to the properties of each model in each controller. They won't act differently on a per-controller basis unless you have code in each controller that tells it to.

Categories