Tripal
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
Drupal\tripal\TripalDBX\TripalDbxConnection Class Reference
Inheritance diagram for Drupal\tripal\TripalDBX\TripalDbxConnection:
Inheritance graph
[legend]
Collaboration diagram for Drupal\tripal\TripalDBX\TripalDbxConnection:
Collaboration graph
[legend]

Public Member Functions

 findVersion (?string $schema_name=NULL, bool $exact_version=FALSE)
 
 getAvailableInstances ()
 
 __construct (string $schema_name='', $database='default', ?\Drupal\tripal\Services\TripalLogger $logger=NULL)
 
 getDatabaseName ()
 
 getDatabaseKey ()
 
 getMessageLogger ()
 
 setMessageLogger (\Drupal\tripal\Services\TripalLogger $logger)
 
 schema ()
 
 setSchemaName (string $schema_name)
 
 getSchemaName ()
 
 getQuotedSchemaName ()
 
 getExtraSchemas ()
 
 clearExtraSchemas ()
 
 addExtraSchema (string $schema_name)
 
 setExtraSchema (string $schema_name, int $index=2)
 
 getVersion ()
 
 useTripalDbxSchemaFor ($object_or_class)
 
 useDrupalSchemaFor ($object_or_class)
 
 getTripalDbxClass ($class)
 
 shouldUseTripalDbxSchema ()
 
 prefixTables ($sql)
 
 tablePrefix ( $table='default', bool $use_tdbx_schema=FALSE)
 
 getPrefix ()
 
 executeSqlQueries (string $sql_queries, $search_path_mode=FALSE, ?string $schema_name=NULL)
 
 executeSqlFile (string $sql_file_path, $search_path_mode=FALSE, ?string $schema_name=NULL)
 
 escapeTable ($table)
 
 getListClassesUsingTripalDbx ()
 
 __toString ()
 

Protected Member Functions

 getDefaultSchemaName (?string $schema_name=NULL, string $error_message='')
 

Static Protected Member Functions

static openNewPdoConnection (\Drupal\Core\Database\Connection $database)
 

Protected Attributes

 $identifierQuotes
 
 $database = NULL
 
 $databaseName = ''
 
 $dbKey = ''
 
 $usedSchemas = []
 
 $version = NULL
 
 $messageLogger = NULL
 
 $tripalDbxApi = NULL
 
 $objectsUsingTripalDbx = []
 
 $classesUsingTripalDbx = []
 

Detailed Description

Tripal DBX API Connection class.

This class provides a Tripal-specific extension of the Drupal database connection abstract class. It extends the base class with specific functions dedicated to querying separate schema aside from the Drupal schema. It has been designed mostly based on Chado schema and PostgreSQL features allowing you have several schemas in the same database and query across them.

The core functionality provided by extending the core Drupal Connection class is to support additional schema using the {tablename} notation for the Drupal schema, {1: tablename} notation for the current Tripal DBX Managed schema and {2+: tablename} notation for any additional Tripal DBX managed schema.

For example, the following code joins chado feature data between two Tripal DBX managed chado schema and includes a join to the drupal node_field_data table.

$dbxdb = \Drupal::service('tripal_chado.database'); $dbxdb->setSchemaName('chado1'); $dbxdb->addExtraSchema('chado2'); $sql = " SELECT * FROM {1:feature} f1, {2:feature} f2, {node_field_data} fd WHERE fd.title = f1.uniquename AND f1.uniquename = f2.uniquename;"; $results = $dbxdb->query($sql);

Additionally, this class allows you to use the native PHP/Drupal PDO query builder as shown in this next example:

