query builder select the id from leftJoin - doctrine-orm

I have a select field that fetch from an entity
and I would like to customize completely my select by choosing the table the id is picked from
(here I would like to select t.id instead of tl.id as the select value)
return $er->createQueryBuilder('tl')
->addSelect('l')
->addSelect('t')
->leftJoin('tl.lang', 'l')
->leftJoin('tl.type', 't')
->where('l.isDefault = 1')
->orderBy('tl.name', 'ASC');
Due to my tables, I can't simply fetch the table t, I have to use tl

Your query is not according to the syntax defined in Doctrine 2 QueryBuilder: http://www.doctrine-project.org/docs/orm/2.0/en/reference/query-builder.html
Your query might work in Doctrine 1.2 but in Doctrine 2 you should build your query according to the syntax defined in the link I posted above.
For example ->addSelect('l') is not being used in Doctrine 2 anymore. It has become ->add('select', 'l').

You don't have to set different alias for your column. It'll be hydrated as column of the related entity.

Related

How to convert this SQL query to Django Queryset?

I have this query which selects values from two different tables and used array agg over matched IDs how can I get same results using the queryset. Thank you!
select
sf.id_s2_users ,
array_agg(sp.id)
from
s2_followers sf
left join s2_post sp on
sp.id_s2_users = sf.id_s2_users1
where
sp.id_s2_post_status = 1
and sf.id_s2_user_status = 1
group by
sf.id_s2_users
You can run raw SQL queries with Django's ORM if that's what you wanted. You don't have to change your query in that case, you can check documentation here.

How to phrase sql query when selecting second table based on information on first table

I have two tables I would like to call, but I am not sure if it is possible to combine them into one query or I have to some how call 2 different queries.
Basically I have 2 tables:
1) item_table: name/id etc. + category ID
2) category_table: categoryID, categoryName, categoryParentID.
The parent categories are also inside the same table with their own name.
I would like to call on my details from item_table, as well as getting the name of the category, as well as the NAME of the parent category.
I know how to get the item_table data, plus the categoryName through an INNER JOIN. But can I use the same query to get the categoryParent's name?
If not, what would be the mist efficient way to do it? The rest of the code is in C++.
SELECT item_table.item_name, c1.name AS CatName, c2.name AS ParentCatName
FROM item_table join category_table c1 on item_table.categoryID=c1.categoryID
LEFT OUTER JOIN category_table c2 ON c2.categoryID = c1.categoryParentID
SQL Fiddle: here

T4 POCO. Foreign Key Relationships (List<T> or T?)

I created a T4 template for our POCO objects using SMO to grab the object details from SQL Server. Right now I'm trying to determine how to determine the datatype of the navigation properties. My main issue is how to determine if it should be T or List<T>.
I'm not using EF or Linq to SQL.
Any ideas on what I should be checking to accurately determine the datatype?
Depending on which version of SQL you're using, you can use the INFORMATION_SCHEMA to get just about everything you need to build out your POCOs. The following is from http://searchcode.com/codesearch/view/15361587. It lists all tables and columns along with many attributes including whether the column is a foreign key.
SELECT
--TBL.TABLE_SCHEMA,
TBL.TABLE_TYPE,
COL.TABLE_NAME,
COL.ORDINAL_POSITION,
COL.COLUMN_NAME,
COL.DATA_TYPE,
COL.IS_NULLABLE,
ISNULL(COL.CHARACTER_MAXIMUM_LENGTH,-1) AS MAXIMUM_LENGTH,
--COL.TABLE_CATALOG,
(CASE KEYUSG.CONSTRAINT_TYPE WHEN 'PRIMARY KEY' THEN 'YES' ELSE 'NO' END) PRIMARY_KEY,
(CASE KEYUSG.CONSTRAINT_TYPE WHEN 'FOREIGN KEY' THEN 'YES' ELSE 'NO' END) FOREIGN_KEY,
FK.FOREIGN_TALBE,
FK.FOREIGN_COLUMN,
KEYUSG.CONSTRAINT_NAME
FROM
INFORMATION_SCHEMA.COLUMNS COL
JOIN
INFORMATION_SCHEMA.TABLES TBL
ON
COL.TABLE_NAME=TBL.TABLE_NAME
LEFT JOIN
(
SELECT
USG.CONSTRAINT_NAME,
USG.TABLE_NAME,
USG.COLUMN_NAME,
CONST.CONSTRAINT_TYPE
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE USG
JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS CONST
ON
USG.TABLE_NAME=CONST.TABLE_NAME
AND
USG.CONSTRAINT_NAME = CONST.CONSTRAINT_NAME
)
AS KEYUSG
ON
COL.TABLE_NAME=KEYUSG.TABLE_NAME
AND
COL.COLUMN_NAME=KEYUSG.COLUMN_NAME
---FOREIGHTKEYS
LEFT OUTER JOIN
(
SELECT
USAGE.TABLE_NAME,
USAGE.COLUMN_NAME,
UNI_USAGE.TABLE_NAME FOREIGN_TALBE,
UNI_USAGE.COLUMN_NAME FOREIGN_COLUMN,
CONST.CONSTRAINT_NAME,
UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS CONST
JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE USAGE
ON
USAGE.CONSTRAINT_NAME=CONST.CONSTRAINT_NAME
JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE UNI_USAGE
ON
UNI_USAGE.CONSTRAINT_NAME=CONST.UNIQUE_CONSTRAINT_NAME
)
AS FK
ON
FK.TABLE_NAME=COL.TABLE_NAME
AND
FK.COLUMN_NAME = COL.COLUMN_NAME
AND
KEYUSG.CONSTRAINT_NAME=FK.CONSTRAINT_NAME
What I was looking for is a way to determine the cardinality of a foreign key. I believe it can be done by checking the uniqueness of the primary key column(s), however, we've opted to hard code the navigation properties ourselves without having to worry about this as well as a auto-generating a name for the property.

