I need to have my database schema information stored in the database.
I already have a table called db_entity which stores the entity name, namespace and other options.
Related to this table I need to have a table entity_attributes which will have the entity_id,attribute_name,attribute_type,required etc.
Creating the schema structure is easy but inserting all the fields from all my entites in the db would be a tedious work.
Is there any way I can create a script that will parse all my entities annotations, allowing me to create all the fields into my database table?
The best would be to write a similar command to doctrine:schema:update that would update my table schema.
Thank you.
The doctrine metadata class http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.Mapping.ClassMetadataInfo.html contains a public property that could be exactly what you need:
222: /**
223: * READ-ONLY: The field mappings of the class.
224: * Keys are field names and values are mapping definitions.
225: *
226: * The mapping definition array has the following values:
227: *
228: * - <b>fieldName</b> (string)
229: * The name of the field in the Entity.
230: *
231: * - <b>type</b> (string)
232: * The type name of the mapped field. Can be one of Doctrine's mapping types
233: * or a custom mapping type.
234: *
235: * - <b>columnName</b> (string, optional)
236: * The column name. Optional. Defaults to the field name.
237: *
238: * - <b>length</b> (integer, optional)
239: * The database length of the column. Optional. Default value taken from
240: * the type.
241: *
242: * - <b>id</b> (boolean, optional)
243: * Marks the field as the primary key of the entity. Multiple fields of an
244: * entity can have the id attribute, forming a composite key.
245: *
246: * - <b>nullable</b> (boolean, optional)
247: * Whether the column is nullable. Defaults to FALSE.
248: *
249: * - <b>columnDefinition</b> (string, optional, schema-only)
250: * The SQL fragment that is used when generating the DDL for the column.
251: *
252: * - <b>precision</b> (integer, optional, schema-only)
253: * The precision of a decimal column. Only valid if the column type is decimal.
254: *
255: * - <b>scale</b> (integer, optional, schema-only)
256: * The scale of a decimal column. Only valid if the column type is decimal.
257: *
258: * - <b>unique (string, optional, schema-only)</b>
259: * Whether a unique constraint should be generated for the column.
260: *
261: * #var array
262: */
263: public $fieldMappings = array();
Related
In our scenario we have a (multivalued) category field on JCR:node and we want to query all nodes that do not have a current selection. In the JCR viewer the fields value is [] but I can't find any query to select nodes with this condition. We have tries:
SELECT * FROM [mgnl:page] as p WHERE p.[categories]=''
or
SELECT * FROM [mgnl:page] as p WHERE p.[categories]=[]
or
SELECT * FROM [mgnl:page] as p WHERE p.[categories] is null
But they aren't working or don't select the proper result. How can we write a query selecting these nodes?
From the JSR 283:
5.10.3 Value Length
The length of a value in a single-value property, as defined in ยง3.6.7 Length of a Value, is returned by long Property.getLength()
Similarly, the method long[] Property.getLengths() is used to get an array of the lengths of all the values of a multi-value property.
From the JavaDocs:
/**
* Returns an array holding the lengths of the values of this (multi-value)
* property in bytes where each is individually calculated as described in
* {#link #getLength()}.
* <p>
* Returns a <code>-1</code> in the appropriate position if the
* implementation cannot determine the length of a value.
*
* #return an array of lengths
* #throws ValueFormatException if this property is single-valued.
* #throws RepositoryException if another error occurs.
*/
public long[] getLengths() throws ValueFormatException, RepositoryException;
Unfortunately, this does not make it clear what the result of LENGTH([multivaluedProperty)] is in a SQL2 query.
Though, after some manual testing, it seems that the LENGTH operand returns some number smaller than 0. Therefore, you could try
select * from [nt:base] where LENGTH([multivaluedProperty]) < 0
Let me know whether this works for you :)
Let's say I have two entities Bus and People with a relation OneToMany between them.
Bus can hold a maximum of 10 persons.
How to create a constraint to control this?
For example:
* #MyAssert\ParentMaxChild(max=10)
* #ORM\ManyToOne(targetEntity="Webface\CharacterBundle\Entity\Bus", inversedBy="wac")
* #ORM\JoinColumn(name="bus_id", referencedColumnName="id", nullable=false)
private $bus;
Use the Count constraint.
In your Bus class, add the constraint in the Person annotation:
/**
* ... Rest of the annotation ...
* #Assert\Count(
* max = "10",
* maxMessage = "Bus can hold a maximum of 10 persons."
* )
*/
protected $persons;
Note that you can specify a min parameter and the according message.
I have database table with 7 rows, I'am trying to fetch those rows with findAll function
$machine_current_counter_repo = $this->getDoctrine()->getRepository('DummyMonitorBundle:MachineCurrentCounter');
$counters = $machine_current_counter_repo->findAll();
The result is 7 rows, but all rows contain data from the first row.
Here is database table entity.
And table structure:
`machine_current_counter` (
`machine_id` tinyint(3) unsigned NOT NULL,
`counter_value` int(10) unsigned NOT NULL,
`time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`machine_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What could cause this problem?
Ps. Entity is generated from database so by default first column setup was this (not sure why type was "boolean", but I changes it to integer, still that didn't solved the problem):
/**
* #var boolean
*
* #ORM\Column(name="machine_id", type="boolean")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $machineId;
#ORM\Id means values of this field MUST be unique. With the boolean type they can be unique only in 2 or less row (because boolean has only 2 values - 0 and 1).
I think you have logical mistake, and must simply change type of field to integer. Like that:
/**
* #var integer
*
* #ORM\Column(name="machine_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $machineId;
Then update your schema by ./app/console doctrine:schema:update then recreate data into table.
I have three tables:
game columns: id | name (eg. 1 | Halo)
own columns: id | type_id | type_name (eg. 1 | 1 | on wishlist)
user columns: id | name (eg. 1 | Tomek)
Now what I have is a ManyToMany connection between those tables:
User (table user_own)
/**
* #ORM\ManyToMany(targetEntity="Own")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
Own (table own_game)
/**
* #ORM\ManyToMany(targetEntity="Game")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")}
* )
*/
My query:
public function getOwned() {
return $this->getEntityManager()
->createQuery('
SELECT u, o, g FROM AcmeGoBundle:User u
JOIN u.owners o
JOIN u.games g
')
->getResult();
}
I can retrieve games owned by particular user, but I can't connect type of ownership. How can I do this?
To crate ManyToMany with additional column with some data you need to create this by hand.
Doctrine ManyToMany relation crates a join table with id's of joined entities. So you need to create by your own Entity named ex. UserOwns with OneToMany relation to User and another OneToMany relation Own. Then you can add additional field with your data inside.
Check that question: Doctrine2: Best way to handle many-to-many with extra columns in reference table
Under what circumstances will the following line create two records instead of one?
The line only runs once, I traced the program to make sure.
createIndcsfResult.token = indcsfService.createIndcsf(indCSF2);
Standard Service
/**
* Returns the item corresponding to the value specified for the primary key.
*
* Add authorization or any logical checks for secure access to your data
*
*
* #return stdClass
*/
public function createIndcsf($item) {
$stmt = mysqli_prepare($this->connection, "INSERT INTO $this->tablename (indcsf_name, indcsf_yourcsf_id, indcsf_status) VALUES (?, ?, ?)");
$this->throwExceptionOnError();
mysqli_stmt_bind_param($stmt, 'sis', $item->indcsf_name, $item->indcsf_yourcsf_id, $item->indcsf_status);
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$autoid = mysqli_stmt_insert_id($stmt);
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $autoid;
}