$dbxdb = \Drupal::service('tripal_chado.database'); $query = $dbxdb->select('feature', 'x'); $query->condition('x.is_obsolete', 'f', '='); $query->fields('x', ['name', 'residues']); $query->range(0, 10); $result = $query->execute(); foreach ($result as $record) { // Do something with the $record object here. // e.g. echo $record->name; }

Here are some useful inherited methods to know:

A couple of methods have been added to this class to complete the above list.

NOTE: It has been documented that in some cases extraSchema set in previous connections have been cached. For example, you create $connection1 and set an extraSchema('fred') then when you create a new $connection2, 'fred' may already be set as an extraSchema(). This would be a problem if 2 different parts of code want to use different extra schemas and expect the schema they added to be the second one while it would be the third one for the last one using addExtraSchema(). More work needs to be done to determine the core cause for this.

NOTE: the setLogger() and getLogger() methods are reserved for database query logging and is operated by Drupal. It works with a \Drupal\Core\Database\Log class. To log messages in extending classes, use setMessageLogger() and getMessageLogger() instead, which operates with the \Drupal\tripal\Services\TripalLogger class. By default, the message logger is set by the constructor either using the user-provided logger or by instanciating one using the log channel 'tripal.logger'.

See also
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%21Driver%21pgsql%21Connection.php/class/Connection/9.0.x
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%21Connection.php/class/Connection/9.0.x

Constructor & Destructor Documentation

◆ __construct()

Drupal\tripal\TripalDBX\TripalDbxConnection::__construct ( string  $schema_name = '',
  $database = 'default',
?\Drupal\tripal\Services\TripalLogger  $logger = NULL 
)

Constructor for a Tripal DBX connection.

Parameters
string$schema_nameThe Tripal DBX managed schema name to use. Default: '' (no schema). It will throw exceptions on methods needing a default schema but may work on others or when a schema can be passed as parameter.
\Drupal\Core\Database\Connection | string$databaseEither a \Drupal\Core\Database\Connection instance or a Drupal database key string (from current site's settings.php). Extra databases specified in settings.php do not need to specify a schema name as a database prefix parameter. The prefix will be managed by this connection class instance.
\Drupal\tripal\Services\TripalLogger?,$loggerA logger in case of operations to log.
Exceptions

Member Function Documentation

◆ __toString()

Drupal\tripal\TripalDBX\TripalDbxConnection::__toString ( )

Implements the magic __toString method.

◆ addExtraSchema()

Drupal\tripal\TripalDBX\TripalDbxConnection::addExtraSchema ( string  $schema_name)

Adds an extra schema to the list and returns its query index.

Parameters
string$schema_nameA user-provided schema name from current database. There must be a non-empty "current schema" set by ::setSchemaName before adding an extra-schema.
Returns
int The extra schema index that can be used in database queries in curly braces using the syntax '{index:table_name}' (where 'index' should be replaced by the returned integer and table_name should be an actual table name).
Exceptions

◆ clearExtraSchemas()

Drupal\tripal\TripalDBX\TripalDbxConnection::clearExtraSchemas ( )

Clears the extra schemas list.

◆ escapeTable()

Drupal\tripal\TripalDBX\TripalDbxConnection::escapeTable (   $table)

Escapes a table name string.

OVERRIDES \Drupal\Core\Database\Connection:escapeTable().

This function is meant to force all table names to be strictly alphanumeric-plus-underscore. According to the Drupal documentation, database drivers should never wrap the table name in database-specific escape characters.

We have a different use case however, as we need to add prefixes to our table names based on schema which is indicated using a numerical indicator before the table name (i.e. '2:'' for the second schema).

As such, we need to prefix the table names now to ensure that information is not lost as the parent:escapeTable() method removes the ':'.

Parameters
string$tableThe value within the curley brackets (i.e. '{2:feature}').
Returns
string The sanitized version of the table name. For Tripal DBX managed schema this will include the schema prefix (e.g. 'chado2.feature').

◆ executeSqlFile()

Drupal\tripal\TripalDBX\TripalDbxConnection::executeSqlFile ( string  $sql_file_path,
  $search_path_mode = FALSE,
?string  $schema_name = NULL 
)

Executes all the SQL statements from a given file into the given schema.

This method uses ::executeSqlQueries methods and have the same security concerns. Please read ::executeSqlQueries description.

Parameters
string$sql_queriesA list of SQL queries to execute.
$search_path_modeIf set to an empty value or FALSE, no search_path is changed. If set to 'none', all "SET search_path" queries are removed from the SQL queries provided. If set to an array, keys are schema names to replace in every "SET search_path" by their corresponding values. Default: FALSE.
Returns
bool Whether the application succeeded.
Exceptions

◆ executeSqlQueries()

Drupal\tripal\TripalDBX\TripalDbxConnection::executeSqlQueries ( string  $sql_queries,
  $search_path_mode = FALSE,
?string  $schema_name = NULL 
)

Executes all the given SQL statements into the current schema.

For security reasons, only trusted SQL statments should be provided to this method. No user-provided queries should be able, in any way, to reach to this method. Use this method with caution as it is not as secure as the regular ::query method.

If no schema was set for this instance, the search_path will not be altered and queries will be run using the current search_path. If a schema has been set, the search_path will be altered to only use that schema during the queries. If $search_path_mode is set to 'none', any "SET search_path =...;" in $sql_queries not followed by a comment '–KEEP' will be removed. If $search_path_mode is set to an array, each key would be considered as a schema name and each corresponding value will be considered as the schema name to use in replacement in every "SET search_path" queries not followed by "--KEEP".

Parameters
string$sql_queriesA list of SQL queries to execute.
$search_path_modeIf set to an empty value or FALSE, no search_path is changed. If set to 'none', all "SET search_path" queries are removed from the SQL queries provided. If set to an array, keys are schema names to replace in every "SET search_path" by their corresponding values. Default: FALSE.
?string$schema_name Name of the schema. Default NULL to use current schema.
Returns
bool Whether the application succeeded.
Exceptions

◆ findVersion()

Drupal\tripal\TripalDBX\TripalDbxConnection::findVersion ( ?string  $schema_name = NULL,
bool  $exact_version = FALSE 
)
abstract

Returns the version number of the given Tripal DBX managed schema.

Parameters
?string$schema_name A schema name or NULL to work on current schema.
bool$exact_versionReturns the most precise version available. Default: FALSE.
Returns
string The version in a simple format like '1.0', '2.3x' or '4.5+' or '0' if the version cannot be guessed but an instance of the Tripal DBX managed schema has been detected or an empty string if the schema does not appear to be an instance of the Tripal DBX managed schema. If $exact_version is FALSE , the returned version must always starts by a number and can be tested against numeric values (ie. ">= 1.2"). If $exact_version is TRUE, the format is free and can start by a letter and hold several dots like 'v1.2.3 alpha'.

Reimplemented in Drupal\tripal_chado\Database\ChadoConnection, and Drupal\Tests\tripal\Kernel\TripalDBX\Subclass\TripalDbxConnectionFake.

◆ getAvailableInstances()

Drupal\tripal\TripalDBX\TripalDbxConnection::getAvailableInstances ( )
abstract

Get the list of available "Tripal DBX Managed schema" instances in current database.

This function returns both PostgreSQL schemas integrated with Tripal and free schemas.

Returns
array An array of available schema keyed by schema name and having the following structure: "schema_name": name of the schema (same as the key); "version": detected version of the Tripal DBX managed schema; "is_test": TRUE if it is a test schema and FALSE otherwise; "has_data": TRUE if the schema contains more than just default records; "size": size of the schema in bytes; "is_integrated": FALSE if not integrated with Tripal and an array otherwise with the following fields: 'install_id', 'schema_name', 'version', 'created', 'updated'.

Reimplemented in Drupal\tripal_chado\Database\ChadoConnection, and Drupal\Tests\tripal\Kernel\TripalDBX\Subclass\TripalDbxConnectionFake.

◆ getDatabaseKey()

Drupal\tripal\TripalDBX\TripalDbxConnection::getDatabaseKey ( )

Returns current database key in Drupal settings if one.

Returns
string Database key in Drupal settings or an empty string if none.

◆ getDatabaseName()

Drupal\tripal\TripalDBX\TripalDbxConnection::getDatabaseName ( )

Returns current database name.

Returns
string Current schema name.

◆ getDefaultSchemaName()

Drupal\tripal\TripalDBX\TripalDbxConnection::getDefaultSchemaName ( ?string  $schema_name = NULL,
string  $error_message = '' 
)
protected

Returns either the user provided schema name or current schema name.

Helper function. If $schema_name is not empty, its name will be checked and returned, otherwise, the default schema name will be returned if set. If none of those are available, an error is thrown.

Parameters
?string$schema_name A user-provided schema name.
string$error_messageAn error message to throw if none of $schema_name and $this->usedSchemas[1] are set. Default: 'Invalid schema name.'
Returns
string $schema_name if set and valid, or the current schema name.
Exceptions

◆ getExtraSchemas()

Drupal\tripal\TripalDBX\TripalDbxConnection::getExtraSchemas ( )

Returns the ordered list of extra schema currently in use.

Returns
array An ordered list of schema names. Note: returned schemas array starts from 2 as 0 and 1 indices are reserved (respectively) to Drupal schema and current schema.

◆ getListClassesUsingTripalDbx()

Drupal\tripal\TripalDBX\TripalDbxConnection::getListClassesUsingTripalDbx ( )

Retrieve a list of classes which are using Tripal DBX byb default.

Returns
array An array of class names including namespace.

◆ getMessageLogger()

Drupal\tripal\TripalDBX\TripalDbxConnection::getMessageLogger ( )

Returns current message logger.

Note: the setLogger() and getLogger() methods are reserved for database query logging and is operated by Drupal. It works with a \Drupal\Core\Database\Log class. To log messages in extending classes, use setMessageLogger() and getMessageLogger() instead, which operates with the \Drupal\tripal\Services\TripalLogger class. By default, the message logger is set by the constructor either using the user-provided logger or by instanciating one using the log channel 'tripal.logger'.

Returns
\Drupal\tripal\Services\TripalLogger A message logger.

◆ getPrefix()

Drupal\tripal\TripalDBX\TripalDbxConnection::getPrefix ( )

Returns the prefix of the tables.

OVERRIDES \Drupal\Core\Database\Connection:getPrefix().

Returns
string $prefix

◆ getQuotedSchemaName()

Drupal\tripal\TripalDBX\TripalDbxConnection::getQuotedSchemaName ( )

Returns current Tripal DBX managed schema name quoted for PostgreSQL queries.

This getter should rarely be used (and in very specific cases). If the schema name does not contain any special characters, it might not require any quote and returned quoted name will be the same as $schemaName. The quoted schema name is only needed when writing special SQL queries that need to qualify database objects with a schema name. The quoted schema name must not be used as a field value in SQL queries. For instance, the quoted schema name will be used to prefix a function:

$sql = 'SELECT ' . $quotedSchemaName . '.some_sql_function();';

but it MUST NOT be used in these kinds of situation:

// This is WRONG:
$sql = 'SELECT * FROM pg_tables WHERE schemaname = ' . $quotedSchemaName;
Returns
string Current Tripal DBX managed schema name quoted by PostgreSQL if necessary or an empty string if not set.

◆ getSchemaName()

Drupal\tripal\TripalDBX\TripalDbxConnection::getSchemaName ( )

Returns current Tripal DBX managed schema name.

Returns
string Current Tripal DBX managed schema name or an empty string if not set.

◆ getTripalDbxClass()

Drupal\tripal\TripalDBX\TripalDbxConnection::getTripalDbxClass (   $class)

Gets the Tripal DBX-specific class for the specified category.

Returns the Tripal DBX-specific override class if any for the specified class category.

Parameters
string$classThe class category for which we want the specific class.
Returns
string The name of the class that should be used.

Reimplemented in Drupal\tripal_chado\Database\ChadoConnection, and Drupal\Tests\tripal\Kernel\TripalDBX\Subclass\TripalDbxConnectionFake.

◆ getVersion()

Drupal\tripal\TripalDBX\TripalDbxConnection::getVersion ( )

Get current schema version.

Note: do not confuse this method with the inherited ::version() method that returns the version of the database server.

Returns
string A schema version or an empty string, just like findVersion.
See also
::findVersion

◆ openNewPdoConnection()

static Drupal\tripal\TripalDBX\TripalDbxConnection::openNewPdoConnection ( \Drupal\Core\Database\Connection  $database)
staticprotected

Opens a new connection using the same settings as the provided one.

Drupal Database class only opens new connection to a database when it is "necessary", which means when a connection to the database is not opened already. However, in the context of a TripalDbxConnection, we need a different database context for each connection since the search_path may be changed. To not mess up with Drupal stuff, we need to open a new and distinct database connection for each TripalDbxConnection instance.

Parameters
\Drupal\Core\Database\Connection$databaseThe database connection to duplicate.
Returns
\PDO A \PDO object.

◆ prefixTables()

Drupal\tripal\TripalDBX\TripalDbxConnection::prefixTables (   $sql)

Appends a database prefix to all tables in a query.

OVERRIDES \Drupal\Core\Database\Connection:prefixTables().

This API expects all table names to be wrapped in curly brackets with an integer indicating the schema the table is in. For example, {1: feature} would indicate the feature table in the current Tripal DBX managed schema, {0: system} would indicate the drupal system table and additional numeric indices would be used for extra Tripal DBX managed schema.

For Example, lets say the schema name of the current TripalDBX managed schema is "chado", Drupal is in the "public" schema and we have a second Tripal DBX managed schema named "genotypes".

Now assume the following query was submitted to this function: SELECT f.name as marker_name, g.allele FROM {1: feature} f LEFT JOIN {2: genotype_call} g ON g.marker_id = f.feature_id WHERE f.uniquename = 'MarkerICareAbout'

Then the returned, properly prefixed query would be: SELECT f.name as marker_name, g.allele FROM chado.feature f LEFT JOIN genotypes.genotype_call g ON g.marker_id = f.feature_id WHERE f.uniquename = 'MarkerICareAbout'

Parameters
string$sqlA string containing a partial or complete SQL query.
Returns
string The same query passed in but now with properly prefixed table names.

◆ schema()

Drupal\tripal\TripalDBX\TripalDbxConnection::schema ( )

Returns a Schema object for manipulating the schema.

OVERRIDES \Drupal\Core\Database\Connection:schema()

This method overrides the parent one in order to force the use of the \Drupal\tripal\TripalDBX\TripalDbxSchema class and manage Tripal DBX managed schema changes for this connection. The Schema object is updated on changes.

Returns
\Drupal\Core\Database\Schema The database Schema object for this connection.

◆ setExtraSchema()

Drupal\tripal\TripalDBX\TripalDbxConnection::setExtraSchema ( string  $schema_name,
int  $index = 2 
)

Adds an extra schema to the list and returns its query index.

Parameters
string$schema_nameA user-provided schema name from current database. There must be a non-empty "current schema" set by ::setSchemaName before adding an extra-schema.
int$indexThe index of the extra schema. Note that '0' is reserved for Drupal schema and 1 for current schema. The first available extra schema index is therefore 2. Using higher values means any lower value has an associated schema set already. Default: 2.
Exceptions

◆ setMessageLogger()

Drupal\tripal\TripalDBX\TripalDbxConnection::setMessageLogger ( \Drupal\tripal\Services\TripalLogger  $logger)

Sets current message logger.

Note: the setLogger() and getLogger() methods are reserved for database query logging and is operated by Drupal. It works with a \Drupal\Core\Database\Log class. To log messages in extending classes, use setMessageLogger() and getMessageLogger() instead, which operates with the \Drupal\tripal\Services\TripalLogger class. By default, the message logger is set by the constructor either using the user-provided logger or by instanciating one using the log channel 'tripal.logger'.

Parameters
\Drupal\tripal\Services\TripalLogger$loggerA message logger.

◆ setSchemaName()

Drupal\tripal\TripalDBX\TripalDbxConnection::setSchemaName ( string  $schema_name)

Sets current Tripal DBX managed schema name.

This method will resets any class member afected by a schema change such as schema version and extra schemas for instance. "No schema name" might be specified using an empty string but calling methods that requires a schema to work on will through errors. The given schema name format will be check and a ConnectionException must be thrown by implementations if the name is incorrect (note: an empty name is allowed).

Parameters
string$schema_nameThe Tripal DBX managed schema name to use.
Exceptions

◆ shouldUseTripalDbxSchema()

Drupal\tripal\TripalDBX\TripalDbxConnection::shouldUseTripalDbxSchema ( )

Tells if the caller assumes current schema is the Tripal DBX managed schema.

Returns
bool TRUE if default schema is not Drupal's but the Tripal DBX managed one.

◆ tablePrefix()

Drupal\tripal\TripalDBX\TripalDbxConnection::tablePrefix (   $table = 'default',
bool  $use_tdbx_schema = FALSE 
)

Find the prefix for a table.

OVERRIDES \Drupal\Core\Database\Connection:tablePrefix(). REMOVED IN Drupal 10.1.x SEE https://www.drupal.org/node/3260849

This function is for when you want to know the prefix of a table. This is not used in prefixTables due to performance reasons.

This override adds the support for Tripal DBX managed schema tables by returning the prefix used for a table in a Tripal DBX managed schema if applicable.

This override adds the optional $use_tdbx_schema parameter which defaults to False to maintain backwards compatibility for non-cross-schema-aware queries. Additionally, there is support through this API with this function and prefixTables() for non-prefixed tables (i.e. {tablename}) to be used for both Drupal and Chado tables depending on the situation.

There are a couple of ways to use this. Call this function with: A) $table matching to the index you would use for your Tripal DBX managed schema (i.e. 0: drupal, 1:current, 2+:extra in order added). This would return the expected prefix used by Tripal DBX (e.g. "chado.") B) $myinstance->tablePrefix('default', TRUE). This would return the Tripal DBX prefix of the current schema (i.e. index 1). C) a Drupal table name only (i.e. $use_tdbx_schema = FALSE) not realizing it's been overriden and get the Drupal table prefix. (Backwards Compatible) D) any table name and $use_tdbx_schema = TRUE and get the prefix for the current Tripal DBX Managed schema.

NOTE: This function does not support Drupal per-table prefixing. While Drupal supported this originally, it has been deprecated in Drupal 8.3 according to https://www.drupal.org/project/drupal/issues/2551549

Parameters
string$table(optional) The table to find the prefix for.
bool$use_tdbx_schema(optional) if TRUE, table will be prefixed with the Tripal DBX managed schema name (if not empty).
Returns
string The prefix that would be used for a table in the specified schema.

◆ useDrupalSchemaFor()

Drupal\tripal\TripalDBX\TripalDbxConnection::useDrupalSchemaFor (   $object_or_class)

Remove the given things from the lists using Tripal DBX managed schema as default.

Parameters
string|objectObject or class to unregister.

◆ useTripalDbxSchemaFor()

Drupal\tripal\TripalDBX\TripalDbxConnection::useTripalDbxSchemaFor (   $object_or_class)

Use the Tripal DBX managed schema as default for the given things.

Register an object or a class to make them use the Tripal DBX managed schema as default in any method of this instance of TripalDbxConnection.

Parameters
string|objectObject or class to register.

Member Data Documentation

◆ $identifierQuotes

Drupal\tripal\TripalDBX\TripalDbxConnection::$identifierQuotes
protected

{}


The documentation for this class was generated from the following file: