Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Cycle ORM bridge for integrating with any framework

License

NotificationsYou must be signed in to change notification settings

wakebit/cycle-bridge

Repository files navigation

This package provides a set of Symfony commands, classes for integrationCycle ORM with any framework. We are supporting integration both versions of the ORM.If you want to integrate this to Laravel we already have aseparated package which uses this bridge.

Requirements

  • PHP >= 8.0
  • Cycle ORM 1 or 2 (branchesv1.x andv2.x accordingly)

Installation

  1. Install the package via composer:
composer require wakebit/cycle-bridge

Example of usage with PHP-DI

  1. Declare configconfig/config.php and fill database credentials:
<?phpdeclare(strict_types=1);usefunctionDI\env;return [// Environment variables'debug'         =>env('APP_DEBUG','true'),// Database'db.connection' =>env('DB_CONNECTION','mysql'),'db.host'       =>env('DB_HOST','localhost'),'db.database'   =>env('DB_DATABASE',''),'db.username'   =>env('DB_USERNAME',''),'db.password'   =>env('DB_PASSWORD',''),];
  1. Declare ORM configconfig/cycle.php. Dont forget to set up correct paths to entities path, migrations path:
<?phpuseCycle\Database\Config\DatabaseConfig;useCycle\Migrations\Config\MigrationConfig;usePsr\Container\ContainerInterface;useSpiral\Tokenizer\Config\TokenizerConfig;useWakebit\CycleBridge\Schema\Config\SchemaConfig;usefunctionDI\create;/** * @psalm-suppress UndefinedClass * @psalm-suppress MixedArgument */return ['database' =>staticfunction (ContainerInterface$container):DatabaseConfig {returnnewDatabaseConfig(['default' =>'default','databases' => ['default' => ['connection' =>$container->get('config')['db.connection'],                ],            ],'connections' => ['sqlite' =>new \Cycle\Database\Config\SQLiteDriverConfig(                    connection:new \Cycle\Database\Config\SQLite\MemoryConnectionConfig(),                    queryCache:true,                ),'mysql' =>new \Cycle\Database\Config\MySQLDriverConfig(                    connection:new \Cycle\Database\Config\MySQL\TcpConnectionConfig(                        database:$container->get('config')['db.database'],                        host:$container->get('config')['db.host'],                        port:3306,                        user:$container->get('config')['db.username'],                        password:$container->get('config')['db.password'],                    ),                    queryCache:true,                ),'postgres' =>new \Cycle\Database\Config\PostgresDriverConfig(                    connection:new \Cycle\Database\Config\Postgres\TcpConnectionConfig(                        database:$container->get('config')['db.database'],                        host:$container->get('config')['db.host'],                        port:5432,                        user:$container->get('config')['db.username'],                        password:$container->get('config')['db.password'],                    ),                    schema:'public',                    queryCache:true,                ),'sqlServer' =>new \Cycle\Database\Config\SQLServerDriverConfig(                    connection:new \Cycle\Database\Config\SQLServer\TcpConnectionConfig(                        database:$container->get('config')['db.database'],                        host:$container->get('config')['db.host'],                        port:1433,                        user:$container->get('config')['db.username'],                        password:$container->get('config')['db.password'],                    ),                    queryCache:true,                ),            ],        ]);    },'orm' => ['schema' =>staticfunction ():SchemaConfig {returnnewSchemaConfig();        },'tokenizer' =>staticfunction ():TokenizerConfig {returnnewTokenizerConfig(['directories' => [__DIR__ .'/../src/Entity',                ],'exclude' => [                ],            ]);        },    ],'migrations' =>staticfunction (ContainerInterface$container):MigrationConfig {returnnewMigrationConfig(['directory' =>__DIR__ .'/../resources/migrations','table'     =>'migrations','safe'      =>filter_var($container->get('config')['debug'],FILTER_VALIDATE_BOOLEAN),        ]);    },];
  1. Declare dependencies for PHP-DI containerconfig/container.php:
<?phpdeclare(strict_types=1);useCycle\Database\Config\DatabaseConfig;useCycle\Database\DatabaseInterface;useCycle\Database\DatabaseManager;useCycle\Database\DatabaseProviderInterface;useCycle\Migrations\Config\MigrationConfig;useCycle\Migrations\FileRepository;useCycle\Migrations\RepositoryInterface;useCycle\ORM\EntityManager;useCycle\ORM\EntityManagerInterface;useCycle\ORM\Factory;useCycle\ORM\FactoryInterface;useCycle\ORM\ORM;useCycle\ORM\ORMInterface;useCycle\ORM\SchemaInterface;usePsr\Container\ContainerInterface;useSpiral\Tokenizer\ClassesInterface;useSpiral\Tokenizer\ClassLocator;useSpiral\Tokenizer\Config\TokenizerConfig;useSpiral\Tokenizer\Tokenizer;useWakebit\CycleBridge\Contracts\Schema\CacheManagerInterface;useWakebit\CycleBridge\Contracts\Schema\CompilerInterface;useWakebit\CycleBridge\Contracts\Schema\GeneratorQueueInterface;useWakebit\CycleBridge\Schema\CacheManager;useWakebit\CycleBridge\Schema\Compiler;useWakebit\CycleBridge\Schema\Config\SchemaConfig;useWakebit\CycleBridge\Schema\GeneratorQueue;useWakebit\CycleBridge\Schema\SchemaFactory;usefunctionDI\autowire;usefunctionDI\factory;usefunctionDI\get;return ['config'                          =>require'config.php','cycle'                           =>require'cycle.php',    DatabaseConfig::class             =>staticfunction (ContainerInterface$container):DatabaseConfig {return$container->get('cycle')['database'];    },    SchemaConfig::class               =>staticfunction (ContainerInterface$container):SchemaConfig {return$container->get('cycle')['orm']['schema'];    },    TokenizerConfig::class            =>staticfunction (ContainerInterface$container):TokenizerConfig {return$container->get('cycle')['orm']['tokenizer'];    },    MigrationConfig::class            =>staticfunction (ContainerInterface$container):MigrationConfig {return$container->get('cycle')['migrations'];    },    DatabaseProviderInterface::class =>autowire(DatabaseManager::class),    DatabaseInterface::class         =>staticfunction (ContainerInterface$container):DatabaseInterface {return$container->get(DatabaseProviderInterface::class)->database();    },    DatabaseManager::class           =>get(DatabaseProviderInterface::class),    ClassLocator::class             =>get(ClassesInterface::class),    ClassesInterface::class         =>staticfunction (ContainerInterface$container):ClassesInterface {return$container->get(Tokenizer::class)->classLocator();    },    FactoryInterface::class         =>autowire(Factory::class),    CacheManagerInterface::class    =>staticfunction ():CacheManagerInterface {// Here you need to pass PSR-16 compatible cache pool. See example with cache file below.// Packages: league/flysystem, cache/filesystem-adapter$filesystemAdapter =new \League\Flysystem\Adapter\Local(__DIR__ .'/../var/cache');$filesystem =new \League\Flysystem\Filesystem($filesystemAdapter);$pool =new \Cache\Adapter\Filesystem\FilesystemCachePool($filesystem);returnnewCacheManager($pool);    },    GeneratorQueueInterface::class  =>autowire(GeneratorQueue::class),    CompilerInterface::class        =>autowire(Compiler::class),    SchemaInterface::class          =>factory([SchemaFactory::class,'create']),    ORMInterface::class =>staticfunction (ContainerInterface$container):ORMInterface {returnnewORM($container->get(FactoryInterface::class),$container->get(SchemaInterface::class));    },    EntityManagerInterface::class   =>autowire(EntityManager::class),    RepositoryInterface::class      =>autowire(FileRepository::class),];
  1. Now, you need to load a dependencies array created in the step above to PHP-DI. After you are free to use dependencies, write your code.

Let's look at quick example. Define entity:

<?phpdeclare(strict_types=1);namespaceApp\Entity;useCycle\Annotated\Annotation\Entity;useCycle\Annotated\Annotation\Column;#[Entity]class User{    #[Column(type:'primary')]privateint$id;    #[Column(type:'string')]privatestring$name;publicfunctiongetId():int    {return$this->id;    }publicfunctiongetName():string    {return$this->name;    }publicfunctionsetName(string$name):void    {$this->name =$name;    }}

You can take DBAL, ORM and EntityManager from the container. Quick example of usage:

<?phpdeclare(strict_types=1);namespaceApp;useCycle\Database\DatabaseProviderInterface;useCycle\ORM\EntityManagerInterface;useCycle\ORM\ORMInterface;finalclass SomeClass{publicfunction__construct(privateDatabaseProviderInterface$dbal,privateEntityManagerInterface$em,privateORMInterface$orm,    ) {    }publicfunction__invoke()    {// DBAL$tables =$this->dbal->database()->getTables();$tableNames =array_map(fn (\Cycle\Database\TableInterface$table):string =>$table->getName(),$tables);dump($tableNames);// Create, modify, delete entities using Transaction$user =new \App\Entity\User();$user->setName("Hello World");$this->em->persist($user);$this->em->run();dump($user);// ORM$repository =$this->orm->getRepository(\App\Entity\User::class);$users =$repository->findAll();dump($users);$user =$repository->findByPK(1);dump($user);    }}

See more onthe official Cycle ORM documentation.

Console commands

Working with ORM schema

CommandDescriptionOptionsSymfony command class FQN
cycle:schema:migrateGenerate ORM schema migrations---run: Automatically run generated migration.
--v: Verbose output.
\Wakebit\CycleBridge\Console\Command\Schema\MigrateCommand::class
cycle:schema:cacheCompile and cache ORM schema\Wakebit\CycleBridge\Console\Command\Schema\CacheCommand::class
cycle:schema:clearClear cached schema (schema will be generated every request now)\Wakebit\CycleBridge\Console\Command\Schema\ClearCommand::class
cycle:schema:syncSync ORM schema with database without intermediate migration (risk operation!)\Wakebit\CycleBridge\Console\Command\Schema\SyncCommand::class
cycle:schema:renderRender available CycleORM schemas.---no-color: Display output without colors.\Wakebit\CycleBridge\Console\Command\Schema\RenderCommand::class

Database migrations

CommandDescriptionOptionsSymfony command class FQN
cycle:migrate:initInitialize migrator: create a table for migrations\Wakebit\CycleBridge\Console\Command\Migrate\InitCommand::class
cycle:migrateRun all outstanding migrations---one: Execute only one (first) migration.
---force: Force the operation to run when in production.
\Wakebit\CycleBridge\Console\Command\Migrate\MigrateCommand::class
cycle:migrate:rollbackRollback the last migration---all: Rollback all executed migrations.
---force: Force the operation to run when in production.
\Wakebit\CycleBridge\Console\Command\Migrate\RollbackCommand::class
cycle:migrate:replayReplay (down, up) one or multiple migrations.---all: Replay all migrations.\Wakebit\CycleBridge\Console\Command\Migrate\ReplayCommand::class
cycle:migrate:statusGet a list of available migrations\Wakebit\CycleBridge\Console\Command\Migrate\StatusCommand::class

Database commands

CommandDescriptionOptionsSymfony command class FQN
cycle:db:listGet list of available databases, their tables and records count---database: Database name\Wakebit\CycleBridge\Console\Command\Database\ListCommand::class
cycle:db:table <table>Describe table schema of specific database---database: Database name\Wakebit\CycleBridge\Console\Command\Database\TableCommand::class

Writing functional tests

If you are using memory database (SQLite) you can just run migrations in thesetUp method of the your test calling the console commandcycle:migrate.For another databases followthis instruction and drop all tables in thetearDown method.

Advanced

Manually defined ORM schema

If you want to use a manually defined ORM schema you can define it in thecycle.phporm.schema.map config key:

useWakebit\CycleBridge\Schema\Config\SchemaConfig;return [// ...'orm' => ['schema' =>staticfunction ():SchemaConfig {returnnewSchemaConfig(['map' =>require__DIR__ .'/../orm_schema.php',            ]);        },    ]// ...]

Manually defined schema should be presented as array. It will be passed to\Cycle\ORM\Schema constructor. See morehere.

Custom schema compilation pipeline

You can redefine the ORM schema compilation generators in thecycle.phporm.schema.generators config key:

useWakebit\CycleBridge\Schema\Config\SchemaConfig;return [// ...'orm' => ['schema' =>staticfunction ():SchemaConfig {returnnewSchemaConfig(['generators' => ['index' => [],'render' => [                        \Cycle\Schema\Generator\ResetTables::class,// re-declared table schemas (remove columns)                        \Cycle\Schema\Generator\GenerateRelations::class,// generate entity relations                        \Cycle\Schema\Generator\ValidateEntities::class,// make sure all entity schemas are correct                        \Cycle\Schema\Generator\RenderTables::class,// declare table schemas                        \Cycle\Schema\Generator\RenderRelations::class,// declare relation keys and indexes                    ],'postprocess' => [                        \Cycle\Schema\Generator\GenerateTypecast::class,// typecast non string columns                    ],                ]            ]);        },    ]// ...]

Classes will be resolved by DI container. Default pipeline you can seehere.

Default collection factory

You can specify predefined or your own collection factory in container definition:

FactoryInterface::class =>staticfunction (ContainerInterface$container):FactoryInterface {returnnew \Cycle\ORM\Factory(        dbal:$container->get(DatabaseProviderInterface::class),        defaultCollectionFactory:new \Cycle\ORM\Collection\DoctrineCollectionFactory(),    );},

Credits

About

Cycle ORM bridge for integrating with any framework

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp