class IntColumnHandlerPostgreSQL in Dynamic Entity Reference 8.2
PostgreSQL implementation of denormalizing into integer columns.
Hierarchy
- class \Drupal\dynamic_entity_reference\Storage\IntColumnHandlerPostgreSQL implements IntColumnHandlerInterface
Expanded class hierarchy of IntColumnHandlerPostgreSQL
1 string reference to 'IntColumnHandlerPostgreSQL'
1 service uses IntColumnHandlerPostgreSQL
File
- src/
Storage/ IntColumnHandlerPostgreSQL.php, line 10
Namespace
Drupal\dynamic_entity_reference\StorageView source
class IntColumnHandlerPostgreSQL implements IntColumnHandlerInterface {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* IntColumnHandlerPostgreSQL constructor.
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection.
*/
public function __construct(Connection $connection) {
$this->connection = $connection;
}
/**
* {@inheritdoc}
*/
public function create($table, array $columns, array $index_columns = []) {
$schema = $this->connection
->schema();
if (!IntColumnHandler::allColumnsExist($schema, $table, $columns)) {
return [];
}
// The integer column specification.
$spec = [
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
];
$new = [];
foreach ($columns as $column) {
$column_int = $column . '_int';
// Make sure the integer columns exist.
if (!$schema
->fieldExists($table, $column_int)) {
$this
->createTriggerFunction($table, $column, $column_int);
$this
->createTrigger($table, $column, $column_int);
$index_fields = [
$column_int,
];
$full_spec = [
'fields' => [
$column_int => $spec,
],
];
if (!empty($index_columns)) {
$full_spec['fields'] = array_merge($full_spec['fields'], $index_columns);
$index_fields = array_merge($index_fields, array_keys($index_columns));
}
$schema
->addField($table, $column_int, $spec);
$schema
->addIndex($table, $column_int, $index_fields, $full_spec);
$new[] = $column_int;
}
}
return $new;
}
/**
* Creates the actual table function.
*
* @param string $table
* The name of the table.
* @param string $column
* The name of the target_id column.
* @param string $column_int
* The name of the target_id_int column.
*/
protected function createTriggerFunction($table, $column, $column_int) {
$function_name = $this
->getFunctionName($table, $column_int);
$query = "CREATE OR REPLACE FUNCTION {$function_name}() RETURNS trigger AS \$\$\n BEGIN\n NEW.{$column_int} = (CASE WHEN NEW.{$column} ~ '^[0-9]+\$' THEN NEW.{$column} ELSE NULL END)::integer";
if (strpos($query, ';') !== FALSE) {
throw new \InvalidArgumentException('; is not supported in SQL strings. Use only one statement at a time.');
}
$this->connection
->query("{$query}; RETURN NEW; END; \$\$ LANGUAGE plpgsql IMMUTABLE RETURNS NULL ON NULL INPUT", [], [
'allow_delimiter_in_query' => TRUE,
'allow_square_brackets' => TRUE,
]);
}
/**
* Creates the trigger.
*
* @param string $table
* The name of the table.
* @param string $column
* The name of the target_id column.
* @param string $column_int
* The name of the target_id_int column.
*/
protected function createTrigger($table, $column, $column_int) {
$function_name = $this
->getFunctionName($table, $column_int);
$prefixed_table = $this
->getPrefixedTable($table);
// It is much easier to just drop and recreate than figuring it out whether
// it exists.
$this->connection
->query("DROP TRIGGER IF EXISTS {$column_int} ON {$prefixed_table}");
$this->connection
->query("\n CREATE TRIGGER {$column_int}\n BEFORE INSERT OR UPDATE\n ON {$prefixed_table}\n FOR EACH ROW\n EXECUTE PROCEDURE {$function_name}();\n ");
}
/**
* Returns an appropriate plpgsql function name.
*
* @param string $table
* The name of the table.
* @param string $column_int
* The name of the target_id_int column.
*
* @return string
* The plpgsql function name.
*/
protected function getFunctionName($table, $column_int) {
return implode('_', [
$this
->getPrefixedTable($table),
$column_int,
]);
}
/**
* Gets the prefxied table name.
*
* @param string $table
* The name of the table.
*
* @return string
* The prefixed table name.
*/
protected function getPrefixedTable($table) {
return trim($this->connection
->prefixTables('{' . $table . '}'), '"');
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
IntColumnHandlerPostgreSQL:: |
protected | property | The database connection. | |
IntColumnHandlerPostgreSQL:: |
public | function |
Creates the _int columns and the triggers for them. Overrides IntColumnHandlerInterface:: |
|
IntColumnHandlerPostgreSQL:: |
protected | function | Creates the trigger. | |
IntColumnHandlerPostgreSQL:: |
protected | function | Creates the actual table function. | |
IntColumnHandlerPostgreSQL:: |
protected | function | Returns an appropriate plpgsql function name. | |
IntColumnHandlerPostgreSQL:: |
protected | function | Gets the prefxied table name. | |
IntColumnHandlerPostgreSQL:: |
public | function | IntColumnHandlerPostgreSQL constructor. |