Coder Social home page Coder Social logo

schema-builder's People

Contributors

alexndr-novikov avatar butschster avatar evgenybarinov avatar gam6itko avatar jstark518 avatar mrakolice avatar msmakouz avatar rauanmayemir avatar roxblnfk avatar serafimarts avatar stylecibot avatar thenotsoft avatar wolfy-j avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

schema-builder's Issues

Schema compile does not adhere to default database value of null

Description

When compiling a schema, the default database value as configured within the database manager will be used inside of the schema instead of null.

Example with annotated entity:

use Cycle\Annotated\Annotation\Entity;

#[Entity(role: AccountType::class, repository: AccountTypeRepository::class, table: 'account_type')]
class AccountType
{
    #[Column(type: 'tinyInteger', name: 'account_type_id', primary: true, nullable: true)]
    protected ?int $accountTypeId = null;
    // ...
}    

In the above example the "database" entity option is not set, so I expect the schema to have a null value for SchemaInterface::DATABASE instead it uses the default value as configured on the database manager (in my example that would be test).

Schema snippit:

namespace Cycle\ORM\SchemaInterface;

class CompiledSchema
{
    public const LIST = [
        AccountType::class => [
            // ...
            SchemaInterface::MAPPER => 'Cycle\ORM\Mapper\Mapper',
            SchemaInterface::SOURCE => 'Cycle\ORM\Select\Source',
            SchemaInterface::REPOSITORY => AccountTypeRepository::class,
            SchemaInterface::DATABASE => 'test', // <================ should be null not test
            
            // ...
        ],
    ];
}

If I compile the schema during my build step which uses a different database name compared to production I end up with the following error, on production.

Cycle\Database\Exception\DBALException: Unable to create Database, no presets for 'build_2024_abfertgg_db' found

I can resolve this by setting the database to null after the schema has been compiled. But I feel like this is not the expected behavior.
Explicitly setting the entity option "database" to null does not change the outcome.

Versions used:

    "cycle/annotated": "^3.4",
    "cycle/database": "^2.7",
    "cycle/orm": "^2.6",

Two mirrored unique indexes gets generated in pivot table

2 unique indexes gets generated in pivot table

unique(product_category_id, product_id)
unique(product_id, product_category_id)
$this->table('product_product_category')
            ->addColumn('id', 'bigPrimary', [
                'nullable' => false,
                'default'  => null
            ])
            ->addColumn('product_category_id', 'bigInteger', [
                'nullable' => false,
                'default'  => null
            ])
            ->addColumn('product_id', 'bigInteger', [
                'nullable' => false,
                'default'  => null
            ])
            ->addIndex(["product_category_id", "product_id"], [
                'name'   => '0e92fceae82e7e0e91d346a72bf831ae',
                'unique' => true
            ])
            ->addIndex(["product_category_id"], [
                'name'   => 'product_product_category_index_product_category_id_6035f3284ea68',
                'unique' => false
            ])
            ->addIndex(["product_id"], [
                'name'   => 'product_product_category_index_product_id_6035f3284ea79',
                'unique' => false
            ])
            ->addIndex(["product_id", "product_category_id"], [
                'name'   => '642dad4db053452e89cb383adbe9089f',
                'unique' => true
            ])
            ->addForeignKey(["product_category_id"], 'product_categories', ["id"], [
                'name'   => '4c20a9d910d4f5d5ffa685a41db81ccc',
                'delete' => 'CASCADE',
                'update' => 'CASCADE'
            ])
            ->addForeignKey(["product_id"], 'products', ["id"], [
                'name'   => 'product_product_category_foreign_product_id_6035f3284ea75',
                'delete' => 'CASCADE',
                'update' => 'CASCADE'
            ])
            ->setPrimaryKeys(["id"])
            ->create();

Column attributes aren't copied on relations generation

Auto-generated columns don't have the same attributes like in the related source column

see https://discord.com/channels/538114875570913290/988308945045180436/1074709906017501325

#[Cycle\Entity(table: 'country')]
class Country
{
    #[Cycle\Column(type: 'primary' /*, unsigned: true*/)]
    private ?int $id = null;
}
#[Cycle\Entity(table: 'city')]
class City
{
    #[Cycle\Column(type: 'primary')]
    private ?int $id = null;

    #[Cycle\Relation\BelongsTo(target: Country::class, nullable: true)]
    private ?Country $country = null;
}

🐛 Primary keys which are defined by "Table / Primary Key" are ignored

No duplicates 🥲.

  • I have searched for a similar issue in our bug tracker and didn't find any solutions.

