Skip to content

Commit

Permalink
Add docs for migrations (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Jan 11, 2024
1 parent 755d9fc commit 049c4cb
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 30 deletions.
108 changes: 79 additions & 29 deletions README.md
Expand Up @@ -57,49 +57,99 @@ $dbConfig = new DatabaseConfig(
],
]
);
$database = (new DatabaseManager($dbConfig))->database();
$databaseManager = new DatabaseManager($dbConfig);
$database = $databaseManager->database();
```

More comprehensive examples can be found at
[Cycle Database docs](https://cycle-orm.dev/docs/database-configuration#declare-connection).

### Working with schema
### Working with migrations

In order to keep less dependencies, this package doesn't provide any CLI for working with schema. There are multiple
options to choose from:
This package uses [Cycle Migrations](https://github.com/cycle/migrations) for managing database tables required for
storages. There are 3 tables in total (`yii_rbac_` prefix is used).

- Use migration tool like [Yii DB Migration](https://github.com/yiisoft/yii-db-migration). Migrations are dumped as
plain SQL in `sql/migrations` folder.
- Without migrations, `DbSchemaManager` class can be used. An example of CLI command containing it can be found
[here](examples/Command/RbacCycleInit.php).
- Use plain SQL that is actual at the moment of installing `rbac-db` package (located at the root of `sql` folder).
Items storage:

The structure of plain SQL files:

- `pgsql-up.sql` - apply the changes for PostgreSQL driver.
- `pgsql-down.sql` - revert the changes for PostgreSQL driver.
- `yii_rbac_item`.
- `yii_rbac_item_child`.

Plain SQL assumes using default names for all 3 tables (`yii_rbac_` prefix is used):
Assignments storage:

- `yii_rbac_item`.
- `yii_rbac_assignment`.
- `yii_rbac_item_child`.

`DbSchemaManager` allows to customize table names:
#### Configuring migrator and capsule

```php
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Rbac\Db\DbSchemaManager;

/** @var ConnectionInterface $database */
$schemaManager = new DbSchemaManager(
database: $database,
itemsTable: 'custom_items',
assignmentsTable: 'custom_assignments',
itemsChildrenTable: 'custom_items_children',
);
$schemaManager->ensureTables();
$schemaManager->ensureNoTables(); // Note: All existing data will be erased.
use Cycle\Database\DatabaseManager;
use Cycle\Migrations\Capsule;
use Cycle\Migrations\Config\MigrationConfig;
use Cycle\Migrations\FileRepository;
use Cycle\Migrations\Migrator;

$migrationsSubfolders = ['items', 'assignments'];
$directories = [];
foreach (static::$migrationsSubfolders as $subfolder) {
$directories[] = implode(DIRECTORY_SEPARATOR, [
dirname(__DIR__, 2), // Adjust this if your path is different.
'migrations',
$subfolder,
]);
}

$config = new MigrationConfig([
'directory' => $directories[0],
// "vendorDirectories" are specified because "directory" option doesn't support multiple directories. In the end, it
// makes no difference, because they all will be merged into single array.
'vendorDirectories' => $directories[1] ?? [],
'table' => 'cycle_migration',
'safe' => true,
]);
/** @var DatabaseManager $databaseManager */
$migrator = new Migrator($config, $databaseManager, new FileRepository($config));
$migrator->configure();

$capsule = new Capsule($databaseManager->database());
```

For configuring `$databaseManager`, see [previous section](#configuring-database-connection).

Because item and assignment storages are completely indepedent, migrations are separated as well in order to prevent
creation of unused tables. So, for example, if you only want to use assignment storage, adjust `$migrationsSubfolders`
variable like this:

```php
$migrationsSubfolders = ['assignments'];
```

#### Applying migrations

```php
use Cycle\Migrations\Capsule;
use Cycle\Migrations\Migrator;

/**
* @var Migrator $migrator
* @var Capsule $capsule
*/
while ($migrator->run($capsule) !== null) {
echo "Migration {$migration->getState()->getName()} applied successfully.\n";
}
```

#### Reverting migrations

```php
use Cycle\Migrations\Capsule;
use Cycle\Migrations\Migrator;

/**
* @var Migrator $migrator
* @var Capsule $capsule
*/
while ($migrator->rollback($capsule) !== null) {
echo "Migration {$migration->getState()->getName()} reverted successfully.\n";
}
```

### Using storages
Expand Down
2 changes: 1 addition & 1 deletion tests/Base/TestCase.php
Expand Up @@ -77,7 +77,7 @@ private function makeMigrator(): Migrator
$config = new MigrationConfig([
'directory' => $directories[0],
// "vendorDirectories" are specified because "directory" option doesn't support multiple directories. In the
// end, it makes no difference.
// end, it makes no difference, because they all will be merged into single array.
'vendorDirectories' => $directories[1] ?? [],
'table' => 'cycle_migration',
'safe' => true,
Expand Down

0 comments on commit 049c4cb

Please sign in to comment.