From e406027ad631dda6da2444a55ff6eeb9162ffbcd Mon Sep 17 00:00:00 2001 From: Ulrich Schmidt-Goertz Date: Tue, 19 Nov 2019 16:18:04 +0100 Subject: [PATCH 1/2] PRI-2601: Add metadata.yaml --- .travis.yml | 17 +++++++++++----- metadata.yaml | 23 ++++++++++++++++++++++ tests/CompositeNumberRangeBehaviorTest.php | 13 +++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 metadata.yaml diff --git a/.travis.yml b/.travis.yml index 62d06e5..07c64b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,25 @@ language: php sudo: false +branches: + only: + - master + - develop + php: - - 5.4 - - 5.5 - - 5.6 - - hhvm + - 7.1 + - 7.2 + - 7.3 + +services: + - mysql before_script: - composer install - mysql -e 'create database behavior_test;' script: - - phpunit + - vendor/bin/phpunit env: - DB_USER=travis DB_PASS= DB_NAME=behavior_test \ No newline at end of file diff --git a/metadata.yaml b/metadata.yaml new file mode 100644 index 0000000..6f3b040 --- /dev/null +++ b/metadata.yaml @@ -0,0 +1,23 @@ +type: library +owners: + - team.prism@finanzcheck.de +product: propel-plugins +id: finanzcheck-composite-number-range-behavior +vertical: finanzcheck +availability: false +confidentiality: company-internal +integrity: false +authenticity: false +exposure: + - non-applicable +lifecycle: maintenance +name: Composite Number Range Behavior +description: Propel behavior for client scoped IDs +links: + - type: repository + title: GitHub repository + address: https://github.com/finanzcheck/composite-number-range-behavior +tags: + - php + - propel +license: Proprietary \ No newline at end of file diff --git a/tests/CompositeNumberRangeBehaviorTest.php b/tests/CompositeNumberRangeBehaviorTest.php index f95b3ec..787e55d 100644 --- a/tests/CompositeNumberRangeBehaviorTest.php +++ b/tests/CompositeNumberRangeBehaviorTest.php @@ -6,6 +6,7 @@ use Propel\Generator\Util\QuickBuilder; use Propel\Runtime\Adapter\Pdo\MysqlAdapter; use Propel\Runtime\Collection\ObjectCollection; +use Propel\Runtime\Propel; use Propel\Tests\TestCase; class CompositeNumberRangeBehaviorTest extends TestCase @@ -35,7 +36,12 @@ public function setUp() $builder = new QuickBuilder(); $builder->setPlatform(new MysqlPlatform()); $builder->setSchema($schema); - $builder->build('mysql:host=127.0.0.1;dbname=' . getenv('DB_NAME'), getenv('DB_USER'), getenv('DB_PASS'), new MysqlAdapter()); + $builder->build( + 'mysql:host=127.0.0.1;dbname=' . getenv('DB_NAME'), + getenv('DB_USER'), + getenv('DB_PASS'), + new MysqlAdapter() + ); } $this->parent = new \ParentTable(); @@ -164,6 +170,10 @@ public function testInsertThirdRowWithDifferentParentTableIdCreatesAnotherParent */ public function testNullingParentTableIdForExistingRowCreatesNewParentTableId() { + $tableMapClass = \ParentTable::TABLE_MAP; + $con = Propel::getServiceContainer()->getWriteConnection($tableMapClass::DATABASE_NAME); + $con->exec('ALTER TABLE child_table CHANGE parent_table_id parent_table_id INT(11) DEFAULT NULL'); + $parentId = $this->parent->getId(); $child = new \ChildTable(); @@ -176,6 +186,7 @@ public function testNullingParentTableIdForExistingRowCreatesNewParentTableId() $child->setParentTableId(null); $child->save(); + $child->reload(); $this->assertGreaterThan($firstParentTableId, $child->getParentTableId()); } From 42c27318f0b815ca4e9a96aeeaa5b9cf06337da3 Mon Sep 17 00:00:00 2001 From: Ulrich Schmidt-Goertz Date: Tue, 22 Sep 2020 16:49:59 +0200 Subject: [PATCH 2/2] Allow aliasing the table name (#3) --- README.md | 17 +++++++ composer.json | 5 ++ src/CompositeNumberRangeBehavior.php | 27 +++++++++- src/Platform/MysqlPlatform.php | 21 ++++---- tests/CompositeNumberRangeBehaviorTest.php | 57 +++++++++++++++++++++- 5 files changed, 115 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a183b51..3d570af 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,23 @@ $userDocumentId = $document->getUserDocumentId(); // $userDocumentId contains 1 ``` +## Table Name Aliases + +It is possible to use an alias instead of the actual table name for the auto-generated column and trigger names +by specifying the `localTableAlias` parameter. For example, this definition: + +```xml + + + + + + +
+``` + +will result in the composite id column being named `user_doc_id` and the trigger `SetDocUserId`. + ## Migrations Notice Because `propel:migrations:diff` does not know anything about triggers, they have to be checked via SQL Statement. If you use triggers and change something on any table having triggers appended, they will always appear in your `down()` section of the migration. At the moment you have to remove them by hand, diff --git a/composer.json b/composer.json index 4d22329..5266a43 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,11 @@ "Finanzcheck\\CompositeNumberRange\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Finanzcheck\\CompositeNumberRange\\": "tests/" + } + }, "authors": [ { "name": "Alexander Pinnecke", diff --git a/src/CompositeNumberRangeBehavior.php b/src/CompositeNumberRangeBehavior.php index b3c1dfc..2ee5e2d 100644 --- a/src/CompositeNumberRangeBehavior.php +++ b/src/CompositeNumberRangeBehavior.php @@ -13,6 +13,7 @@ class CompositeNumberRangeBehavior extends Behavior protected $parameters = array( 'foreignTable' => null, + 'localTableAlias' => null, 'refPhpName' => null, 'phpName' => null, ); @@ -33,6 +34,21 @@ public function getForeignTable() return strtolower($table); } + /** + * Returns the name that should be used (in column names) for the table that the behavior is applied to. + * The default is the actual table name, but it can be overridden with the localTableAlias parameter. + * + * @return string + */ + public function getLocalTableName() + { + $alias = $this->getParameter('localTableAlias'); + if ($alias === null) { + return $this->getTable()->getName(); + } + return $alias; + } + /** * Gets the refPhpName parameter from config array. * @@ -61,6 +77,14 @@ protected function getPhpName() return $name; } + public function getCompositeKeyColumnName() + { + $tableName = $this->getLocalTableName(); + $foreignTableName = $this->getForeignTable(); + + return $foreignTableName . '_' . $tableName . '_id'; + } + /** * Adds all columns, indexes, constraints and additional tables. */ @@ -75,7 +99,8 @@ public function modifyTable() $table->setReloadOnInsert(true); $foreignIdColumnName = $foreignTableName . '_id'; - $this->compositeKeyColumnName = $foreignTableName . '_' . $tableName . '_id'; + + $this->compositeKeyColumnName = $this->getCompositeKeyColumnName(); if ($table->hasBehavior('concrete_inheritance')) { // we're a child in a concrete inheritance diff --git a/src/Platform/MysqlPlatform.php b/src/Platform/MysqlPlatform.php index 4bb8300..9eb18cb 100644 --- a/src/Platform/MysqlPlatform.php +++ b/src/Platform/MysqlPlatform.php @@ -150,14 +150,13 @@ protected function createDropTriggersDDL(Table $table) */ protected function getTriggerNames(Table $table) { - $tableName = $table->getName(); - /** @var CompositeNumberRangeBehavior $behavior */ $behavior = $table->getBehavior(self::BEHAVIOR_NAME); - $foreignTableName = $behavior->getForeignTable(); + $compositeKeyColumnName = $behavior->getCompositeKeyColumnName(); + $triggerColumnName = ucwords($compositeKeyColumnName, '_'); - $insertTrigger = str_replace(' ', '', ucwords(str_replace('_', ' ', 'set' . ucfirst($foreignTableName) . ucfirst($tableName) . 'Id'))); - $updateTrigger = str_replace(' ', '', ucwords(str_replace('_', ' ', 'setOnUpdate' . ucfirst($foreignTableName) . ucfirst($tableName) . 'Id'))); + $insertTrigger = str_replace(' ', '', ucwords(str_replace('_', ' ', 'set' . $triggerColumnName))); + $updateTrigger = str_replace(' ', '', ucwords(str_replace('_', ' ', 'setOnUpdate' . $triggerColumnName))); return [ $insertTrigger, $updateTrigger ]; } @@ -177,6 +176,8 @@ protected function createTriggersDDL(Table $table) $foreignTableName = $behavior->getForeignTable(); $triggerNames = $this->getTriggerNames($table); $tableName = $table->getName(); + $tableNameOrAlias = $behavior->getLocalTableName(); + $compositeKeyColumnName = $behavior->getCompositeKeyColumnName(); $sql = " DELIMITER $; @@ -188,11 +189,11 @@ protected function createTriggersDDL(Table $table) INSERT INTO ${foreignTableName}_sequence ( table_name, ${foreignTableName}_id, ${foreignTableName}_max_sequence_id ) VALUES ( - '${tableName}', NEW.${foreignTableName}_id, LAST_INSERT_ID(1) + '${tableNameOrAlias}', NEW.${foreignTableName}_id, LAST_INSERT_ID(1) ) ON DUPLICATE KEY UPDATE ${foreignTableName}_max_sequence_id = LAST_INSERT_ID(${foreignTableName}_max_sequence_id +1); - SET NEW.${foreignTableName}_${tableName}_id = LAST_INSERT_ID(); + SET NEW.${compositeKeyColumnName} = LAST_INSERT_ID(); END DELIMITER ; @@ -203,15 +204,15 @@ protected function createTriggersDDL(Table $table) BEFORE UPDATE ON ${tableName} FOR EACH ROW BEGIN - IF NEW.${foreignTableName}_${tableName}_id IS NULL OR NEW.${foreignTableName}_${tableName}_id = 0 THEN + IF NEW.${compositeKeyColumnName} IS NULL OR NEW.${compositeKeyColumnName} = 0 THEN INSERT INTO ${foreignTableName}_sequence ( table_name, ${foreignTableName}_id, ${foreignTableName}_max_sequence_id ) VALUES ( - '${tableName}', NEW.${foreignTableName}_id, LAST_INSERT_ID(1) + '${tableNameOrAlias}', NEW.${foreignTableName}_id, LAST_INSERT_ID(1) ) ON DUPLICATE KEY UPDATE ${foreignTableName}_max_sequence_id = LAST_INSERT_ID(${foreignTableName}_max_sequence_id +1); - SET NEW.${foreignTableName}_${tableName}_id = LAST_INSERT_ID(); + SET NEW.${compositeKeyColumnName} = LAST_INSERT_ID(); END IF; END diff --git a/tests/CompositeNumberRangeBehaviorTest.php b/tests/CompositeNumberRangeBehaviorTest.php index 787e55d..f56e8d0 100644 --- a/tests/CompositeNumberRangeBehaviorTest.php +++ b/tests/CompositeNumberRangeBehaviorTest.php @@ -1,6 +1,6 @@ assertGreaterThan($firstParentTableId, $child->getParentTableId()); } + + public function testUsesTheLocalTableAliasParameterWhenGiven() + { + $schema = << + + +
+ + + + + + +
+ +EOF; + + $builder = new QuickBuilder(); + $builder->setPlatform(new MysqlPlatform()); + $builder->setSchema($schema); + $builder->build( + 'mysql:host=127.0.0.1;dbname=' . getenv('DB_NAME'), + getenv('DB_USER'), + getenv('DB_PASS'), + new MysqlAdapter() + ); + + $this->assertTrue(class_exists('\Bar')); + $this->assertTrue(class_exists('\BarQuery')); + $this->assertTrue(class_exists('\Foo')); + $this->assertTrue(class_exists('\FooQuery')); + $this->assertTrue(class_exists('\FooSequence')); + $this->assertTrue(class_exists('\FooSequenceQuery')); + + $entity = new \Bar(); + + $this->assertTrue(method_exists($entity, 'setFoo')); + $this->assertTrue(method_exists($entity, 'setFooId')); + $this->assertTrue(method_exists($entity, 'setFooBazId')); + + $sequenceEntity = new \FooSequence(); + + $this->assertTrue(method_exists($sequenceEntity, 'setTableName')); + $this->assertTrue(method_exists($sequenceEntity, 'setFooId')); + $this->assertTrue(method_exists($sequenceEntity, 'setFooMaxSequenceId')); + + $foo = new \Foo(); + $foo->save(); + + $entity->setFoo($foo); + $entity->save(); + + $this->assertEquals($foo->getId(), $entity->getFooBazId()); + } }