What happened?

Entity:

<?php declare(strict_types=1);

namespace App\Core\Entity\Wall;

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\BelongsTo;
use Cycle\Annotated\Annotation\Table;

// #[PrimaryKey(['group_id', 'block_id'])] does not work too
#[Table(primary: new Table\PrimaryKey(['group_id', 'block_id']))]
#[Entity(table: 'wall_block')]
class WallBlock
{
    public function __construct(
        #[BelongsTo(target: Group::class, innerKey: 'group_id')]
        private Group $group,

        #[BelongsTo(target: Block::class, innerKey: 'block_id')]
        private Block $block,
    ) {
    }
}

Error:

Entity `wallBlock` must have defined primary key
Exception trace:
  at /srv/app/vendor/cycle/schema-builder/src/Relation/RelationSchema.php:127
 Cycle\Schema\Relation\RelationSchema->getPrimaryColumns() at /srv/app/vendor/cycle/schema-builder/src/Relation/RelationSchema.php:89
 Cycle\Schema\Relation\RelationSchema->compute() at /srv/app/vendor/cycle/schema-builder/src/Relation/BelongsTo.php:52
 Cycle\Schema\Relation\BelongsTo->compute() at /srv/app/vendor/cycle/schema-builder/src/Generator/GenerateRelations.php:117
 Cycle\Schema\Generator\GenerateRelations->register() at /srv/app/vendor/cycle/schema-builder/src/Generator/GenerateRelations.php:91
 Cycle\Schema\Generator\GenerateRelations->run() at /srv/app/vendor/cycle/schema-builder/src/Compiler.php:57

Version

ORM 2.2.1
PHP 8.2

Exception when using one embedded entity for multiple fields

When using the same embedded entity without a prefix, for example "Money" for the price and total fields, I expect an exception with the message you need to specify a prefix, but now nothing happens and the schema is built with the same fields, and both entities get the same data.

image

Add support for postgres schemas

Было бы здорово добавить поддержку постгресовских схем. Сейчас по умолчанию захардкожена дефолтная public.

Respect @Embedded property order when you generate migration's columns

Entities

/**
 * @Cycle\Entity()
 */
class Post
{
    /**
     * @Cycle\Column(type="primary")
     */
    public int $id;

    /**
     * @Cycle\Relation\Embedded(target="Seo")
     */
    public Seo $seo;

    /**
     * @Cycle\Column(type="primary")
     */
    public DateTimeImmutable $createdAt;
}
/**
 * @Embeddable(columnPrefix="seo_")
 */
class Seo
{
    /**
     * @Cycle\Column(type="string", name="title", nullable=true)
     */
    public ?string $title;

    /**
     * @Cycle\Column(type="string", name="description", nullable=true)
     */
    public ?string $description;

    /**
     * @Cycle\Column(type="string", name="keywords", nullable=true)
     */
    public ?string $keywords;
}

Generated migration

$this->table('posts')
    ->addColumn('id', 'primary', [
        'nullable' => false,
        'default'  => null
    ])
    ->addColumn('created_at', 'primary', [
        'nullable' => false,
        'default'  => null
    ])
    ->addColumn('seo_title', 'string', [
        'nullable' => true,
        'default'  => null,
        'size'     => 255
    ])
    ->addColumn('seo_description', 'string', [
        'nullable' => true,
        'default'  => null,
        'size'     => 255
    ])
    ->addColumn('seo_keywords', 'string', [
        'nullable' => true,
        'default'  => null,
        'size'     => 255
    ])
    ->setPrimaryKeys(["id", "created_at"])
    ->create();

What i want is that created_at should be generated after Seo columns, i.e. in this case after seo_keywords

Generate schema by annotated entities without DB connection

Is it possible generate schema only use info form entity, not to load actual schema from DB?

Problem:
I use "cycle/orm and co" among with symfony. Schema is compiled while cache:clear, cache:clear is run while docker build.
As there is no db connection, this error occur.