How to write a DQL select statement to search some, but not all the entities in a single table inheritance table

So I have 3 entities within one table. I need to be able to search 2 out of the 3 entities in one select statement, but I'm not sure how to do this.
Use the INSTANCE OF operator in your dql query like this (where User is your base class):
$em->createQuery('
SELECT u
FROM Entity\User u
WHERE (u INSTANCE OF Entity\Manager OR u INSTANCE OF Entity\Customer)
');
Doctrine translates this in the sql query in a WHERE user.type = '...' condition.
See here for more details on the dql query syntax.
The answer for multiple instances actually doesn't work. You would have to do something like this to check for multiple instances.
$classes = ['Entity\Manager', 'Entity\Customer'];
$qb = $this->createQueryBuilder('u');
->where('u.id > 10') //an arbitrary condition, to show it can be combined with multiple instances tests
->andWhere("u INSTANCE OF ('" . implode("','", $classes) . "')");
As commented by flu, if you want to retrieve some entities from different instances with a QueryBuilder instead of a DQL query, you can use an array as parameter:
$qb = $this->createQueryBuilder('u');
->where('u.id > 10') //an arbitrary condition, to show it can be combined with multiple instances tests
->andWhere('u INSTANCE OF :classes')
->setParameter('classes', ['Entity\Manager', 'Entity\Customer'])
;

Doctrine2 - use fulltext and MyIsam

I am building an app in Symfony2, using Doctrine2 with mysql. I would like to use a fulltext search. I can't find much on how to implement this - right now I'm stuck on how to set the table engine to myisam.
It seems that it's not possible to set the table type using annotations. Also, if I did it manually by running an "ALTER TABLE" query, I'm not sure if Doctrine2 will continue to work properly - does it depend on the InnoDB foreign keys?
Is there a better place to ask these questions?
INTRODUCTION
Doctrine2 uses InnoDB which supports Foreign Keys used in Doctrine associations. But as MyISAM does not support this yet, you can not use MyISAM to manage Doctrine Entities.
On the other side, MySQL v5.6, currently in development, will bring the support of InnoDB FTS and so will enable the Full-Text search in InnoDB tables.
SOLUTIONS
So there are two solutions :
Using the MySQL v5.6 at your own risks and hacking a bit Doctrine to implement a MATCH AGAINST method : link in french... (I could translate if needed but there still are bugs and I would not recommend this solution)
As described by quickshifti, creating a MyISAM table with fulltext index just to perform the search on. As Doctrine2 allows native SQL requests and as you can map this request to an entity (details here).
EXAMPLE FOR THE 2nd SOLUTION
Consider the following tables :
table 'user' : InnoDB [id, name, email]
table 'search_user : MyISAM [user_id, name -> FULLTEXT]
Then you just have to write a search request with a JOIN and mapping (in a repository) :
<?php
public function searchUser($string) {
// 1. Mapping
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Acme\DefaultBundle\Entity\User', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'name', 'name');
$rsm->addFieldResult('u', 'email', 'email');
// 2. Native SQL
$sql = 'SELECT u.id, u.name FROM search_user AS s JOIN user AS u ON s.user_id = u.id WHERE MATCH(s.name) AGAINST($string IN BOOLEAN MODE)> 0;
// 3. Run the query
$query = $this->_em->createNativeQuery($sql, $rsm);
// 4. Get the results as Entities !
$results = $query->getResult();
return $results;
}
?>
But the FULLTEXT index needs to stay up-to-date. Instead of using a cron task, you can add triggers (INSERT, UPDATE and DELETE) like this :
CREATE TRIGGER trigger_insert_search_user
AFTER INSERT ON user
FOR EACH ROW
INSERT INTO search_user SET user_id=NEW.id, name=NEW.name;
CREATE TRIGGER trigger_update_search_user
AFTER UPDATE ON user
FOR EACH ROW
UPDATE search_user SET name=name WHERE user_id=OLD.id;
CREATE TRIGGER trigger_delete_search_user
AFTER DELETE ON user
FOR EACH ROW
DELETE FROM search_user WHERE user_id=OLD.id;
So that your search_user table will always get the last changes.
Of course, this is just an example, I wanted to keep it simple, and I know this query could be done with a LIKE.
Doctrine ditched the fulltext Searchable feature from v1 on the move to Doctrine2. You will likely have to roll your own support for a fulltext search in Doctrine2.
I'm considering using migrations to generate the tables themselves, running the search queries w/ the native SQL query option to get sets of ids that refer to tables managed by Doctrine, then using said sets of ids to hydrate records normally through Doctrine.
Will probly cron something periodic to update the fulltext tables.