diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..bb9de13
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,22 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - master
+ - 3.next
+ pull_request:
+ branches:
+ - '*'
+
+permissions:
+ contents: read
+
+jobs:
+ testsuite:
+ uses: cakephp/.github/.github/workflows/testsuite-with-db.yml@5.x
+ secrets: inherit
+
+ cs-stan:
+ uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x
+ secrets: inherit
diff --git a/.phive/phars.xml b/.phive/phars.xml
new file mode 100644
index 0000000..9aa6dfe
--- /dev/null
+++ b/.phive/phars.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/README.md b/README.md
index b576a78..7fe6409 100644
--- a/README.md
+++ b/README.md
@@ -8,11 +8,9 @@ CakePHP behavior plugin for easily generating some complicated queries like (bul
[](https://packagist.org/packages/itosho/easy-query)
## Requirements
-- PHP 7.2+
-- CakePHP 4.0+
-- MySQL 5.6+
-
-:warning: For CakePHP3.x, use 1.x branch.
+- PHP 8.1+
+- CakePHP 5.0+
+- MySQL 8.0+ / MariaDB 10.4+
## Installation
```bash
diff --git a/composer.json b/composer.json
index bce050e..bcfd135 100644
--- a/composer.json
+++ b/composer.json
@@ -26,12 +26,14 @@
"source": "https://github.com/itosho/easy-query"
},
"require": {
- "php": ">=7.2.0",
- "cakephp/orm": "^4.0"
+ "php": ">=8.1",
+ "cakephp/orm": "^5.0.0"
},
"require-dev": {
- "cakephp/cakephp": "^4.0",
- "phpunit/phpunit": "^8.5"
+ "cakephp/cakephp": "^5.0.0",
+ "phpunit/phpunit": "^10.1.0",
+ "cakephp/cakephp-codesniffer": "^5.0",
+ "vimeo/psalm": "^5.15"
},
"autoload": {
"psr-4": {
@@ -42,5 +44,10 @@
"psr-4": {
"Itosho\\EasyQuery\\Test\\": "tests"
}
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
}
}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..0737a91
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 0000000..f51e71c
--- /dev/null
+++ b/phpstan-baseline.neon
@@ -0,0 +1,2 @@
+parameters:
+ ignoreErrors: []
diff --git a/phpstan.neon b/phpstan.neon
index ca05326..f1af199 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,3 +1,9 @@
+includes:
+ - phpstan-baseline.neon
+
parameters:
- checkMissingIterableValueType: false
- ignoreErrors: []
+ level: 6
+ checkGenericClassInNonGenericObjectType: false
+ checkMissingIterableValueType: false
+ paths:
+ - src/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 878585e..7acf8f8 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,37 +1,23 @@
-
+
+
+
-
- ./tests/TestCase
+ tests/TestCase/
-
-
-
-
-
-
-
-
-
-
-
-
- ./src/
-
-
-
+
+
+
+
+
+ src/
+
+
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000..08f635d
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Model/Behavior/InsertBehavior.php b/src/Model/Behavior/InsertBehavior.php
index 5d1c050..883e77f 100644
--- a/src/Model/Behavior/InsertBehavior.php
+++ b/src/Model/Behavior/InsertBehavior.php
@@ -5,11 +5,11 @@
use Cake\Database\Expression\QueryExpression;
use Cake\Database\StatementInterface;
-use Cake\I18n\FrozenTime;
+use Cake\Datasource\EntityInterface;
+use Cake\I18n\DateTime;
use Cake\ORM\Behavior;
-use Cake\ORM\Entity;
-use Cake\ORM\Query;
-use Cake\ORM\TableRegistry;
+use Cake\ORM\Locator\LocatorAwareTrait;
+use Cake\ORM\Query\SelectQuery;
use LogicException;
/**
@@ -17,21 +17,23 @@
*/
class InsertBehavior extends Behavior
{
+ use LocatorAwareTrait;
+
/**
* Default config
*
- * @var array
+ * @var array
*/
- protected $_defaultConfig = [
+ protected array $_defaultConfig = [
'event' => ['beforeSave' => true],
];
/**
* execute bulk insert query
*
- * @param Entity[] $entities insert entities
- * @throws LogicException no save data
- * @return StatementInterface query result
+ * @param array<\Cake\Datasource\EntityInterface> $entities insert entities
+ * @throws \LogicException no save data
+ * @return \Cake\Database\StatementInterface query result
*/
public function bulkInsert(array $entities): StatementInterface
{
@@ -50,7 +52,7 @@ public function bulkInsert(array $entities): StatementInterface
$fields = array_keys($saveData[0]);
$query = $this->_table
- ->query()
+ ->insertQuery()
->insert($fields);
$query->clause('values')->setValues($saveData);
@@ -60,11 +62,11 @@ public function bulkInsert(array $entities): StatementInterface
/**
* execute insert select query for saving a record just once
*
- * @param Entity $entity insert entity
+ * @param \Cake\Datasource\EntityInterface $entity insert entity
* @param array|null $conditions search conditions
- * @return StatementInterface query result
+ * @return \Cake\Database\StatementInterface query result
*/
- public function insertOnce(Entity $entity, array $conditions = null): StatementInterface
+ public function insertOnce(EntityInterface $entity, ?array $conditions = null): StatementInterface
{
if ($this->_config['event']['beforeSave']) {
$this->_table->dispatchEvent('Model.beforeSave', compact('entity'));
@@ -72,11 +74,11 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI
$entity->setVirtual([]);
$insertData = $entity->toArray();
- if (isset($insertData['created']) && !is_null($insertData['created'])) {
- $insertData['created'] = FrozenTime::now()->toDateTimeString();
+ if (isset($insertData['created'])) {
+ $insertData['created'] = DateTime::now()->toDateTimeString();
}
- if (isset($insertData['modified']) && !is_null($insertData['modified'])) {
- $insertData['modified'] = FrozenTime::now()->toDateTimeString();
+ if (isset($insertData['modified'])) {
+ $insertData['modified'] = DateTime::now()->toDateTimeString();
}
$fields = array_keys($insertData);
@@ -84,7 +86,7 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI
if (is_null($existsConditions)) {
$existsConditions = $this->getExistsConditions($insertData);
}
- $query = $this->_table->query()->insert($fields);
+ $query = $this->_table->insertQuery()->insert($fields);
$subQuery = $this
->buildTmpTableSelectQuery($insertData)
->where(function (QueryExpression $exp) use ($existsConditions) {
@@ -95,7 +97,7 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI
return $exp->notExists($query);
})
->limit(1);
- /* @phpstan-ignore-next-line */
+
$query = $query->epilog($subQuery);
return $query->execute();
@@ -105,10 +107,10 @@ public function insertOnce(Entity $entity, array $conditions = null): StatementI
* build tmp table's select query for insert select query
*
* @param array $insertData insert data
- * @throws LogicException select query is invalid
- * @return Query tmp table's select query
+ * @return \Cake\ORM\Query\SelectQuery tmp table's select query
+ * @throws \LogicException select query is invalid
*/
- private function buildTmpTableSelectQuery($insertData): Query
+ private function buildTmpTableSelectQuery(array $insertData): SelectQuery
{
$driver = $this->_table
->getConnection()
@@ -118,15 +120,15 @@ private function buildTmpTableSelectQuery($insertData): Query
foreach ($insertData as $key => $value) {
$col = $driver->quoteIdentifier($key);
if (is_null($value)) {
- $schema[] = "NULL AS {$col}";
+ $schema[] = "NULL AS $col";
} else {
$bindKey = ':' . strtolower($key);
$binds[$bindKey] = $value;
- $schema[] = "{$bindKey} AS {$col}";
+ $schema[] = "$bindKey AS $col";
}
}
- $tmpTable = TableRegistry::getTableLocator()->get('tmp', [
+ $tmpTable = $this->fetchTable('tmp', [
'schema' => $this->_table->getSchema(),
]);
$query = $tmpTable
diff --git a/src/Model/Behavior/UpsertBehavior.php b/src/Model/Behavior/UpsertBehavior.php
index 374f7e0..33d6f78 100644
--- a/src/Model/Behavior/UpsertBehavior.php
+++ b/src/Model/Behavior/UpsertBehavior.php
@@ -6,7 +6,6 @@
use Cake\Database\StatementInterface;
use Cake\Datasource\EntityInterface;
use Cake\ORM\Behavior;
-use Cake\ORM\Entity;
use LogicException;
/**
@@ -17,9 +16,9 @@ class UpsertBehavior extends Behavior
/**
* Default config
*
- * @var array
+ * @var array
*/
- protected $_defaultConfig = [
+ protected array $_defaultConfig = [
'updateColumns' => null,
'uniqueColumns' => null,
'event' => ['beforeSave' => true],
@@ -28,11 +27,11 @@ class UpsertBehavior extends Behavior
/**
* execute upsert query
*
- * @param Entity $entity upsert entity
- * @return EntityInterface|array|null result entity
- * @throws LogicException invalid config
+ * @param \Cake\Datasource\EntityInterface $entity upsert entity
+ * @return \Cake\Datasource\EntityInterface|array|null result entity
+ * @throws \LogicException invalid config
*/
- public function upsert(Entity $entity)
+ public function upsert(EntityInterface $entity): array|EntityInterface|null
{
if (!$this->isValidArrayConfig('updateColumns')) {
throw new LogicException('config updateColumns is invalid.');
@@ -52,13 +51,13 @@ public function upsert(Entity $entity)
$updateValues = [];
foreach ($updateColumns as $column) {
- $updateValues[] = "`{$column}`=VALUES(`{$column}`)";
+ $updateValues[] = "`$column`=VALUES(`$column`)";
}
$updateStatement = implode(', ', $updateValues);
$expression = 'ON DUPLICATE KEY UPDATE ' . $updateStatement;
$this->_table
- ->query()
+ ->insertQuery()
->insert($fields)
->values($upsertData)
->epilog($expression)
@@ -80,9 +79,9 @@ public function upsert(Entity $entity)
/**
* execute bulk upsert query
*
- * @param Entity[] $entities upsert entities
- * @return StatementInterface query result
- * @throws LogicException invalid config or no save data
+ * @param array<\Cake\Datasource\EntityInterface> $entities upsert entities
+ * @return \Cake\Database\StatementInterface query result
+ * @throws \LogicException invalid config or no save data
*/
public function bulkUpsert(array $entities): StatementInterface
{
@@ -107,13 +106,12 @@ public function bulkUpsert(array $entities): StatementInterface
$updateColumns = $this->_config['updateColumns'];
$updateValues = [];
foreach ($updateColumns as $column) {
- $updateValues[] = "`{$column}`=VALUES(`{$column}`)";
+ $updateValues[] = "`$column`=VALUES(`$column`)";
}
$updateStatement = implode(', ', $updateValues);
$expression = 'ON DUPLICATE KEY UPDATE ' . $updateStatement;
-
$query = $this->_table
- ->query()
+ ->insertQuery()
->insert($fields)
->epilog($expression);
$query->clause('values')->setValues($saveData);
@@ -125,7 +123,6 @@ public function bulkUpsert(array $entities): StatementInterface
* validate config value
*
* @param string $configName config key
- *
* @return bool valid or invalid
*/
private function isValidArrayConfig(string $configName): bool
diff --git a/tests/Fixture/ArticlesFixture.php b/tests/Fixture/ArticlesFixture.php
index 55a5835..ba6710b 100644
--- a/tests/Fixture/ArticlesFixture.php
+++ b/tests/Fixture/ArticlesFixture.php
@@ -7,18 +7,7 @@
class ArticlesFixture extends TestFixture
{
- public $fields = [
- 'id' => ['type' => 'integer'],
- 'title' => ['type' => 'string', 'length' => 255, 'null' => false],
- 'body' => 'text',
- 'published' => ['type' => 'integer', 'default' => '0', 'null' => false],
- 'created' => 'datetime',
- 'modified' => 'datetime',
- '_constraints' => [
- 'primary' => ['type' => 'primary', 'columns' => ['id']],
- ],
- ];
- public $records = [
+ public array $records = [
[
'title' => 'First Article',
'body' => 'First Article Body',
diff --git a/tests/Fixture/TagsFixture.php b/tests/Fixture/TagsFixture.php
index 4d11962..a9d4250 100644
--- a/tests/Fixture/TagsFixture.php
+++ b/tests/Fixture/TagsFixture.php
@@ -7,18 +7,7 @@
class TagsFixture extends TestFixture
{
- public $fields = [
- 'id' => ['type' => 'integer'],
- 'name' => ['type' => 'string', 'length' => 255, 'null' => false],
- 'description' => ['type' => 'string', 'length' => 255, 'null' => false],
- 'created' => 'datetime',
- 'modified' => 'datetime',
- '_constraints' => [
- 'primary' => ['type' => 'primary', 'columns' => ['id']],
- 'unique' => ['type' => 'unique', 'columns' => ['name']],
- ],
- ];
- public $records = [
+ public array $records = [
[
'name' => 'tag1',
'description' => 'tag1 description',
diff --git a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php
index 30ed2d9..e634eb1 100644
--- a/tests/TestCase/Model/Behavior/InsertBehaviorTest.php
+++ b/tests/TestCase/Model/Behavior/InsertBehaviorTest.php
@@ -3,11 +3,10 @@
namespace Itosho\EasyQuery\Test\TestCase\Model\Behavior;
-use Cake\Chronos\Chronos;
-use Cake\I18n\FrozenTime;
+use Cake\I18n\DateTime;
use Cake\ORM\Table;
-use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
+use LogicException;
/**
* Itosho\EasyQuery\Model\Behavior\InsertBehavior Test Case
@@ -19,31 +18,31 @@ class InsertBehaviorTest extends TestCase
*
* @var Table
*/
- public $Articles;
+ public Table $Articles;
/**
* Fixtures
*
* @var array
*/
- public $fixtures = ['plugin.Itosho/EasyQuery.Articles'];
+ public array $fixtures = ['plugin.Itosho/EasyQuery.Articles'];
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
public function setUp(): void
{
parent::setUp();
- $this->Articles = TableRegistry::getTableLocator()->get('Itosho/EasyQuery.Articles');
+ $this->Articles = $this->getTableLocator()->get('Itosho/EasyQuery.Articles');
$this->Articles->addBehavior('Itosho/EasyQuery.Insert');
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
public function tearDown(): void
{
parent::tearDown();
- TableRegistry::getTableLocator()->clear();
+ $this->getTableLocator()->clear();
unset($this->Articles);
}
@@ -55,7 +54,7 @@ public function tearDown(): void
public function testBulkInsert()
{
$records = $this->getBaseInsertRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
foreach ($records as $key => $val) {
$record[$key]['created'] = $now;
$record[$key]['modified'] = $now;
@@ -85,7 +84,7 @@ public function testBulkInsertAddTimestamp()
$records[0]['modified'] = $customNow;
$expectedRecords = $this->getBaseInsertRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
foreach ($expectedRecords as $key => $val) {
$expectedRecords[$key]['created'] = $now;
$expectedRecords[$key]['modified'] = $now;
@@ -145,8 +144,8 @@ public function testBulkInsertNoBeforeSave()
*/
public function testBulkInsertNoSaveData()
{
- $this->expectExceptionMessage("entities has no save data.");
- $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('entities has no save data.');
+ $this->expectException(LogicException::class);
$this->Articles->bulkInsert([]);
}
@@ -190,7 +189,7 @@ public function testInsertOnceAddTimestampBehavior()
'published' => 1,
];
$entity = $this->Articles->newEntity($newData);
- $now = FrozenTime::now();
+ $now = DateTime::now();
$this->Articles->insertOnce($entity);
diff --git a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php
index 4a5cbb8..3a6ffdb 100644
--- a/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php
+++ b/tests/TestCase/Model/Behavior/UpsertBehaviorTest.php
@@ -3,10 +3,10 @@
namespace Itosho\EasyQuery\Test\TestCase\Model\Behavior;
-use Cake\Chronos\Chronos;
+use Cake\I18n\DateTime;
use Cake\ORM\Table;
-use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
+use LogicException;
/**
* Itosho\EasyQuery\Model\Behavior\UpsertBehavior Test Case
@@ -18,21 +18,21 @@ class UpsertBehaviorTest extends TestCase
*
* @var Table
*/
- public $Tags;
+ public Table $Tags;
/**
* Fixtures
*
* @var array
*/
- public $fixtures = ['plugin.Itosho/EasyQuery.Tags'];
+ public array $fixtures = ['plugin.Itosho/EasyQuery.Tags'];
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
public function setUp(): void
{
parent::setUp();
- $this->Tags = TableRegistry::getTableLocator()->get('Itosho/EasyQuery.Tags');
+ $this->Tags = $this->getTableLocator()->get('Itosho/EasyQuery.Tags');
$this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [
'uniqueColumns' => ['name'],
'updateColumns' => ['description', 'modified'],
@@ -40,12 +40,12 @@ public function setUp(): void
}
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
public function tearDown(): void
{
parent::tearDown();
- TableRegistry::getTableLocator()->clear();
+ $this->getTableLocator()->clear();
unset($this->Tags);
}
@@ -56,7 +56,7 @@ public function tearDown(): void
*/
public function testUpsertByInsert()
{
- $now = Chronos::now();
+ $now = DateTime::now();
$record = [
'name' => 'tag4',
'description' => 'tag4 description',
@@ -97,7 +97,7 @@ public function testUpsertByInsertAddTimestamp()
'name' => 'tag4',
'description' => 'tag4 description',
];
- $now = Chronos::now();
+ $now = DateTime::now();
$expectedRecord = $record;
$expectedRecord['created'] = $now;
$expectedRecord['modified'] = $now;
@@ -172,7 +172,7 @@ public function testUpsertByUpdateAddTimestamp()
'name' => 'tag1',
'description' => 'brand new tag1 description',
];
- $now = Chronos::now();
+ $now = DateTime::now();
$currentCreated = '2017-09-01 00:00:00';
$expectedRecord = $record;
$expectedRecord['created'] = $currentCreated;
@@ -242,8 +242,8 @@ public function testUpsertNoBeforeSave()
*/
public function testUpsertInvalidUpdateColumnsConfig()
{
- $this->expectExceptionMessage("config updateColumns is invalid.");
- $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('config updateColumns is invalid.');
+ $this->expectException(LogicException::class);
$this->Tags->removeBehavior('Upsert');
$this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [
@@ -267,8 +267,8 @@ public function testUpsertInvalidUpdateColumnsConfig()
*/
public function testUpsertInvalidUniqueColumnsConfig()
{
- $this->expectExceptionMessage("config uniqueColumns is invalid.");
- $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('config uniqueColumns is invalid.');
+ $this->expectException(LogicException::class);
$this->Tags->removeBehavior('Upsert');
$this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [
@@ -298,7 +298,7 @@ public function testBulkUpsertByInsert()
]);
$records = $this->getBaseInsertRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
foreach ($records as $key => $val) {
$records[$key]['created'] = $now;
$records[$key]['modified'] = $now;
@@ -327,7 +327,7 @@ public function testBulkUpsertByInsertAddTimestamp()
$this->Tags->addBehavior('Timestamp');
$records = $this->getBaseInsertRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
$expectedRecords = $records;
foreach ($expectedRecords as $key => $val) {
$expectedRecords[$key]['created'] = $now;
@@ -356,7 +356,7 @@ public function testBulkUpsertByUpdate()
]);
$records = $this->getBaseUpdateRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
foreach ($records as $key => $val) {
$records[$key]['created'] = $now;
$records[$key]['modified'] = $now;
@@ -387,7 +387,7 @@ public function testBulkUpsertByUpdateAddTimestamp()
$this->Tags->addBehavior('Timestamp');
$records = $this->getBaseUpdateRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
$currentCreated = '2017-09-01 00:00:00';
$expectedRecords = $records;
foreach ($expectedRecords as $key => $val) {
@@ -441,14 +441,14 @@ public function testBulkUpsertNoBeforeSave()
*/
public function testBulkUpsertInvalidUpdateColumnsConfig()
{
- $this->expectExceptionMessage("config updateColumns is invalid.");
- $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('config updateColumns is invalid.');
+ $this->expectException(LogicException::class);
$this->Tags->removeBehavior('Upsert');
$this->Tags->addBehavior('Itosho/EasyQuery.Upsert');
$records = $this->getBaseInsertRecords();
- $now = Chronos::now();
+ $now = DateTime::now();
foreach ($records as $key => $val) {
$records[$key]['created'] = $now;
$records[$key]['modified'] = $now;
@@ -465,8 +465,8 @@ public function testBulkUpsertInvalidUpdateColumnsConfig()
*/
public function testBulkUpsertNoSaveData()
{
- $this->expectExceptionMessage("entities has no save data.");
- $this->expectException(\LogicException::class);
+ $this->expectExceptionMessage('entities has no save data.');
+ $this->expectException(LogicException::class);
$this->Tags->removeBehavior('Upsert');
$this->Tags->addBehavior('Itosho/EasyQuery.Upsert', [
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index e2b0179..66d427f 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -1,18 +1,19 @@
Connection::class,
- 'driver' => Mysql::class,
- 'host' => getenv('db_host'),
- 'username' => getenv('db_user'),
- 'database' => getenv('db_name'),
+ 'url' => env('DB_URL'),
];
ConnectionManager::drop('test');
ConnectionManager::setConfig('test', $dbConfig);
+
+// Create test database schema
+if (env('FIXTURE_SCHEMA_METADATA')) {
+ $loader = new SchemaLoader();
+ $loader->loadInternalFile(env('FIXTURE_SCHEMA_METADATA'));
+}
diff --git a/tests/schema.php b/tests/schema.php
new file mode 100644
index 0000000..c4d65d5
--- /dev/null
+++ b/tests/schema.php
@@ -0,0 +1,33 @@
+ 'articles',
+ 'columns' => [
+ 'id' => ['type' => 'integer'],
+ 'title' => ['type' => 'string', 'length' => 255, 'null' => false],
+ 'body' => 'text',
+ 'published' => ['type' => 'integer', 'default' => '0', 'null' => false],
+ 'created' => 'datetime',
+ 'modified' => 'datetime',
+ ],
+ 'constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['id']],
+ ],
+ ],
+ [
+ 'table' => 'tags',
+ 'columns' => [
+ 'id' => ['type' => 'integer'],
+ 'name' => ['type' => 'string', 'length' => 255, 'null' => false],
+ 'description' => ['type' => 'string', 'length' => 255, 'null' => false],
+ 'created' => 'datetime',
+ 'modified' => 'datetime',
+ ],
+ 'constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['id']],
+ 'unique' => ['type' => 'unique', 'columns' => ['name']],
+ ],
+ ],
+];