[PDOException (7)]
SQLSTATE[08006] [7] could not translate host name "db" to address: Name does not resolve
Exception trace:
at /srv/app/vendor/cycle/database/src/Driver/Driver.php:637
PDO->__construct() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:637
Cycle\Database\Driver\Driver->createPDO() at /srv/app/vendor/cycle/database/src/Driver/Postgres/PostgresDriver.php:213
Cycle\Database\Driver\Postgres\PostgresDriver->createPDO() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:200
Cycle\Database\Driver\Driver->connect() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:653
Cycle\Database\Driver\Driver->getPDO() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:487
Cycle\Database\Driver\Driver->prepare() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:443
Cycle\Database\Driver\Driver->statement() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:457
Cycle\Database\Driver\Driver->statement() at /srv/app/vendor/cycle/database/src/Driver/Driver.php:253
Cycle\Database\Driver\Driver->query() at /srv/app/vendor/cycle/database/src/Driver/Postgres/PostgresHandler.php:71
Cycle\Database\Driver\Postgres\PostgresHandler->hasTable() at /srv/app/vendor/cycle/database/src/Schema/AbstractTable.php:99
Cycle\Database\Schema\AbstractTable->__construct() at /srv/app/vendor/cycle/database/src/Driver/Postgres/PostgresHandler.php:31
Cycle\Database\Driver\Postgres\PostgresHandler->getSchema() at /srv/app/vendor/cycle/database/src/Table.php:88
Cycle\Database\Table->getSchema() at /srv/app/vendor/cycle/schema-builder/src/Registry.php:161
Cycle\Schema\Registry->linkTable() at /srv/app/vendor/cycle/annotated/src/Entities.php:80
Cycle\Annotated\Entities->run() at /srv/app/vendor/cycle/schema-builder/src/Compiler.php:57
Cycle\Schema\Compiler->compile() at /srv/app/package/CycleORMBundle/src/Service/SchemaCompiler.php:26

As a workaround, I do cache:clear at startup time.
But it loads DB, every kubernetes pod get schema from DB at the same time.

Embedded entity's fields conflict with the parent ones (even using columnPrefix)

Let's say we have a parent entity:

<?php

declare(strict_types=1);

namespace App\Database;

use Cycle\Annotated\Annotation;

/** @Annotation\Entity() */
class Parent
{
    /** @Annotation\Column(type="primary") */
    public $id;
    /** @Annotation\Relation\Embedded(target="Embed") */
    public Embed $embed;
}

and an embeddable one:

<?php

declare(strict_types=1);

namespace App\Database;

use Cycle\Annotated\Annotation;

/** @Annotation\Embeddable(columnPrefix="embedded_") */
class Embed
{
    /** @Annotation\Column(type="int") */
    public $id;
    /** @Annotation\Column(type="text") */
    public $data;
}

Cycle fails on making scheme of such relations:

php app.php cycle
Updating ORM schema...  [Cycle\Schema\Exception\FieldException] 
 Field `id` already exists               

I would agree on that if we had no columnPrefix attribute. But the real column name will be equal to embedded_id and this is not a duplicate. There's a tricky hack (which allows you to remain the same DB scheme, but with changes in the class) - rename the property and add the name attribute with the previous value:

<?php

declare(strict_types=1);

namespace App\Database;

use Cycle\Annotated\Annotation;

/** @Annotation\Embeddable(columnPrefix="embedded_") */
class Embed
{
    /** @Annotation\Column(type="int", name="id") */
    public $myRandomIDField;
    /** @Annotation\Column(type="text") */
    public $data;
}

Change column naming case in relations for consistency

Now if entity has relation to another entity with naming like ProductBrand, orm generates column name like productBrand_id.
It would be better if output name was product_brand_id, coz entity properties gets generated with snake case.

Не создаются таблицы с одинаковым именем в разных БД

Есть 2 entity с одинаковым именем класса User, лежат по разным неймспейсам и смотрят в разные БД

1ая Entity user

<?php
declare(strict_types=1);
namespace App\Admin\Database;
use Cycle\Annotated\Annotation as Cycle;
/**
 * @Cycle\Entity(database="admintool", table="users")
 * @Cycle\Table()
 */
class User
{
 /**
 * @Cycle\Column(type="bigPrimary")
 */
 public $id;
/**
 * @Cycle\Column(type="string")
 */
 public $email;
}

2ая Entity user

<?php
declare(strict_types=1);
namespace App\Ugg\Database;
use Cycle\Annotated\Annotation as Cycle;
/**
 * @Cycle\Entity(database="ugg", role="ugg_users", table="users")
 * @Cycle\Table()
 */
class User
{
 /** @Cycle\Column(type="bigPrimary") */
 public $id;
/** @Cycle\Column(type="enum(active,inactive,deleted,unknown)", default="active") */
 public $status;
}

выполняем

php app.php cycle:sync

результат

Detecting schema changes:
• ugg.users: 5 change(s) detected
• admintool.users: 2 change(s) detected

отрабатывает без ошибок, но появится только одна таблица users в БД admintool

Если запустить через миграцию, появится таблица users и в admintool и в ugg БД

php app.php cycle:migrate
php app.php migrate

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.