Naming a relation in Doctrine 2 ORM? - symfony

How can i set the name of the foreign key (edit: not the name of the attribute itself) for the many-to-one relation "region" using YAML?
SWA\TestBundle\Entity\Province:
type: entity
table: province
uniqueConstraints:
UNIQUE_PROVINCE_CODE:
columns: code
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
code:
type: integer
name:
type: string
length: 255
short_name:
type: string
length: 2
manyToOne:
region:
targetEntity: Region
inversedBy: provinces

Look at the getCreateConstraintSQL method in the AbstractPlatform class to see how the name of the foreign key is chosen (line 1088).
It is taken directly from the constraint name. Influencing constraint name will influence the foreign key name.
As a workaround you could drop the constraint and re-create it with a new name in a doctrine migration.

Due to #JakubZalas answer, I had taken a look to the code in Github, and have seen that changing the framework code for doing what you want is really easy.
If you check the folder where AbstractPlatform class is, you'll see that there is a ForeignKeyConstraint class. In it you'll see it inherits from AbstractAsset.
Now AbstractAsset class has a _generateIdentifierName method. If you check this method in github you'll see that it has a commented part that does just what you want. You just uncomment this part, comment the actual active part, change the $prefix parameter to $postfix and you're done. The constraint name will be generated using the table and column names with a corresponding postfix.
The AbstractAsset.php file is the the this folder: Symfony/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema
I tried in my project ant it worked fine.
One final information: at least for my project the commented part I mention above is only in github, not in the file at my local machine.

Related

Realm - Creating and Updating Objects With other Keys apart from primary key

I'm using Mongodb Realm.
I know it is possible to 'createOrUpdate' in realm by using the primary key i.e If the primary key doesn't exists create a new object, If it does update the object.
Something like
realm.write(() => {
// Create a book object
realm.create('Book', {id: 1, date: '12-12-2020', price: 35});
// It will update the price but won't create a new object since the id is the same
realm.create('Book', {id: 1, date: '12-12-2020', price: 55}, 'modified');
});
The realm docs says that
If your model class includes a primary key, you can have Realm
intelligently update or add objects based off of their primary key
values. This is done by passing true as the third argument to the
create method:
this can be found here https://docs.mongodb.com/realm-legacy/docs/javascript/latest/#creating-and-updating-objects-with-primary-keys
NOW, I want to update the Object based on a different field(key) apart from the primary key and On this case it is the date field This is to say that, If the date doesn't exist, create a new object/entry but it it does, just update the price.
How do I do this with realm?

How to modify an already constructed schema

I'm using a third party package that defines a schema like this:
People.schema = new SimpleSchema({
firstName: {
type: String,
optional: false
}
//Many other fields defined...
});
I would like to modify it to have optional: true for the first name without changing the source code for the third party package.
I could use People.schema.pick to get a schema with all of the fields except the firstName, and then combine this with another schema with firstName as optional. But this method would require listing all of the fields in the schema in the pick function, which is tedious.
Is there a better way of accomplishing this?
I can edit the object simple schema creates just like any other object:
People.schema._schema.firstName.optional = true.
To override the field.

Nullable embedded value object with not nullable fields

I created an entity "Person" in Doctrine2, and I added to it an Adress entity, which is a value object (embeddable).
I want to allow a Person creation, without an Address, so I tag my embedded as "nullable = true". But on the other hand, my Address entity, if it exists, SHOULD contains at least some information (like city, zip code, etc...). So it has "nullable = false" attributes.
Address:
type: embeddable
fields:
[...]
city:
type: string
length: 255
nullable: false
Person:
type: entity
table: null
embedded:
address:
class: Address
nullable: true
It seems that the "nullable = true" of the embedded object was not working.
Do you know if it's a normal Doctrine behaviour ?
Do I have to put all my embeddable attributes to nullable = true ?

Is it possible to run an ' HAS ANCESTOR' filter/query on a property that contains a list(Value) of keys

I have a kind client that consists of entities with a property psets containing a list of Key
Using the JSON api psets this would expressed as :
psets = { listValue: [ {keyValue: { path: [...]} },{keyValue: { path: [...]} },... ]}
The KeyValues are made of path = [{ kind: 'project', name: 'projectn' }]
I am trying to run an 'ancestor' query on 'client' using
SELECT * from client where psets HAS ANCESTOR KEY( project, 'project1')
This query returns an error: unsupported property
What is unsupported ?
How can I run an 'HAS ANCESTOR' filter on a list of Keys ?
Please note that according the the DataStore Documentation (Operators and comparisons)
A condition can also test whether one entity has another entity as an ancestor, using the HAS ANCESTOR or HAS DESCENDANT operators. These operators test ancestor relationships between keys. They can operate on __key__, but they can also operate on a key-valued property. For HAS ANCESTOR, the right operand cannot be a property
(emphasis mine)
Datastore only supports the HAS ANCESTOR operator on entity keys (i.e. the special __key__ property), not on regular key values.
A possible workaround would be to explicitly include each of the ancestors as a property in the entity.
So for example, if your psets property contained a key project:project1/foo:2/bar:3, you could maintain a separate psets_ancestors list property that contained project:project1, project:project1/foo:2, and project:project1/foo:2/bar:3. Then you could do equality queries on the psets_ancestors property:
SELECT * FROM client WHERE psets_ancestors = KEY(project, 'project1')
(This comes at the cost of extra index entries and having to maintain the separate list property.)

Objects with multiple key columns in realm.io

I am writing an app using the Realm.io database that will pull data from another, server database. The server database has some tables whose primary keys are composed of more than one field. Right now I can't find a way to specify a multiple column key in realm, since the primaryKey() function only returns a String optional.
This one works:
//index
override static func primaryKey() ->String?
{
return "login"
}
But what I would need looks like this:
//index
override static func primaryKey() ->[String]?
{
return ["key_column1","key_column2"]
}
I can't find anything on the docs on how to do this.
Supplying multiple properties as the primary key isn't possible in Realm. At the moment, you can only specify one.
Could you potentially use the information in those two columns to create a single unique value that you could use instead?
It's not natively supported but there is a decent workaround. You can add another property that holds the compound key and make that property the primary key.
Check out this conversation on github for more details https://github.com/realm/realm-cocoa/issues/1192
You can do this, conceptually, by using hash method drived from two or more fields.
Let's assume that these two fields 'name' and 'lastname' are used as multiple primary keys. Here is a sample pseudo code:
StudentSchema = {
name: 'student',
primaryKey: 'pk',
properties: {
pk: 'string',
name: 'string',
lastname: 'string',
schoolno: 'int'
}
};
...
...
// Create a hash string drived from related fields. Before creating hash combine the fields in order.
myname="Uranus";
mylastname="SUN";
myschoolno=345;
hash_pk = Hash( Concat(myname, mylastname ) ); /* Hash(myname + mylastname) */
// Create a student object
realm.create('student',{pk:hash_pk,name:myname,lastname:mylastname,schoolno: myschoolno});
If ObjectId is necessary then goto Convert string to ObjectID in MongoDB

Resources