diff --git a/app/src/Lib/Match/MatchgridBuilder.php b/app/src/Lib/Match/MatchgridBuilder.php index 4f057c85c..796c6ae44 100644 --- a/app/src/Lib/Match/MatchgridBuilder.php +++ b/app/src/Lib/Match/MatchgridBuilder.php @@ -29,29 +29,33 @@ namespace App\Lib\Match; -use Cake\Datasource\ConnectionInterface; use Cake\Datasource\ConnectionManager; -use Cake\Utility\Xml; +use Cake\Datasource\EntityInterface; +use Doctrine\DBAL\Connection as DBALConnection; +use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Exception; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; -use Doctrine\DBAL\Schema\SchemaDiff; +use Doctrine\DBAL\Schema\SchemaException; class MatchgridBuilder { /** * Build the requested Matchgrid. * + * @param EntityInterface $Matchgrid Matchgrid Object + * @param array $attributes Array of Attributes + * @param bool $indexes Whether to build indexes (disable for bulk loading only) + * @throws SchemaException|DBALException|Exception * @since COmanage Match v1.0.0 - * @param \Cake\Datasource\EntityInterface $Matchgrid Matchgrid Object - * @param array $attributes Array of Attributes - * @param bool $indexes Whether to build indexes (disable for bulk loading only) */ - public function build(\Cake\Datasource\EntityInterface $Matchgrid, array $attributes, bool $indexes=true) { + public function build(EntityInterface $Matchgrid, array $attributes, bool $indexes=true): void + { // Connect to the database $dbc = $this->connect(); - + // Build and execute the schema $this->configToSchema($dbc, $Matchgrid, $attributes, $indexes); @@ -59,19 +63,24 @@ public function build(\Cake\Datasource\EntityInterface $Matchgrid, array $attrib // No DBAL disconnect? // $dbc->disconnect(); } - + /** * Convert a Matchgrid Attribute configuration into a DBAL schema. - * + * + * @param DBALConnection $dbc DBAL Connection Object + * @param EntityInterface $Matchgrid Matchgrid Object + * @param array $attributes Array of Attributes + * @param bool $indexes Whether to build indexes (disable for bulk loading only) + * @throws SchemaException * @since COmanage Match v1.0.0 - * @param DBALConnection $dbc DBAL Connection Object - * @param \Cake\Datasource\EntityInterface $Matchgrid Matchgrid Object - * @param array $attributes Array of Attributes - * @param bool $indexes Whether to build indexes (disable for bulk loading only) - * @throws Exceptions */ - - protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchgrid, array $attributes, bool $indexes=true) { + + protected function configToSchema( + DBALConnection $dbc, + EntityInterface $Matchgrid, + array $attributes, + bool $indexes=true): void + { // Unlike ADOdb, there is no native DBAL format. We could create a JSON // document similar to what DatabaseCommand uses, but the use case is just // different enough that it's not really worth the effort at the moment. @@ -82,9 +91,9 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg // Create the table $table = $schema->createTable($Matchgrid->prefixed_table_name); - - // For type definitions see https://www.doctrine-project.org/api/dbal/2.9/Doctrine/DBAL/Types/Type.html - + + // For type definitions see https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#types + // There are various mandatory columns that we hardcode here. $table->addColumn("id", "integer", ['autoincrement' => true, 'notnull' => true]); // Maybe SOR Label and ID should be UI configured so length can be set? @@ -113,11 +122,12 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg // $flags and $options as passed to Index(), but otherwise undocumented $flags = []; $options = []; - + $indexPrefix = "matchgrid_" . $Matchgrid->id; + $i = 1; // Start with the standard indexes - $indexLabel = "matchgrid_" . $Matchgrid->id . "_i"; + $indexLabel = $indexPrefix . "_i"; $table->addIndex(['sor'], $indexLabel.$i++, $flags, $options); $table->addIndex(['sorid'], $indexLabel.$i++, $flags, $options); $table->addUniqueIndex(['sor', 'sorid'], $indexLabel.$i++, $options); @@ -127,7 +137,7 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg // Add in indexes for configured fields foreach($attributes as $attr) { // We use the Entity ID to provide some level of reproducibility - $indexName = 'matchgrid_' . $Matchgrid->id . '_attr_id' . $attr->id; + $indexName = $indexPrefix . '_attr_id' . $attr->id; $table->addIndex([$attr->name], $indexName, $flags, $options); @@ -143,9 +153,9 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg $toSql = $schema->toSql($dbc->getDatabasePlatform()); // SchemaManager provides info about the database - $sm = $dbc->getSchemaManager(); + $sm = $dbc->createSchemaManager(); - // The is the current database representation + // This is the current database representation $curSchema = $sm->createSchema(); $fromSql = $curSchema->toSql($dbc->getDatabasePlatform()); @@ -181,20 +191,21 @@ protected function configToSchema($dbc, \Cake\Datasource\EntityInterface $Matchg } } - $stmt = $dbc->query($sql); // $stmt just returns the query string so we don't bother examining it + $stmt = $dbc->query($sql); } } - + /** * Connect to the Database. * + * @return DBALConnection + * @throws DBALException|Exception * @since COmanage Match v1.0.0 - * @return \Doctrine\DBAL\Connection - * @throws DBALException */ - protected function connect() { + protected function connect(): DBALConnection + { // There's some overlap between here and DatabaseCommand. // Use the ConnectionManager to get the database config to pass to adodb. @@ -204,20 +215,24 @@ protected function connect() { $cfg = $db->config(); // We only support Postgres (at least for now) - if($cfg['driver'] != "Cake\Database\Driver\Postgres") { + if($cfg['driver'] !== "Cake\Database\Driver\Postgres") { throw new \RuntimeException(__('match.er.db.driver' , [ $cfg['driver'] ])); } - - $config = new \Doctrine\DBAL\Configuration(); + + // Map CAKE DB drivers to PHP DB drivers + $driver = [ + 'Cake\Database\Driver\Postgres' => 'pdo_pgsql', + 'Cake\Database\Driver\Mysql' => 'pdo_mysql', + ]; $cfargs = [ 'dbname' => $cfg['database'], 'user' => $cfg['username'], 'password' => $cfg['password'], 'host' => $cfg['host'], - 'driver' => ($cfg['driver'] == 'Cake\Database\Driver\Postgres' ? "pdo_pgsql" : "pdo_mysql") + 'driver' => $driver[ $cfg['driver'] ] ]; - return DriverManager::getConnection($cfargs, $config); + return DriverManager::getConnection($cfargs); } }