Doctrine: Is it possible to INDEX BY a related field? - doctrine-orm

I have a Doctrine model (Assignment), which has a many-to-one relationship with another model (Region). Assignments are owned by users (with each user having only one assignment per region at a time), and I am trying to use indexBy to have the user's array of assignments be keyed by the ID of the assignment's region. However, I only get standard 0..n numeric keys.
When I try to run a DQL query like SELECT am, reg, user FROM Assignment am INDEX BY [...] JOIN am.region reg JOIN am.user user WHERE user.id = ?1, none of these values for INDEX BY work:
region (Error: Invalid PathExpression. Must be a StateFieldPathExpression.)
region_id (Error: Class ...\Assignment has no field or association named region_id)
region.id (Error: Expected end of string, got '.')
Is this possible? If not, then what would be a convenient way to access a User's assignment on a region without indexBy?

I was dealing with the same problem today. Fortunately I've found the solution : )
First of all, you have to declare additional column in ORM mapping:
Abdulklarapl\My\EntityA:
type: entity
table: entityA
manyToOne:
entityB:
targetEntity: EntityB
joinColumn:
name: label_id
referencedColumnName: id
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
value:
type: text
entityB_id:
type: integer
lifecycleCallbacks: { }
notice that I've declared entityB_id as a field + I've configured manyToOne relation by adding a joinColumn clause
so now you can use entityB_id as scalar value
$doctrine->getEntityManager()->createQueryBuilder()
->select('c')
->from('AbdulklaraplMyBundle:EntityA', 'c', 'c.entityB_id')
->getQuery()->getResult();
it will return assoc array
[
c.entityB_id: {
id: "",
value: ""
entityB_id: ""
}
]
you can also use AbstractQuery::HYDRATE_ARRAY as a argument for getResult() - it will return assoc array with array instead the objects

If you need to INDEX BY a foreign key e.g. "region_id" it is possible in your mapping:
/**
* #ORM\OneToMany(targetEntity="Region", mappedBy="user", indexBy="region_id")
*/
protected $regions;
The feature was added here.
Unfortunately it does not seem to be documented that you have to use the name of the column of the foreign key itself.
Working with Indexed Associations

