vendor/jackalope/jackalope-doctrine-dbal/src/Jackalope/Transport/DoctrineDBAL/RepositorySchema.php line 41

  1. <?php
  2. namespace Jackalope\Transport\DoctrineDBAL;
  3. use Doctrine\DBAL\Exception;
  4. use Doctrine\DBAL\Schema\Schema;
  5. use Doctrine\DBAL\Connection;
  6. use Doctrine\DBAL\Schema\Table;
  7. use PHPCR\RepositoryException;
  8. /**
  9.  * Class to handle setup the RDBMS tables for the Doctrine DBAL transport.
  10.  *
  11.  * @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
  12.  * @license http://opensource.org/licenses/MIT MIT License
  13.  */
  14. class RepositorySchema extends Schema
  15. {
  16.     /**
  17.      * @var Connection
  18.      */
  19.     private $connection;
  20.     /**
  21.      * @var integer
  22.      */
  23.     private $maxIndexLength = -1;
  24.     /**
  25.      * @param array $options The options could be use to make the table
  26.      *                               names configurable.
  27.      * @param Connection $connection
  28.      */
  29.     public function __construct(array $options = [], Connection $connection null)
  30.     {
  31.         $this->connection $connection;
  32.         $schemaConfig null === $connection null $connection->getSchemaManager()->createSchemaConfig();
  33.         parent::__construct([], [], $schemaConfig);
  34.         $this->options $options;
  35.         $this->addNamespacesTable();
  36.         $this->addWorkspacesTable();
  37.         $nodes $this->addNodesTable();
  38.         $this->addInternalIndexTypesTable();
  39.         $this->addBinaryDataTable();
  40.         $this->addNodesReferencesTable($nodes);
  41.         $this->addNodesWeakreferencesTable($nodes);
  42.         $this->addTypeNodesTable();
  43.         $this->addTypePropsTable();
  44.         $this->addTypeChildsTable();
  45.     }
  46.     /**
  47.      * Merges Jackalope schema with the given schema.
  48.      *
  49.      * @param Schema $schema
  50.      */
  51.     public function addToSchema(Schema $schema)
  52.     {
  53.         foreach ($this->getTables() as $table) {
  54.             $schema->_addTable($table);
  55.         }
  56.         foreach ($this->getSequences() as $sequence) {
  57.             $schema->_addSequence($sequence);
  58.         }
  59.     }
  60.     protected function addNamespacesTable()
  61.     {
  62.         $namespace $this->createTable('phpcr_namespaces');
  63.         $namespace->addColumn('prefix''string', ['length' => $this->getMaxIndexLength()]);
  64.         $namespace->addColumn('uri''string');
  65.         $namespace->setPrimaryKey(['prefix']);
  66.     }
  67.     protected function addWorkspacesTable()
  68.     {
  69.         $workspace $this->createTable('phpcr_workspaces');
  70.         $workspace->addColumn('name''string', ['length' => $this->getMaxIndexLength()]);
  71.         $workspace->setPrimaryKey(['name']);
  72.     }
  73.     /**
  74.      * @return Table
  75.      */
  76.     protected function addNodesTable()
  77.     {
  78.         // TODO increase the size of 'path' and 'parent' but this causes issues on MySQL due to key length
  79.         $nodes $this->createTable('phpcr_nodes');
  80.         $nodes->addColumn('id''integer', ['autoincrement' => true]);
  81.         $nodes->addColumn('path''string', ['length' => $this->getMaxIndexLength()]);
  82.         $nodes->addColumn('parent''string', ['length' => $this->getMaxIndexLength()]);
  83.         $nodes->addColumn('local_name''string', ['length' => $this->getMaxIndexLength()]);
  84.         $nodes->addColumn('namespace''string', ['length' => $this->getMaxIndexLength()]);
  85.         $nodes->addColumn('workspace_name''string', ['length' => $this->getMaxIndexLength()]);
  86.         $nodes->addColumn('identifier''string', ['length' => $this->getMaxIndexLength()]);
  87.         $nodes->addColumn('type''string', ['length' => $this->getMaxIndexLength()]);
  88.         $nodes->addColumn('props''text');
  89.         $nodes->addColumn('numerical_props''text', ['notnull' => false]);
  90.         $nodes->addColumn('depth''integer');
  91.         $nodes->addColumn('sort_order''integer', ['notnull' => false]);
  92.         $nodes->setPrimaryKey(['id']);
  93.         $nodes->addUniqueIndex(['path''workspace_name']);
  94.         $nodes->addUniqueIndex(['identifier''workspace_name']);
  95.         $nodes->addIndex(['parent']);
  96.         $nodes->addIndex(['type']);
  97.         $nodes->addIndex(['local_name''namespace']);
  98.         return $nodes;
  99.     }
  100.     protected function addInternalIndexTypesTable()
  101.     {
  102.         $indexJcrTypes $this->createTable('phpcr_internal_index_types');
  103.         $indexJcrTypes->addColumn('type''string', ['length' => $this->getMaxIndexLength()]);
  104.         $indexJcrTypes->addColumn('node_id''integer', ['length' => $this->getMaxIndexLength()]);
  105.         $indexJcrTypes->setPrimaryKey(['type''node_id']);
  106.     }
  107.     protected function addBinaryDataTable()
  108.     {
  109.         $binary $this->createTable('phpcr_binarydata');
  110.         $binary->addColumn('id''integer', ['autoincrement' => true]);
  111.         $binary->addColumn('node_id''integer');
  112.         $binary->addColumn('property_name''string', ['length' => $this->getMaxIndexLength()]);
  113.         $binary->addColumn('workspace_name''string', ['length' => $this->getMaxIndexLength()]);
  114.         $binary->addColumn('idx''integer', ['default' => 0]);
  115.         $binary->addColumn('data''blob');
  116.         $binary->setPrimaryKey(['id']);
  117.         $binary->addUniqueIndex(['node_id''property_name''workspace_name''idx']);
  118.     }
  119.     protected function addNodesReferencesTable(Table $nodes)
  120.     {
  121.         $references $this->createTable('phpcr_nodes_references');
  122.         $references->addColumn('source_id''integer');
  123.         $references->addColumn('source_property_name''string', ['length' => $this->getMaxIndexLength(220)]);
  124.         $references->addColumn('target_id''integer');
  125.         $references->setPrimaryKey(['source_id''source_property_name''target_id']);
  126.         $references->addIndex(['target_id']);
  127.         if (!empty($this->options['disable_fk'])) {
  128.             $references->addForeignKeyConstraint($nodes, ['source_id'], ['id'], ['onDelete' => 'CASCADE']);
  129.             // TODO: this should be reenabled on RDBMS with deferred FK support
  130.             //$references->addForeignKeyConstraint($nodes, array('target_id'), array('id'));
  131.         }
  132.     }
  133.     protected function addNodesWeakreferencesTable(Table $nodes)
  134.     {
  135.         $weakreferences $this->createTable('phpcr_nodes_weakreferences');
  136.         $weakreferences->addColumn('source_id''integer');
  137.         $weakreferences->addColumn('source_property_name''string', ['length' => $this->getMaxIndexLength(220)]);
  138.         $weakreferences->addColumn('target_id''integer');
  139.         $weakreferences->setPrimaryKey(['source_id''source_property_name''target_id']);
  140.         $weakreferences->addIndex(['target_id']);
  141.         if (!empty($this->options['disable_fk'])) {
  142.             $weakreferences->addForeignKeyConstraint($nodes, ['source_id'], ['id'], ['onDelete' => 'CASCADE']);
  143.             $weakreferences->addForeignKeyConstraint($nodes, ['target_id'], ['id'], ['onDelete' => 'CASCADE']);
  144.         }
  145.     }
  146.     protected function addTypeNodesTable()
  147.     {
  148.         $types $this->createTable('phpcr_type_nodes');
  149.         $types->addColumn('node_type_id''integer', ['autoincrement' => true]);
  150.         $types->addColumn('name''string', ['length' => $this->getMaxIndexLength()]);
  151.         $types->addColumn('supertypes''string');
  152.         $types->addColumn('is_abstract''boolean');
  153.         $types->addColumn('is_mixin''boolean');
  154.         $types->addColumn('queryable''boolean');
  155.         $types->addColumn('orderable_child_nodes''boolean');
  156.         $types->addColumn('primary_item''string', ['notnull' => false]);
  157.         $types->setPrimaryKey(['node_type_id']);
  158.         $types->addUniqueIndex(['name']);
  159.     }
  160.     protected function addTypePropsTable()
  161.     {
  162.         $propTypes $this->createTable('phpcr_type_props');
  163.         $propTypes->addColumn('node_type_id''integer');
  164.         $propTypes->addColumn('name''string', ['length' => $this->getMaxIndexLength()]);
  165.         $propTypes->addColumn('protected''boolean');
  166.         $propTypes->addColumn('auto_created''boolean');
  167.         $propTypes->addColumn('mandatory''boolean');
  168.         $propTypes->addColumn('on_parent_version''integer');
  169.         $propTypes->addcolumn('multiple''boolean');
  170.         $propTypes->addColumn('fulltext_searchable''boolean');
  171.         $propTypes->addcolumn('query_orderable''boolean');
  172.         $propTypes->addColumn('required_type''integer');
  173.         $propTypes->addColumn('query_operators''integer'); // BITMASK
  174.         $propTypes->addColumn('default_value''string', ['notnull' => false]);
  175.         $propTypes->setPrimaryKey(['node_type_id''name']);
  176.     }
  177.     protected function addTypeChildsTable()
  178.     {
  179.         $childTypes $this->createTable('phpcr_type_childs');
  180.         $childTypes->addColumn('id''integer', ['autoincrement' => true]);
  181.         $childTypes->addColumn('node_type_id''integer');
  182.         $childTypes->addColumn('name''string');
  183.         $childTypes->addColumn('protected''boolean');
  184.         $childTypes->addColumn('auto_created''boolean');
  185.         $childTypes->addColumn('mandatory''boolean');
  186.         $childTypes->addColumn('on_parent_version''integer');
  187.         $childTypes->addColumn('primary_types''string');
  188.         $childTypes->addColumn('default_type''string', ['notnull' => false]);
  189.         $childTypes->setPrimaryKey(['id']);
  190.     }
  191.     public function reset()
  192.     {
  193.         if (null === $this->connection) {
  194.             throw new RepositoryException('Do not use RepositorySchema::reset when not instantiated with a connection');
  195.         }
  196.         foreach ($this->toDropSql($this->connection->getDatabasePlatform()) as $sql) {
  197.             try {
  198.                 $this->connection->executeStatement($sql);
  199.             } catch (Exception $exception) {
  200.                 // do nothing
  201.             }
  202.         }
  203.         foreach ($this->toSql($this->connection->getDatabasePlatform()) as $sql) {
  204.             $this->connection->executeStatement($sql);
  205.         }
  206.     }
  207.     private function getMaxIndexLength($currentMaxLength null)
  208.     {
  209.         if (-=== $this->maxIndexLength) {
  210.             $this->maxIndexLength null;
  211.             if ($this->isConnectionCharsetUtf8mb4()) {
  212.                 $this->maxIndexLength 191;
  213.             }
  214.         }
  215.         if ($currentMaxLength && (
  216.             null === $this->maxIndexLength
  217.             || $currentMaxLength $this->maxIndexLength
  218.         )) {
  219.             return $currentMaxLength;
  220.         }
  221.         return $this->maxIndexLength;
  222.     }
  223.     private function isConnectionCharsetUtf8mb4()
  224.     {
  225.         if (!$this->connection) {
  226.             return false;
  227.         }
  228.         $databaseParameters $this->connection->getParams();
  229.         return isset($databaseParameters['charset']) && 'utf8mb4' === strtolower($databaseParameters['charset']);
  230.     }
  231. }