cycle / orm Goto Github PK
View Code? Open in Web Editor NEWPHP DataMapper, ORM
Home Page: https://cycle-orm.dev
License: MIT License
PHP DataMapper, ORM
Home Page: https://cycle-orm.dev
License: MIT License
This case need for object activity logging
I do not know this is by design or not, but I think it is a strange behavior.
This is my use case:
I have an entity, and I would like to check this entity exists or not in the database. A simplified example:
class CustomerRepository
{
public function exists($entity)
{
/** @var \Cycle\ORM\Select $select */
$select = $this->select();
// .. adding conditions based on primary keys
return $this->fetchOne() !== null;
}
}
After calling fetchOne
my $entity
instance is overridden with the result of fetchOne
During the development in PHPStorm it was detected problem with usage Cycle\ORM\Select
IDE can't work correctly with annotation $this for defined methods like where, andWhere, orderBy, etc:
private function someQuery(string $fieldVal): Select
{
$repository->select()
->where('field', 'like', $fieldVal);
}
This code will be highlighted as wrong with error message like "Return value expected to be '\Cycle\ORM\Select'. '$this' returned"
It breaks auto-completion and hinting.
It works correctly with annotation self
Example of usage:
$repository->select()->subquery([
'alias' => function(QueryBuilder $qb){
$qb->from($tableName)->columns('field1', 'field2');
}
]);
$repository->select()->subquery(function(QueryBuilder $qb){
$qb->from($tableName)->columns('field1', 'field2');
});
$repository->select()->subquery(function(QueryBuilder $qb) use($anotherSelect){
$qb->addSelect($anotherSelect);
});
$repository->select()->with([
'load' => function($qb){
$qb->subquery(<...>);
}
]);
Need to be done:
if ($this->getPrimary($entity) === null) {
if in my table primary key === string not uuid?
now I try to do like this
/** @Cycle\Column(type = "primary", typecast = "string") */
public $contract_number;
but get error
Cycle\ORM\Exception\ParserException: Unable to parse incoming row: Unable to typecast `contract_number`
I need to update HasMany and ManyToMany relations via set of ids, instead of loading entities that exists in database.
For example:
Child table
Id | Parent id | field |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | null | 5 |
$parent->children->sync([1,3]);
$parent->save();
Child table
Id | Parent id | field |
---|---|---|
1 | 1 | 1 |
2 | null | 2 |
3 | 1 | 5 |
ORM should generate 2 update queries for nullable hasMany relations and 1 update and 1 delete query for not nullable hasMany relations and ManyToMany relations.
UPDATE child SET parent_id = null
WHERE id IN (SELECT unnest(?) EXCEPT
SELECT child.id FROM child WHERE child.parent_id=?);
DELETE FROM child
WHERE id IN (SELECT unnest(?) EXCEPT
SELECT child.id FROM child WHERE child.parent_id=?);
UPDATE child SET parent_id = ?
WHERE child.id IN ?;
My classes definition:
** @Entity */
class User
{
/** @Column(type="primary") */
public $id;
}
/** @Entity */
class CustomUser extends User
{
/** @Column(type="string") */
public $email;
}
DI container configuration
$container = new Container();
$container->setDefinitions([ User::class => CustomUser::class ]);
Finding entity with class defined in DI container
$definitions = $container->getDefinitions();
$definition = $definitions[User::class];
// $definition is equal ['class' => 'path\to\CustomUser']
$entity = $orm->getRepository($definition['class'])->findOne([...]);
Now I try to get class of $entity
get_class($entity);
I expecting to get CustomUser but got User
Would be interesting to see how it will process Cycle codebase.
ORM Version: 1.0.3
$database = $ormFactory->database('example');
$database->execute('SHOW TABLES');
All OK
Argument 1 passed to Spiral\Database\Driver\Driver::bindParameters() must be an instance of Spiral\Database\Statement, instance of Doctrine\DBAL\Driver\PDOStatement given, called in .../vendor/spiral/database/src/Driver/Driver.php on line 275
I'm still trying to understand the cause of the problem. Maybe I'm doing something wrong =))))
Something like:
$users = $orm->getRepository(User::class)->select();
$batchSelect = new BatchSelect($users, new IterateOverLastPK());
foreach ($batchSelect as $u) {
// each batch of users has it's own heap
}
Are there any plans to support mongodb?
I think that you can follow the PSR-12, which should soon become stable: https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md#3-declare-statements-namespace-and-import-statements
<?php declare(strict_types=1);
/**
* Spiral Framework.
*
* @license MIT
* @author Anton Titov (Wolfy-J)
*/
namespace Cycle\ORM;
<?php
/**
* Spiral Framework.
*
* @license MIT
* @author Anton Titov (Wolfy-J)
*/
declare(strict_types=1);
namespace Cycle\ORM;
Is there any opportunities for filtering columns rather than select()->buildQuery()->columns()
?
I make some investigation and found that this behaviour can be implemented via implementation of LoaderInterface and so on.
Am I right or in this library exists other way to do what I want?
I want this behaviour:
class TestModel
{
/** @Column(type="string")*/
public $field1;
/** @Column(type="string")*/
public $field2;
/** @Column(type="string")*/
public $field3;
public function __construct($field1, $field2, $field3)
{
$this->field1 = $field1;
$this->field2 = $field2;
$this->field3 = $field3;
}
}
class TestCase
{
public function testSelectFields()
{
$t = new Transaction($orm)->persist((new TestModel('1', '2', '3')))
$t->run();
$result = $orm->getRepository(TestModel::class)->select()->columns(['field1', 'field2'])->fetchOne();
$this->assertEquals('1', $result->field1);
$this->assertEquals('2', $result->field2);
$this->assertNull($result->field3);
}
}
It would be nice to be able to set a Constrain
when using the ->load()
method
Try to add php 7.4 property typing to any of the Entity examples from docs and persist it with db, you will get that exception.
For the reference see also doctrine issue and corresponding PR. As far as I see the issue is partially resolved, see this one.
Not sure whether the issue in Doctrine was only for id (i.e. primary keys), but here we have the issue for any typed field in Entity.
How to create translatable entity field ?
Currently, this is the only thing which strictly couples the domain layer to the ORM. Can be achieved by adding CollectionFactory and invoking it in a relation initialization. Need proper support for pivot collections and collection data extraction.
$select->load('comments', ['load' => new PublicCmments()])
Now it works so that the new Scope (Constraint) is added to a default global Scope.
It would be very cool to be able to replace or disable a default Scope
Objective: To adapt the cycle to the existing solutions (Symfony, Laravel, ะต.g.)
The easiest implementation:
class MyDatabaseManager extends Spiral\Database\DatabaseManager
{
protected function makeDatabase(DatabasePartial $database): Database
{
return new Database (
$database->getName(),
$database->getPrefix(),
// In this place we can create our own driver using the existing connection in the framework, like:
// DoctrineMySQLDriver::fromPdo($this->symfony->connection($database->getName())->getPdo())
}
}
class DoctrineMySQLDriver extends MySQLDriver { ... }
But such an implementation is impossible, we cannot reuse the existing connection due to the presence of the final classes in the code.
DatabaseManager doesn't even have an interface so we can completely rewrite it, and the code uses impl: https://github.com/cycle/orm/blob/master/src/Factory.php#L42
Proposal:
interface DatabaseManagerInterface
{
public function getDatabases(): iterable;
public function database(string $database = null): Database;
public function addDatabase(Database $database);
}
final
keyword.What is currently done:
What needs to be done:
I would like to insert an entity with a primary key which already set.
albertborsos/yii2-ddd@d902852#diff-ae9027ddfeba092d21397ff138998d33R35
When the insert runs it overrides the primary key.
Which is a problem when I would like to migrate an old database to a new structure, but with the old primary keys.
I tried to override the nextPrimaryKey
method in the Mapper
class, but I cannot reach the current value of the entity in the Mapper.
Hi. If I want use some custom types of Postgres? For example "geometry" (postgis).
Try this?
class Uuid implements ValueInterface
{
/** @var UuidBody */
private $uuid;
/**
* @return string
*/
public function rawValue(): string
{
return $this->uuid->getBytes();
}
...
Need addCommand method in transaction. Possibly add ability to automatically link to parent context (some user friendly simplification?). Need ability to expose column name resolution for update/delete queries (see resolveAlias of QueryBuilder, split query builder?).
Constrain is not a good name for a thing since it is a verb. I think it should "constraint".
Hi. Help me with column wrapper.
I wanna use Postgis in my project with Laravel 6.x
I've created column wrapper for Point (Geometry, srid 4326) type
<?php declare(strict_types=1);
namespace App\Domain\ColumnWrappers;
use Spiral\Database\DatabaseInterface;
class Point
{
/**
* @var \Phaza\LaravelPostgis\Geometries\Point
*/
private $point;
/**
* @return string
*/
public function __toString(): string
{
return $this->point->__toString();
}
/**
* @param $lat
* @param $lng
* @param null $alt
* @return Point
*/
public static function create($lat, $lng, $alt = null): Point
{
$point = new static();
$point->point = new \Phaza\LaravelPostgis\Geometries\Point($lat, $lng, $alt);
return $point;
}
/**
* @param string $value
* @param DatabaseInterface $db
* @return Point
*/
public static function typecast($value, DatabaseInterface $db): Point
{
$point = new static();
$point->point = \Phaza\LaravelPostgis\Geometries\Point::fromString((string)$value);
return $point;
}
}
then add in model
/** @Cycle\Column(type="string", typecast="Point") */
protected $location;
in DB stored data looks like
0101000020E61000001EE0490B97B53D40603B18B14FF64D40
column type === geography(Point, 4326)
But I see error every time
Unable to parse incoming row: Unable to typecast location
This is schema dump
Cycle\ORM\Schema {#549
-aliases: array:3 [
"App\Domain\Models\ORM\Poi" => "poi"
"App\Domain\Models\ORM\PoiGeosetting" => "poiGeosetting"
"App\Domain\Models\ORM\PoiPrice" => "poiPrice"
]
-schema: array:3 [
"poi" => array:13 [
1 => "App\Domain\Models\ORM\Poi"
2 => "Cycle\ORM\Mapper\Mapper"
3 => "Cycle\ORM\Select\Source"
4 => "Cycle\ORM\Select\Repository"
5 => "default"
6 => "poi"
7 => "contract_number"
8 => array:1 [
0 => "contract_number"
]
9 => array:18 [
"contract_number" => "contract_number"
"contract_name" => "contract_name"
"status" => "status"
"country_code" => "country_code"
"region_code" => "region_code"
"secession_gpn" => "secession_gpn"
"belongs_to" => "belongs_to"
"name" => "name"
"partner" => "partner"
"brand" => "brand"
"own_type" => "own_type"
"latitude" => "latitude"
"longitude" => "longitude"
"type" => "type"
"location_type" => "location_type"
"time_zone" => "time_zone"
"updated_at" => "updated_at"
"balloon_type" => "balloon_type"
]
10 => array:2 [
"geosettings" => array:4 [
0 => 10
1 => "poiGeosetting"
3 => 10
2 => array:4 [
30 => true
31 => false
33 => "contract_number"
32 => "poi_contract_number"
]
]
"prices" => array:4 [
0 => 11
1 => "poiPrice"
3 => 10
2 => array:5 [
30 => true
31 => false
41 => []
33 => "contract_number"
32 => "poi_contract_number"
]
]
]
12 => null
13 => array:4 [
"region_code" => "int"
"latitude" => "float"
"longitude" => "float"
"updated_at" => "datetime"
]
14 => []
]
"poiGeosetting" => array:13 [
1 => "App\Domain\Models\ORM\PoiGeosetting"
2 => "Cycle\ORM\Mapper\Mapper"
3 => "Cycle\ORM\Select\Source"
4 => "Cycle\ORM\Select\Repository"
5 => "default"
6 => "poi_geo_settings"
7 => "poi_contract_number"
8 => array:1 [
0 => "poi_contract_number"
]
9 => array:5 [
"poi_contract_number" => "poi_contract_number"
"small_radius" => "small_radius"
"large_radius" => "large_radius"
"max_detour" => "max_detour"
"location" => "location"
]
10 => []
12 => null
13 => array:4 [
"small_radius" => "int"
"large_radius" => "int"
"max_detour" => "int"
"location" => array:2 [
0 => "\App\Domain\ColumnWrappers\Point"
1 => "typecast"
]
]
14 => []
]
"poiPrice" => array:13 [
1 => "App\Domain\Models\ORM\PoiPrice"
2 => "Cycle\ORM\Mapper\Mapper"
3 => "Cycle\ORM\Select\Source"
4 => "Cycle\ORM\Select\Repository"
5 => "default"
6 => "poi_prices"
7 => "id"
8 => array:1 [
0 => "id"
]
9 => array:8 [
"id" => "id"
"poi_contract_number" => "poi_contract_number"
"fuel_code" => "fuel_code"
"price" => "price"
"currency" => "currency"
"currency_code" => "currency_code"
"date_from" => "date_from"
"date_to" => "date_to"
]
10 => []
12 => null
13 => array:5 [
"id" => "int"
"price" => "float"
"currency_code" => "int"
"date_from" => "datetime"
"date_to" => "datetime"
]
14 => []
]
]
}
Simple mapper modification to issue different command set for queue update and queue delete with version check.
Sounds like the distro was updated and this dependency is not available anymore.
It would be a nice feature to write code like this:
// grid filtering conditions
$select->andFilterWhere('code', 'like', $entity->code);
$select->andFilterWhere('name', 'like', $entity->name);
instead of this:
// grid filtering conditions
if ($entity->code !== null) {
$select->andWhere('code', 'like', $entity->code);
}
if ($entity->name !== null) {
$select->andWhere('name', 'like', $entity->name);
}
I tried to implement it, but I do not really understand yet how it works.
I recently used the ORM Cycle to make my task easier. But when I create 2 entities that have relationships in different folders, I get an error. The error says that
"Cannot complete the target` relations`.`city` relation (not found or invalid) "
But when I put all the entities in one folder, I didn't get any errors.
This is my Venue entity code in the App\Domain\Venue\Entities folder :
<?php
namespace App\Domain\Venue\Entities;
use Cycle\Annotated\Annotation\Column;
use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Table;
use Cycle\Annotated\Annotation\Relation\BelongsTo;
use Cycle\Annotated\Annotation\Relation\HasMany;
use Cycle\Annotated\Annotation\Table\Index;
use App\Domain\Region\Entities\City;
/**
* @Entity(table = "venue", database = "main")
* @Table(
* indexes = {
* @Index(columns = {"name"}),
* @Index(columns = {"published"}),
* @Index(columns = {"latitude"}),
* @Index(columns = {"longitude"}),
* }
* )
*/
class Venue {
/** @Column(type = "primary", name = "ID") */
protected $id;
//....
/**
* @HasMany(target = "VenueImage", innerKey = "id", outerKey = "venueId")
*/
protected $images;
/**
* @BelongsTo(target = "City", innerKey = "cityId", outerKey = "id")
*/
protected $city;
//....
}
This is my City entity code in the App\Domain\Region\Entities folder :
<?php
namespace App\Domain\Region\Entities;
use Cycle\Annotated\Annotation\Column;
use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Table;
use Cycle\Annotated\Annotation\Relation\BelongsTo;
use Cycle\Annotated\Annotation\Table\Index;
/**
* @Entity(table = "city", database = "region")
* @Table(
* indexes = {
* @Index(columns = {"name"}, unique = true),
* @Index(columns = {"governingDistrictID"})
* }
* )
*/
class City {
/** @Column(type = "primary", name = "ID") */
protected $id;
//...
}
I think that types should be defined in the schema, not in Entity. In this case, we can allow for more flexible behavior (have several different types in the same entity depending on the repository source). In that case, when we need to guarantee the types in entity, we can use the PHP 7.4+ properties typing.
class Entity
{
/** @column(type=string) */
protected $some;
}
new Schema([
'user' => [Schema::COLUMNS => ['some']]
]);
class Entity
{
protected $some;
}
new Schema([
'user' => [Schema::COLUMNS => ['some' => 'string']]
]);
Based on this benchmark https://github.com/adrianmiu/forked-php-orm-benchmark the ORM is pretty slow currently compared to competitors.
The ideal optimizations based on cached nodes and generated mappers looks like:
Need to abstract Node Parsers into its own factory so:
The persist most likely can't be optimized a lot due to the nature of the graph traversal algorithm.
run cycle:sync and got:
[Cycle\Schema\Exception\RelationException]
Unable to resolve last
.info
relation target (not found or invalid)
Entities example:
/** @Entity */
class Post
{
/** @Column(type="primary") */
public $id;
}
/** @Entity */
class Article extends Post
{
/** @Column(type="string") */
public $articleTitle;
}
/** @Entity */
class Last
{
/** @HasOne(target="Article") */
public $info;
}
If I add fields that are generated by relationships to the crosstab Entity class:
/** @Entity */
class PostTag
{
/** @Column(type="primary") */
private ?int $id = null;
private ?int $post_id = null;
private ?int $tag_id = null;
}
And when adding fixtures i will bind both entities:
$post->addTag($tag);
$tag->addPost($post);
If i remove $tag->addPost($post);
or fields $post_id
and $tag_id
then will be good
Relations in entities:
Entity Tag https://github.com/roxblnfk/yii-demo/blob/bug/many-to-many/src/Blog/Entity/Post.php#L90
Entity Post https://github.com/roxblnfk/yii-demo/blob/bug/many-to-many/src/Blog/Entity/Tag.php#L45
php 7.4.1
git clone https://github.com/roxblnfk/yii-demo.git
and git checkout bug/many-to-many
config/params.php
(you can skip this step)composer install
vendor/bin/yii serve
or start your web-serverGenerator\SyncTables::class
in the config/params.php
file. In this case you should create migrations to sync changes of entities with DBvendor/bin/yii fixture/add 20
to create random dataFollowed https://github.com/cycle/docs/blob/master/advanced/single-table-inheritance.md, created two Entities.
run cycle:sync and got Duplicate entity error.
Hi. Can I use your ORM with Laravel/Lumen framework?
Let's say we have 2 entities, which will look like the next ones:
<?php
declare(strict_types=1);
namespace App;
use Cycle\Annotated\Annotation as Cycle;
/** @Cycle\Entity() */
class A
{
/** @Cycle\Column(type="int", name="a_key") */
public $aKey;
}
<?php
declare(strict_types=1);
namespace App;
use Cycle\Annotated\Annotation as Cycle;
/** @Cycle\Entity() */
class B
{
/** @Cycle\Column(type="int", name="b_key") */
public $bKey;
}
Entity A refers to entity B using $aKey
and $bKey
inner/outer keys. Let's add this relation to entity A using property names:
// somewhere inside of entity A
/**
* @Cycle\Relation\RefersTo(target="B", innerKey="aKey", outerKey="bKey")
* @var B
*/
public $b;
This code will fail on insert because (at least in PostgreSQL) the generated SQL is trying to add both a_key
and aKey
columns:
INSERT INTO "a" (..., "a_key", ..., "aKey") VALUES (..., NULL, ..., <aKey value>)
a_key
appears to be null, and theaKey
, which is unknown to the db scheme contains the required value.
As a fix right now, the referTo
relation should be declared as below:
// somewhere inside of entity A
/**
* @Cycle\Relation\RefersTo(target="B", innerKey="a_key", outerKey="bKey")
* @var B
*/
public $b;
The SQL will be correct now:
INSERT INTO "a_named_b_props" (..., "a_key", ...) VALUES (..., <aKey value>, ...)
Meanwhile, using a_key
and b_key
as inner/outer keys:
// somewhere inside of entity A
/**
* @Cycle\Relation\RefersTo(target="B", innerKey="a_key", outerKey="b_key")
* @var B
*/
public $b;
leads to a Cycle\Schema\Exception\SchemaException
Unable to compute relation `a`.'b'
Package zendframework/zend-stdlib is abandoned, you should avoid using it. Use laminas/laminas-stdlib instead.
Package zendframework/zend-hydrator is abandoned, you should avoid using it. Use laminas/laminas-hydrator instead.
cycle\orm
requires zendframework/zend-hydrator
, while zendframework/zend-hydrator
requires zendframework/zend-stdlib
.
These two packages are officially abandoned.
When creating an entity, too many requests are generated as a result the speed of work is slow.
entity has only one dependency hasOne
$user = new User('[email protected]');
$tr = new Transaction($orm);
$tr->persist($user);
$tr->run();
[2020-01-28T17:15:29.240219+02:00] database.INFO: Begin transaction [] []
[2020-01-28T17:15:29.244725+02:00] database.INFO: SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'; {"elapsed":0.0007541179656982422} []
[2020-01-28T17:15:29.246982+02:00] database.INFO: SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = 'f_data' AND table_type = 'BASE TABLE' AND table_name = 'user' {"elapsed":0.002146005630493164} []
[2020-01-28T17:15:29.248863+02:00] database.INFO: SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = 'f_data' AND table_type = 'BASE TABLE' AND table_name = 'user' {"elapsed":0.0007250308990478516} []
[2020-01-28T17:15:29.249161+02:00] database.INFO: SELECT oid FROM pg_class WHERE relname = 'user' {"elapsed":0.0002269744873046875} []
[2020-01-28T17:15:29.260026+02:00] database.INFO: SELECT * FROM information_schema.columns JOIN pg_type ON (pg_type.typname = columns.udt_name) WHERE table_name = 'user' {"elapsed":0.0107879638671875} []
[2020-01-28T17:15:29.262229+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{3}' {"elapsed":0.0008358955383300781} []
[2020-01-28T17:15:29.262498+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{4}' {"elapsed":0.00017714500427246094} []
[2020-01-28T17:15:29.262705+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{5}' {"elapsed":0.000125885009765625} []
[2020-01-28T17:15:29.262953+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{6}' {"elapsed":0.00016999244689941406} []
[2020-01-28T17:15:29.263203+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{7}' {"elapsed":0.0001709461212158203} []
[2020-01-28T17:15:29.263461+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{8}' {"elapsed":0.00017905235290527344} []
[2020-01-28T17:15:29.263653+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{9}' {"elapsed":0.00011396408081054688} []
[2020-01-28T17:15:29.263835+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{12}' {"elapsed":9.799003601074219e-5} []
[2020-01-28T17:15:29.263956+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{13}' {"elapsed":5.793571472167969e-5} []
[2020-01-28T17:15:29.264073+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{15}' {"elapsed":5.412101745605469e-5} []
[2020-01-28T17:15:29.264202+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{2}' {"elapsed":5.2928924560546875e-5} []
[2020-01-28T17:15:29.264315+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{3}' {"elapsed":5.1975250244140625e-5} []
[2020-01-28T17:15:29.264422+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{4}' {"elapsed":5.316734313964844e-5} []
[2020-01-28T17:15:29.264529+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{5}' {"elapsed":5.078315734863281e-5} []
[2020-01-28T17:15:29.264627+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{6}' {"elapsed":5.0067901611328125e-5} []
[2020-01-28T17:15:29.264723+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{7}' {"elapsed":4.887580871582031e-5} []
[2020-01-28T17:15:29.264828+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{9}' {"elapsed":5.0067901611328125e-5} []
[2020-01-28T17:15:29.264927+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{11}' {"elapsed":4.9114227294921875e-5} []
[2020-01-28T17:15:29.265030+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{15}' {"elapsed":4.9114227294921875e-5} []
[2020-01-28T17:15:29.265143+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{3}' {"elapsed":5.0067901611328125e-5} []
[2020-01-28T17:15:29.265239+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{4}' {"elapsed":4.887580871582031e-5} []
[2020-01-28T17:15:29.265335+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{5}' {"elapsed":4.887580871582031e-5} []
[2020-01-28T17:15:29.265430+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{6}' {"elapsed":4.9114227294921875e-5} []
[2020-01-28T17:15:29.265526+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{7}' {"elapsed":4.887580871582031e-5} []
[2020-01-28T17:15:29.265621+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{8}' {"elapsed":4.9114227294921875e-5} []
[2020-01-28T17:15:29.265721+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{9}' {"elapsed":5.2928924560546875e-5} []
[2020-01-28T17:15:29.265829+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{12}' {"elapsed":5.1021575927734375e-5} []
[2020-01-28T17:15:29.265926+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{13}' {"elapsed":4.9114227294921875e-5} []
[2020-01-28T17:15:29.266038+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 17802 AND contype = 'c' AND conkey = '{15}' {"elapsed":5.412101745605469e-5} []
[2020-01-28T17:15:29.267647+02:00] database.INFO: SELECT * FROM pg_indexes WHERE schemaname = 'f_data' AND tablename = 'user' {"elapsed":0.0015099048614501953} []
[2020-01-28T17:15:29.267911+02:00] database.INFO: SELECT contype FROM pg_constraint WHERE conname = 'user_pkey' {"elapsed":0.0001780986785888672} []
[2020-01-28T17:15:29.582315+02:00] database.INFO: SELECT tc.constraint_name, tc.table_name, kcu.column_name, rc.update_rule, rc.delete_rule, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name JOIN information_schema.referential_constraints AS rc ON rc.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name = 'user' {"elapsed":0.31433701515197754} []
[2020-01-28T17:15:29.583371+02:00] database.INFO: SELECT * FROM pg_indexes WHERE schemaname = 'f_data' AND tablename = 'user' {"elapsed":0.0006330013275146484} []
[2020-01-28T17:15:29.583596+02:00] database.INFO: SELECT contype FROM pg_constraint WHERE conname = 'user_pkey' {"elapsed":0.00014495849609375} []
[2020-01-28T17:15:29.584425+02:00] database.INFO: INSERT INTO "f_data"."user" ("id", "role_id", "email", "new_email", "username", "password", "auth_key", "api_key", "share_key", "share_track", "ban_time", "ban_reason", "login_ip", "login_time", "create_ip", "status", "create_time", "update_time") VALUES (724, 5, '[email protected]', NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, '2020-01-28T17:15:29+02:00', '2020-01-28T17:15:29+02:00') RETURNING "id" {"elapsed":0.00036716461181640625} []
[2020-01-28T17:15:29.585477+02:00] database.INFO: SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = 'f_data' AND table_type = 'BASE TABLE' AND table_name = 'user_profile' {"elapsed":0.0005700588226318359} []
[2020-01-28T17:15:29.586146+02:00] database.INFO: SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = 'f_data' AND table_type = 'BASE TABLE' AND table_name = 'user_profile' {"elapsed":0.0005431175231933594} []
[2020-01-28T17:15:29.586443+02:00] database.INFO: SELECT oid FROM pg_class WHERE relname = 'user_profile' {"elapsed":0.0002357959747314453} []
[2020-01-28T17:15:29.591299+02:00] database.INFO: SELECT * FROM information_schema.columns JOIN pg_type ON (pg_type.typname = columns.udt_name) WHERE table_name = 'user_profile' {"elapsed":0.004782915115356445} []
[2020-01-28T17:15:29.591772+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{3}' {"elapsed":0.00021910667419433594} []
[2020-01-28T17:15:29.592009+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{4}' {"elapsed":0.00015306472778320312} []
[2020-01-28T17:15:29.592246+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{5}' {"elapsed":0.00015807151794433594} []
[2020-01-28T17:15:29.592483+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{6}' {"elapsed":0.0001590251922607422} []
[2020-01-28T17:15:29.592717+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{7}' {"elapsed":0.0001571178436279297} []
[2020-01-28T17:15:29.592919+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{8}' {"elapsed":0.0001239776611328125} []
[2020-01-28T17:15:29.593079+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{3}' {"elapsed":7.891654968261719e-5} []
[2020-01-28T17:15:29.593216+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{4}' {"elapsed":7.510185241699219e-5} []
[2020-01-28T17:15:29.593349+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{5}' {"elapsed":7.605552673339844e-5} []
[2020-01-28T17:15:29.593485+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{6}' {"elapsed":7.486343383789062e-5} []
[2020-01-28T17:15:29.593595+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{7}' {"elapsed":5.888938903808594e-5} []
[2020-01-28T17:15:29.593696+02:00] database.INFO: SELECT conname, pg_get_constraintdef(oid) as consrc FROM pg_constraint WHERE conrelid = 16628 AND contype = 'c' AND conkey = '{8}' {"elapsed":5.1975250244140625e-5} []
[2020-01-28T17:15:29.594383+02:00] database.INFO: SELECT * FROM pg_indexes WHERE schemaname = 'f_data' AND tablename = 'user_profile' {"elapsed":0.0006208419799804688} []
[2020-01-28T17:15:29.594575+02:00] database.INFO: SELECT contype FROM pg_constraint WHERE conname = 'user_profile_pkey' {"elapsed":0.00014495849609375} []
[2020-01-28T17:15:29.903750+02:00] database.INFO: SELECT tc.constraint_name, tc.table_name, kcu.column_name, rc.update_rule, rc.delete_rule, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name JOIN information_schema.referential_constraints AS rc ON rc.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name = 'user_profile' {"elapsed":0.30912208557128906} []
[2020-01-28T17:15:29.904518+02:00] database.INFO: SELECT * FROM pg_indexes WHERE schemaname = 'f_data' AND tablename = 'user_profile' {"elapsed":0.0006289482116699219} []
[2020-01-28T17:15:29.904743+02:00] database.INFO: SELECT contype FROM pg_constraint WHERE conname = 'user_profile_pkey' {"elapsed":0.00014519691467285156} []
[2020-01-28T17:15:29.905470+02:00] database.INFO: INSERT INTO "f_data"."user_profile" ("fname", "lname", "phone", "mobile", "email", "lang", "create_time", "update_time", "user_id") VALUES (NULL, NULL, NULL, NULL, NULL, NULL, '2020-01-28T17:15:29+02:00', '2020-01-28T17:15:29+02:00', 724) RETURNING "id" {"elapsed":0.0005609989166259766} []
[2020-01-28T17:15:29.905599+02:00] database.INFO: Commit transaction [] []
What could be the problem ?
The DatabaseManager
class uses the LoggerTrait
trait
He has the setLogger($logger)
method
If i want to log SQL queries then i call setLogger()
method on DatabaseManager
object
But all existing drivers do not recieve LoggerInterface
because drivers were created when created the DatabaseManager
instance
It would be great if instead of this code:
foreach ($dbal->getDrivers() as $driver) {
$driver->setLogger($this->logger);
}
... i could use this:
$dbal->setLogger($this->logger);
Example of generated SQL:
SELECT table1_alias.* FROM
(
SELECT id, field1, field2 from table1
WHERE field1=%val1
LIMIT 10 OFFSET 20
) as table1_alias
LEFT JOIN (
SELECT field3, field4, table1_id FROM table2
WHERE field3=%val2
LIMIT 10 OFFSET 20
) as table2_alias ON table1_alias.id = table2_alias.table1_id
$select->load('many_to_many.has_many')
failed with Undefined node 'has_many'
exception.
$select->load('[email protected]_many')
failed with Undefined relation 'pivotTestModel'.'has_many'
exception.
This problem in AbstractLoader#251 in $node->getNode($relation)
function.
In debug $node
has this structure:
Here my models
/**
* @Entity
*/
class ManyToManyTestModel extends BaseTestModel
{
public function __construct(array $data = [])
{
$this->many_to_many_inverse = new PivotedCollection();
$this->has_many = new ArrayCollection();
parent::__construct($data);
}
/**
* @ManyToMany(though=PivotTestModel::class, target=HasManyTestModel::class)
*/
public $many_to_many_inverse;
/** @HasMany(target=RelatedModel::class, nullable=true) */
public $has_many;
}
/**
* @Entity
*/
class HasManyTestModel extends BaseTestModel
{
public function __construct(array $data = [])
{
$this->many_to_many = new PivotedCollection();
parent::__construct($data);
}
/**
* @ManyToMany(target=ManyToManyTestModel::class, though=PivotTestModel::class)
*/
public $many_to_many;
public $has_many_inverse;
}
/**
* @Entity
*/
class PivotTestModel
{
/** @Column(type="primary") */
public $id;
}
/**
* @Entity
*/
class RelatedModel extends BaseTestModel
{
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.