Import the Query class (optional):
use \Doctrine\ORM\Query;
Create the query:
$query = $this->data->em->createQuery('
SELECT a
FROM Assignment a
INDEX BY a.reg //to set array custom key
WHERE a.user = :user');
$query->setParameter('user', 3); //user with id 3
//set the hidration mode in order to work with read-only arrays
$assignments = $query->getResult(Query::HYDRATE_ARRAY);

Related

go and dynamo get data from table where field in list and field is not null / field is not empty

Do you know how to make a get or delete call with a "field in list" (example: " type in ('first','primero','base')")? (In dynamo-goLang, please.)
The following code works:
input := &dynamodb.GetItemInput{
TableName: aws.String(myTableName),
Key: map[string]dynamodb.AttributeValue{
"id": {
S: aws.String(positionId),
},
"type": {
S: aws.String('first'),
},
},
}
But I would like to make a get data from a list of types (where type is in list), or where type is not null or is not empty.
Example in sql of what I intend to do in dynamo-goLang:
SELECT * FROM myTableName WHERE id = positionId AND type IN ('first','primero','base');
AND
SELECT * FROM myTableName WHERE id = positionId AND type IS NOT NULL;
To get multiple results where you specify the partition key and you want to filter by the sort key, you want to use Query instead of GetItem.
Some resources with examples as my golang is a little rusty:
https://github.com/markuscraig/dynamodb-examples/blob/master/go/movies_query_year_title.go
https://medium.com/#spiritualcoder/step-by-step-guide-to-use-dynamodb-with-golang-cd374f159a64

Dql query to find all the attributes

I need a full dql query to find all the attributes (single and Repeating) for the documents. I haven't tried any query.
You can select all attributes for object type using this query:
SELECT DISTINCT attr_name, attr_type, attr_repeating, attr_length FROM dm_type WHERE name = 'dm_document' ORDER BY attr_name
Where you replace dm_document by your target object type name and
attr_name contains attribute name
attr_type defines attribute type (0 - Boolean, 1 - Integer, 2 - String, 3 - ID, 4 - Time, 5 - Double)
attr_repeating indicates whether the attribute is repeating or not
attr_length defines size of String based attributes
If you want only attributes for that object type and not ones inherited from super type then you can select them by this query:
SELECT DISTINCT r_object_id, attr_name, attr_type, attr_repeating, attr_length, i_position, start_pos FROM dm_type WHERE name = 'dm_document' AND i_position < -start_pos ORDER BY attr_name ENABLE(ROW_BASED)
You could also use a "describe " to get information.
You should also investigate the views underneath if you're querying from non-dql application.

Doctrine2 - Annotations: eager load (join) vs. nullable column (ManyToOne)

I have this:
/**
* #ManyToOne(targetEntity="TblCity",fetch="EAGER",cascade={"persist"})
* #JoinColumn(name="tblCity",referencedColumnName="Id")
*/
and it creates the correct JOIN for table tblCity in sql and TblCity entity is plugged in my parent entity - aka "Eager-Load"
Pseudo result:
PersonEntity: {
Id: 1
...
CityEntity: {
Id: 1
...
}
}
but, this column NEEDS to be nullable
(if it runs into a "missing" foreign id it complains about missing proxy files for TblCity).
So it has to look like this:
/**
* #Column(nullable=true)
* #ManyToOne(targetEntity="TblCity",fetch="EAGER",cascade={"persist"})
* #JoinColumn(name="tblCity",referencedColumnName="Id")
*/
and poff there goes the "Eager-Load"
The generated sql is missing the JOIN of table tblCity and the column contains only the id and not the entity for TblCity
Pseudo result:
PersonEntity: {
Id: 1
...
CityEntity: 1 (as integer)
}
What am I doing wrong?
PS: I CAN'T use createQuery or such things, so please no solutions involving that
The doctrine #JoinColumn annotation has an optiobal attribute nullable which defaults to true. Read more on this here in the documentation: 21.2.15. #JoinColumn
So the proper way to declare nullable for the join column is:
#JoinColumn(name="tblCity",referencedColumnName="Id", nullable=true)
But nullable is true by default so you don't really need it...
My guess would be that your #Column annotation is overruling the whole #ManyToOne annotation in your case. That is why you get only an id and no TblCity entity.

Doctrine DQL returns multiple types of entities

I have three entities: HandsetSubscription, Handset and Subscription.
The yaml of HandsetSubscription is:
App\SoBundle\Entity\HandsetSubscription:
type: entity
table: handset_subscription
manyToOne:
handset:
targetEntity: Handset
subscription:
targetEntity: Subscription
id:
id:
type: integer
generator: { strategy: AUTO }
options: { unsigned: true }
fields:
amount:
type: integer
nullable: false
options: { default: 0, unsigned: true }
discount:
type: integer
nullable: false
options: { default: 0, unsigned: true }
The query:
SELECT hs,s,h
FROM \App\SoBundle\Entity\HandsetSubscription hs
JOIN \App\SoBundle\Entity\Subscription s with s.id = hs.subscription
AND s.mins = 150
AND s.mb = 250
AND s.sms = 150
JOIN \App\SoBundle\Entity\Handset h with h.id = hs.handset ​
These are the class names of the entries retrieved:
App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Subscription
Proxies\__CG__\App\SoBundle\Entity\Handset
App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Handset
App\SoBundle\Entity\HandsetSubscription
Proxies\__CG__\App\SoBundle\Entity\Handset
…
I would expect to get only HandsetSubscription entities back. Why am I getting proxies of Subscription and Handset too?
By adding fetch eager to the handset and subscription mappings and removing handset and subscription from the SELECT statement in the query I would get only HandsetSubscription but I would like to do this through fetch joins, as stated in the manual (http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#joins).
UPDATE
Quote from the link posted above:
Fetch join of the address:
<?php
$query = $em->createQuery("SELECT u, a FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
$users = $query->getResult();
When Doctrine hydrates a query with fetch-join it returns the class in the FROM clause on the root level of the result array. In the previous example an array of User instances is returned and the address of each user is fetched and hydrated into the User#address variable. If you access the address Doctrine does not need to lazy load the association with another query.
Big thanks goes to veonik from the #doctrine irc channel for solving this.
Instead of joining with the fully qualified names of the entities you should join with the association. So the query becomes:
SELECT hs,s,h
FROM \App\SoBundle\Entity\HandsetSubscription hs
JOIN hs.subscription s with s.id = hs.subscription
AND s.mins = 150
AND s.mb = 250
AND s.sms = 150
JOIN hs.handset h with h.id = hs.handset

How to get the default value of a column of MS Access Database using C++?

This is the sql script I used to create a table in MS Access Database.
CREATE TABLE Contracts (
id int NULL DEFAULT 0,
sex varchar(255) DEFAULT 'female' NOT NULL
)
Now I want to programmatically get the default value of the field: "sex", I know it's 'female' but I don't know how to get it using C++ ADO interface.
Below is a snippet of my code:
m_pRecordset->Fields->get_Item(vIntegerType, &pvObject);
bstrColName = pvObject->GetName();
dtype = pvObject->GetType();
attr = pvObject->GetAttributes();
I can give you idea how to achieve it..
GetAttributes() method will not give you default value of the field but it will give you info about whether field is autoincrement ,system field or fixed - variable size field.
Check out for method GetDefaultValue() of the field that will do what you want.