File manager - Edit - /home/opticamezl/www/newok/Pgsql.zip
Back
PK 9?�\ � 7| | PgsqlQuery.phpnu �[��� <?php /** * Part of the Joomla Framework Database Package * * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Database\Pgsql; use Joomla\Database\Pdo\PdoQuery; use Joomla\Database\Query\PostgresqlQueryBuilder; use Joomla\Database\Query\QueryElement; /** * PDO PostgreSQL Query Building Class. * * @since 1.0 * * @property-read QueryElement $forUpdate The FOR UPDATE element used in "FOR UPDATE" lock * @property-read QueryElement $forShare The FOR SHARE element used in "FOR SHARE" lock * @property-read QueryElement $noWait The NOWAIT element used in "FOR SHARE" and "FOR UPDATE" lock * @property-read QueryElement $returning The RETURNING element of INSERT INTO */ class PgsqlQuery extends PdoQuery { use PostgresqlQueryBuilder; /** * The list of zero or null representation of a datetime. * * @var array * @since 2.0.0 */ protected $nullDatetimeList = ['1970-01-01 00:00:00']; /** * Casts a value to a char. * * Ensure that the value is properly quoted before passing to the method. * * Usage: * $query->select($query->castAsChar('a')); * $query->select($query->castAsChar('a', 40)); * * @param string $value The value to cast as a char. * @param string $length The length of the char. * * @return string Returns the cast value. * * @since 1.8.0 */ public function castAsChar($value, $length = null) { if ((int) $length < 1) { return $value . '::text'; } return 'CAST(' . $value . ' AS CHAR(' . $length . '))'; } } PK 9?�\ ��� � PgsqlExporter.phpnu �[��� <?php /** * Part of the Joomla Framework Database Package * * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Database\Pgsql; use Joomla\Database\DatabaseExporter; /** * PDO PostgreSQL Database Exporter. * * @since 1.5.0 */ class PgsqlExporter extends DatabaseExporter { /** * Builds the XML data for the tables to export. * * @return string An XML string * * @since 1.0 * @throws \Exception if an error occurs. */ protected function buildXml() { $buffer = []; $buffer[] = '<?xml version="1.0"?>'; $buffer[] = '<postgresqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'; $buffer[] = ' <database name="">'; if ($this->options->withStructure) { $buffer = array_merge($buffer, $this->buildXmlStructure()); } if ($this->options->withData) { $buffer = array_merge($buffer, $this->buildXmlData()); } $buffer[] = ' </database>'; $buffer[] = '</postgresqldump>'; return implode("\n", $buffer); } /** * Builds the XML structure to export. * * @return array An array of XML lines (strings). * * @since 1.0 * @throws \Exception if an error occurs. */ protected function buildXmlStructure() { $buffer = []; foreach ($this->from as $table) { // Replace the magic prefix if found. $table = $this->getGenericTableName($table); // Get the details columns information. $fields = $this->db->getTableColumns($table, false); $keys = $this->db->getTableKeys($table); $sequences = $this->db->getTableSequences($table); $buffer[] = ' <table_structure name="' . $table . '">'; foreach ($sequences as $sequence) { $buffer[] = ' <sequence Name="' . $this->getGenericTableName($sequence->sequence) . '" Schema="' . $sequence->schema . '"' . ' Table="' . $table . '" Column="' . $sequence->column . '" Type="' . $sequence->data_type . '"' . ' Start_Value="' . $sequence->start_value . '" Min_Value="' . $sequence->minimum_value . '"' . ' Max_Value="' . $sequence->maximum_value . '" Last_Value="' . $this->db->getSequenceLastValue($sequence->sequence) . '"' . ' Increment="' . $sequence->increment . '" Cycle_option="' . $sequence->cycle_option . '"' . ' Is_called="' . $this->db->getSequenceIsCalled($sequence->sequence) . '"' . ' />'; } foreach ($fields as $field) { $buffer[] = ' <field Field="' . $field->column_name . '" Type="' . $field->type . '" Null="' . $field->null . '"' . ' Default="' . $field->Default . '" Comments="' . $field->comments . '" />'; } foreach ($keys as $key) { $buffer[] = ' <key Index="' . $this->getGenericTableName($key->idxName) . '" is_primary="' . $key->isPrimary . '"' . ' is_unique="' . $key->isUnique . '" Key_name="' . $this->db->getNamesKey($table, $key->indKey) . '"' . ' Query=\'' . $key->Query . '\' />'; } $buffer[] = ' </table_structure>'; } return $buffer; } /** * Builds the XML data to export. * * @return array An array of XML lines (strings). * * @since 2.0.0 * @throws \Exception if an error occurs. */ protected function buildXmlData() { $buffer = []; foreach ($this->from as $table) { // Replace the magic prefix if found. $table = $this->getGenericTableName($table); // Get the details columns information. $fields = $this->db->getTableColumns($table, false); $colblob = []; foreach ($fields as $field) { // Catch blob for xml conversion // PostgreSQL binary large object type if ($field->Type == 'bytea') { $colblob[] = $field->Field; } } $query = $this->db->getQuery(true); $query->select($query->quoteName(array_keys($fields))) ->from($query->quoteName($table)); $this->db->setQuery($query); $rows = $this->db->loadObjectList(); if (!count($rows)) { continue; } $buffer[] = ' <table_data name="' . $table . '">'; foreach ($rows as $row) { $buffer[] = ' <row>'; foreach ($row as $key => $value) { if (!in_array($key, $colblob)) { $buffer[] = ' <field name="' . $key . '">' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '</field>'; } else { $buffer[] = ' <field name="' . $key . '">' . stream_get_contents($value) . '</field>'; } } $buffer[] = ' </row>'; } $buffer[] = ' </table_data>'; } return $buffer; } /** * Checks if all data and options are in order prior to exporting. * * @return $this * * @since 1.5.0 * @throws \RuntimeException */ public function check() { // Check if the db connector has been set. if (!($this->db instanceof PgsqlDriver)) { throw new \RuntimeException('Database connection wrong type.'); } // Check if the tables have been specified. if (empty($this->from)) { throw new \RuntimeException('ERROR: No Tables Specified'); } return $this; } } PK 9?�\ ���p �p PgsqlDriver.phpnu �[��� <?php /** * Part of the Joomla Framework Database Package * * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Database\Pgsql; use Joomla\Database\Pdo\PdoDriver; /** * PostgreSQL PDO Database Driver * * @since 1.5.0 */ class PgsqlDriver extends PdoDriver { /** * The database driver name * * @var string * @since 1.5.0 */ public $name = 'pgsql'; /** * The character(s) used to quote SQL statement names such as table names or field names, * etc. The child classes should define this as necessary. If a single character string the * same character is used for both sides of the quoted name, else the first character will be * used for the opening quote and the second for the closing quote. * * @var string * @since 1.5.0 */ protected $nameQuote = '"'; /** * The null or zero representation of a timestamp for the database driver. This should be * defined in child classes to hold the appropriate value for the engine. * * @var string * @since 1.5.0 */ protected $nullDate = '1970-01-01 00:00:00'; /** * The minimum supported database version. * * @var string * @since 1.5.0 */ protected static $dbMinimum = '9.4.0'; /** * Operator used for concatenation * * @var string * @since 1.5.0 */ protected $concat_operator = '||'; /** * Database object constructor * * @param array $options List of options used to configure the connection * * @since 1.5.0 */ public function __construct($options) { $options['driver'] = 'pgsql'; $options['host'] = $options['host'] ?? 'localhost'; $options['user'] = $options['user'] ?? ''; $options['password'] = $options['password'] ?? ''; $options['database'] = $options['database'] ?? ''; $options['port'] = $options['port'] ?? null; // Finalize initialization parent::__construct($options); } /** * Connects to the database if needed. * * @return void * * @since 1.5.0 * @throws \RuntimeException */ public function connect() { if ($this->getConnection()) { return; } parent::connect(); $this->setQuery('SET standard_conforming_strings = off')->execute(); } /** * Method to get the database collation in use by sampling a text field of a table in the database. * * @return string|boolean The collation in use by the database or boolean false if not supported. * * @since 1.5.0 * @throws \RuntimeException */ public function getCollation() { $this->setQuery('SHOW LC_COLLATE'); $array = $this->loadAssocList(); return $array[0]['lc_collate']; } /** * Method to get the database connection collation in use by sampling a text field of a table in the database. * * @return string|boolean The collation in use by the database connection (string) or boolean false if not supported. * * @since 1.6.0 * @throws \RuntimeException */ public function getConnectionCollation() { $this->setQuery('SHOW LC_COLLATE'); $array = $this->loadAssocList(); return $array[0]['lc_collate']; } /** * Method to get the database encryption details (cipher and protocol) in use. * * @return string The database encryption details. * * @since 2.0.0 * @throws \RuntimeException */ public function getConnectionEncryption(): string { // Requires PostgreSQL 9.5 or newer if (version_compare($this->getVersion(), '9.5', '<')) { return ''; } $query = $this->createQuery() ->select($this->quoteName(['version', 'cipher'])) ->from($this->quoteName('pg_stat_ssl')) ->where($this->quoteName('pid') . ' = pg_backend_pid()'); $variables = $this->setQuery($query)->loadAssoc(); if (!empty($variables['cipher'])) { return $variables['version'] . ' (' . $variables['cipher'] . ')'; } return ''; } /** * Method to test if the database TLS connections encryption are supported. * * @return boolean Whether the database supports TLS connections encryption. * * @since 2.0.0 */ public function isConnectionEncryptionSupported(): bool { $variables = $this->setQuery('SHOW "ssl"')->loadAssoc(); return !empty($variables['ssl']) && $variables['ssl'] === 'on'; } /** * Internal function to get the name of the default schema for the current PostgreSQL connection. * That is the schema where tables are created by Joomla. * * @return string * * @since 1.8.0 */ private function getDefaultSchema() { // Supported since PostgreSQL 7.3 $this->setQuery('SELECT (current_schemas(false))[1]'); return $this->loadResult(); } /** * Shows the table CREATE statement that creates the given tables. * * This is unsupported by PostgreSQL. * * @param mixed $tables A table name or a list of table names. * * @return string An empty string because this function is not supported by PostgreSQL. * * @since 1.5.0 * @throws \RuntimeException */ public function getTableCreate($tables) { return ''; } /** * Retrieves field information about a given table. * * @param string $table The name of the database table. * @param boolean $typeOnly True to only return field types. * * @return array An array of fields for the database table. * * @since 1.5.0 * @throws \RuntimeException */ public function getTableColumns($table, $typeOnly = true) { $this->connect(); $result = []; $tableSub = $this->replacePrefix($table); $defaultSchema = $this->getDefaultSchema(); $this->setQuery(' SELECT a.attname AS "column_name", pg_catalog.format_type(a.atttypid, a.atttypmod) as "type", CASE WHEN a.attnotnull IS TRUE THEN \'NO\' ELSE \'YES\' END AS "null", CASE WHEN pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, true) IS NOT NULL THEN pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, true) END as "Default", CASE WHEN pg_catalog.col_description(a.attrelid, a.attnum) IS NULL THEN \'\' ELSE pg_catalog.col_description(a.attrelid, a.attnum) END AS "comments" FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef adef ON a.attrelid=adef.adrelid AND a.attnum=adef.adnum LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid WHERE a.attrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname=' . $this->quote($tableSub) . ' AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = ' . $this->quote($defaultSchema) . ') ) AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum' ); $fields = $this->loadObjectList(); if ($typeOnly) { foreach ($fields as $field) { $result[$field->column_name] = preg_replace('/[(0-9)]/', '', $field->type); } } else { foreach ($fields as $field) { if ($field->Default !== null) { // Normalise default values like datetime if (preg_match('/^\'(.*)\'::.*/', $field->Default, $matches)) { $field->Default = $matches[1]; } // Change Postgresql's NULL::* type with PHP's null one. Do this last to avoid PHP type issues in PHP 8.1 and up if (preg_match('/^NULL::*/', $field->Default)) { $field->Default = null; } } // Do some dirty translation to MySQL output. // @todo: Come up with and implement a standard across databases. $result[$field->column_name] = (object) [ 'column_name' => $field->column_name, 'type' => $field->type, 'null' => $field->null, 'Default' => $field->Default, 'comments' => '', 'Field' => $field->column_name, 'Type' => $field->type, 'Null' => $field->null, // @todo: Improve query above to return primary key info as well // 'Key' => ($field->PK == '1' ? 'PRI' : '') ]; } } return $result; } /** * Get the details list of keys for a table. * * @param string $table The name of the table. * * @return array An array of the column specification for the table. * * @since 1.5.0 * @throws \RuntimeException */ public function getTableKeys($table) { $this->connect(); // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); if (\in_array($tableSub, $tableList, true)) { // Get the details columns information. $this->setQuery(' SELECT indexname AS "idxName", indisprimary AS "isPrimary", indisunique AS "isUnique", indkey AS "indKey", CASE WHEN indisprimary = true THEN ( SELECT \'ALTER TABLE \' || tablename || \' ADD \' || pg_catalog.pg_get_constraintdef(const.oid, true) FROM pg_constraint AS const WHERE const.conname= pgClassFirst.relname ) ELSE pg_catalog.pg_get_indexdef(indexrelid, 0, true) END AS "Query" FROM pg_indexes LEFT JOIN pg_class AS pgClassFirst ON indexname=pgClassFirst.relname LEFT JOIN pg_index AS pgIndex ON pgClassFirst.oid=pgIndex.indexrelid WHERE tablename=' . $this->quote($tableSub) . ' ORDER BY indkey' ); return $this->loadObjectList(); } return []; } /** * Get the list of column names this index indexes. * * @param string $table The name of the table. * @param string $indKey The list of column numbers for the table * * @return string A list of the column names for the table. * * @since 2.0.0 * @throws \RuntimeException */ public function getNamesKey($table, $indKey) { $this->connect(); $tableSub = $this->replacePrefix($table); $tabInd = explode(' ', $indKey); $colNames = []; foreach ($tabInd as $numCol) { $query = $this->createQuery() ->select('attname') ->from('pg_attribute') ->join('LEFT', 'pg_class ON pg_class.relname=' . $this->quote($tableSub)) ->where('attnum=' . $numCol . ' AND attrelid=pg_class.oid'); $this->setQuery($query); $colNames[] = $this->loadResult(); } return implode(', ', $colNames); } /** * Method to get an array of all tables in the database. * * @return array An array of all the tables in the database. * * @since 1.5.0 * @throws \RuntimeException */ public function getTableList() { $query = $this->createQuery() ->select('table_name') ->from('information_schema.tables') ->where('table_type = ' . $this->quote('BASE TABLE')) ->where('table_schema NOT IN (' . $this->quote('pg_catalog') . ', ' . $this->quote('information_schema') . ')') ->order('table_name ASC'); $this->setQuery($query); return $this->loadColumn(); } /** * Get the details list of sequences for a table. * * @param string $table The name of the table. * * @return array An array of sequences specification for the table. * * @since 1.5.0 * @throws \RuntimeException */ public function getTableSequences($table) { // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); if (\in_array($tableSub, $tableList, true)) { $name = [ 's.relname', 'n.nspname', 't.relname', 'a.attname', 'info.data_type', 'info.minimum_value', 'info.maximum_value', 'info.increment', 'info.cycle_option', 'info.start_value', ]; $as = [ 'sequence', 'schema', 'table', 'column', 'data_type', 'minimum_value', 'maximum_value', 'increment', 'cycle_option', 'start_value', ]; // Get the details columns information. $query = $this->createQuery() ->select($this->quoteName($name, $as)) ->from('pg_class AS s') ->leftJoin("pg_depend d ON d.objid = s.oid AND d.classid = 'pg_class'::regclass AND d.refclassid = 'pg_class'::regclass") ->leftJoin('pg_class t ON t.oid = d.refobjid') ->leftJoin('pg_namespace n ON n.oid = t.relnamespace') ->leftJoin('pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid') ->leftJoin('information_schema.sequences AS info ON info.sequence_name = s.relname') ->where('s.relkind = ' . $this->quote('S') . ' AND d.deptype = ' . $this->quote('a') . ' AND t.relname = ' . $this->quote($tableSub)); $this->setQuery($query); return $this->loadObjectList(); } return []; } /** * Method to get the last value of a sequence in the database. * * @param string $sequence The name of the sequence. * * @return integer The last value of the sequence. * * @since 2.0.0 * @throws \RuntimeException */ public function getSequenceLastValue($sequence) { $this->connect(); $query = $this->createQuery() ->select($this->quoteName('last_value')) ->from($sequence); $this->setQuery($query); return $this->loadResult(); } /** * Method to get the is_called attribute of a sequence. * * @param string $sequence The name of the sequence. * * @return boolean The is_called attribute of the sequence. * * @since 2.0.0 * @throws \RuntimeException */ public function getSequenceIsCalled($sequence) { $this->connect(); $query = $this->createQuery() ->select($this->quoteName('is_called')) ->from($sequence); $this->setQuery($query); return $this->loadResult(); } /** * Locks a table in the database. * * @param string $tableName The name of the table to unlock. * * @return $this * * @since 1.5.0 * @throws \RuntimeException */ public function lockTable($tableName) { $this->transactionStart(); $this->setQuery('LOCK TABLE ' . $this->quoteName($tableName) . ' IN ACCESS EXCLUSIVE MODE')->execute(); return $this; } /** * Renames a table in the database. * * @param string $oldTable The name of the table to be renamed * @param string $newTable The new name for the table. * @param string $backup Not used by PostgreSQL. * @param string $prefix Not used by PostgreSQL. * * @return $this * * @since 1.5.0 * @throws \RuntimeException */ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) { $this->connect(); $oldTable = $this->replacePrefix($oldTable); $newTable = $this->replacePrefix($newTable); // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); // Origin Table does not exist if (!\in_array($oldTable, $tableList, true)) { // Origin Table not found throw new \RuntimeException('Table not found in Postgresql database.'); } // Rename indexes $subQuery = $this->createQuery() ->select('indexrelid') ->from('pg_index, pg_class') ->where('pg_class.relname = ' . $this->quote($oldTable)) ->where('pg_class.oid = pg_index.indrelid'); $this->setQuery( $this->createQuery() ->select('relname') ->from('pg_class') ->where('oid IN (' . (string) $subQuery . ')') ); $oldIndexes = $this->loadColumn(); foreach ($oldIndexes as $oldIndex) { $changedIdxName = str_replace($oldTable, $newTable, $oldIndex); $this->setQuery('ALTER INDEX ' . $this->escape($oldIndex) . ' RENAME TO ' . $this->escape($changedIdxName))->execute(); } // Rename sequences $subQuery = $this->createQuery() ->select('oid') ->from('pg_namespace') ->where('nspname NOT LIKE ' . $this->quote('pg_%')) ->where('nspname != ' . $this->quote('information_schema')); $this->setQuery( $this->createQuery() ->select('relname') ->from('pg_class') ->where('relkind = ' . $this->quote('S')) ->where('relnamespace IN (' . (string) $subQuery . ')') ->where('relname LIKE ' . $this->quote("%$oldTable%")) ); $oldSequences = $this->loadColumn(); foreach ($oldSequences as $oldSequence) { $changedSequenceName = str_replace($oldTable, $newTable, $oldSequence); $this->setQuery('ALTER SEQUENCE ' . $this->escape($oldSequence) . ' RENAME TO ' . $this->escape($changedSequenceName))->execute(); } // Rename table $this->setQuery('ALTER TABLE ' . $this->escape($oldTable) . ' RENAME TO ' . $this->escape($newTable))->execute(); return $this; } /** * This function return a field value as a prepared string to be used in a SQL statement. * * @param array $columns Array of table's column returned by ::getTableColumns. * @param string $fieldName The table field's name. * @param string $fieldValue The variable value to quote and return. * * @return string The quoted string. * * @since 1.5.0 */ public function sqlValue($columns, $fieldName, $fieldValue) { switch ($columns[$fieldName]) { case 'boolean': $val = 'NULL'; if ($fieldValue === 't' || $fieldValue === true || $fieldValue === 1 || $fieldValue === '1') { $val = 'TRUE'; } elseif ($fieldValue === 'f' || $fieldValue === false || $fieldValue === 0 || $fieldValue === '0') { $val = 'FALSE'; } break; case 'bigint': case 'bigserial': case 'integer': case 'money': case 'numeric': case 'real': case 'smallint': case 'serial': case 'numeric,': $val = $fieldValue === '' ? 'NULL' : $fieldValue; break; case 'timestamp without time zone': case 'date': if (empty($fieldValue)) { $fieldValue = $this->getNullDate(); } $val = $this->quote($fieldValue); break; default: $val = $this->quote($fieldValue); break; } return $val; } /** * Method to commit a transaction. * * @param boolean $toSavepoint If true, commit to the last savepoint. * * @return void * * @since 1.0 * @throws \RuntimeException */ public function transactionCommit($toSavepoint = false) { $this->connect(); if (!$toSavepoint || $this->transactionDepth <= 1) { parent::transactionCommit($toSavepoint); } else { $this->transactionDepth--; } } /** * Method to roll back a transaction. * * @param boolean $toSavepoint If true, rollback to the last savepoint. * * @return void * * @since 1.0 * @throws \RuntimeException */ public function transactionRollback($toSavepoint = false) { $this->connect(); if (!$toSavepoint || $this->transactionDepth <= 1) { parent::transactionRollback($toSavepoint); } else { $savepoint = 'SP_' . ($this->transactionDepth - 1); $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); if ($this->execute()) { $this->transactionDepth--; $this->setQuery('RELEASE SAVEPOINT ' . $this->quoteName($savepoint))->execute(); } } } /** * Method to initialize a transaction. * * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. * * @return void * * @since 1.0 * @throws \RuntimeException */ public function transactionStart($asSavepoint = false) { $this->connect(); if (!$asSavepoint || !$this->transactionDepth) { parent::transactionStart($asSavepoint); } else { $savepoint = 'SP_' . $this->transactionDepth; $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); if ($this->execute()) { $this->transactionDepth++; } } } /** * Inserts a row into a table based on an object's properties. * * @param string $table The name of the database table to insert into. * @param object $object A reference to an object whose public properties match the table fields. * @param string $key The name of the primary key. If provided the object property is updated. * * @return boolean True on success. * * @since 1.5.0 * @throws \RuntimeException */ public function insertObject($table, &$object, $key = null) { $columns = $this->getTableColumns($table); $fields = []; $values = []; // Iterate over the object variables to build the query fields and values. foreach (get_object_vars($object) as $k => $v) { // Skip columns that don't exist in the table. if (!\array_key_exists($k, $columns)) { continue; } // Only process non-null scalars. if (\is_array($v) || \is_object($v) || $v === null) { continue; } // Ignore any internal fields or primary keys with value 0. if (($k[0] === '_') || ($k == $key && (($v === 0) || ($v === '0')))) { continue; } // Ignore null timestamp fields. if ($columns[$k] === 'timestamp without time zone' && empty($v)) { continue; } // Prepare and sanitize the fields and values for the database query. $fields[] = $this->quoteName($k); $values[] = $this->sqlValue($columns, $k, $v); } // Create the base insert statement. $query = $this->createQuery(); $query->insert($this->quoteName($table)) ->columns($fields) ->values(implode(',', $values)); if ($key) { $query->returning($key); // Set the query and execute the insert. $object->$key = $this->setQuery($query)->loadResult(); } else { // Set the query and execute the insert. $this->setQuery($query)->execute(); } return true; } /** * Test to see if the PostgreSQL connector is available. * * @return boolean True on success, false otherwise. * * @since 1.5.0 */ public static function isSupported() { return class_exists('\\PDO') && \in_array('pgsql', \PDO::getAvailableDrivers(), true); } /** * Returns an array containing database's table list. * * @return array The database's table list. * * @since 1.5.0 */ public function showTables() { $query = $this->createQuery() ->select('table_name') ->from('information_schema.tables') ->where('table_type=' . $this->quote('BASE TABLE')) ->where('table_schema NOT IN (' . $this->quote('pg_catalog') . ', ' . $this->quote('information_schema') . ' )'); $this->setQuery($query); return $this->loadColumn(); } /** * Get the substring position inside a string * * @param string $substring The string being sought * @param string $string The string/column being searched * * @return integer The position of $substring in $string * * @since 1.5.0 */ public function getStringPositionSql($substring, $string) { $this->setQuery("SELECT POSITION($substring IN $string)"); $position = $this->loadRow(); return $position['position']; } /** * Generate a random value * * @return float The random generated number * * @since 1.5.0 */ public function getRandom() { $this->setQuery('SELECT RANDOM()'); $random = $this->loadAssoc(); return $random['random']; } /** * Get the query string to alter the database character set. * * @param string $dbName The database name * * @return string The query that alter the database query string * * @since 1.5.0 */ public function getAlterDbCharacterSet($dbName) { return 'ALTER DATABASE ' . $this->quoteName($dbName) . ' SET CLIENT_ENCODING TO ' . $this->quote('UTF8'); } /** * Get the query string to create new Database in correct PostgreSQL syntax. * * @param object $options object coming from "initialise" function to pass user and database name to database driver. * @param boolean $utf True if the database supports the UTF-8 character set, not used in PostgreSQL "CREATE DATABASE" query. * * @return string The query that creates database, owned by $options['user'] * * @since 1.5.0 */ public function getCreateDbQuery($options, $utf) { $query = 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' OWNER ' . $this->quoteName($options->db_user); if ($utf) { $query .= ' ENCODING ' . $this->quote('UTF-8'); } return $query; } /** * This function replaces a string identifier with the configured table prefix. * * @param string $sql The SQL statement to prepare. * @param string $prefix The table prefix. * * @return string The processed SQL statement. * * @since 1.5.0 */ public function replacePrefix($sql, $prefix = '#__') { $sql = trim($sql); if (strpos($sql, '\'')) { // Sequence name quoted with ' ' but need to be replaced if (strpos($sql, 'currval')) { $sql = explode('currval', $sql); for ($nIndex = 1, $nIndexMax = \count($sql); $nIndex < $nIndexMax; $nIndex += 2) { $sql[$nIndex] = str_replace($prefix, $this->tablePrefix, $sql[$nIndex]); } $sql = implode('currval', $sql); } // Sequence name quoted with ' ' but need to be replaced if (strpos($sql, 'nextval')) { $sql = explode('nextval', $sql); for ($nIndex = 1, $nIndexMax = \count($sql); $nIndex < $nIndexMax; $nIndex += 2) { $sql[$nIndex] = str_replace($prefix, $this->tablePrefix, $sql[$nIndex]); } $sql = implode('nextval', $sql); } // Sequence name quoted with ' ' but need to be replaced if (strpos($sql, 'setval')) { $sql = explode('setval', $sql); for ($nIndex = 1, $nIndexMax = \count($sql); $nIndex < $nIndexMax; $nIndex += 2) { $sql[$nIndex] = str_replace($prefix, $this->tablePrefix, $sql[$nIndex]); } $sql = implode('setval', $sql); } $explodedQuery = explode('\'', $sql); for ($nIndex = 0, $nIndexMax = \count($explodedQuery); $nIndex < $nIndexMax; $nIndex += 2) { if (strpos($explodedQuery[$nIndex], $prefix)) { $explodedQuery[$nIndex] = str_replace($prefix, $this->tablePrefix, $explodedQuery[$nIndex]); } } $replacedQuery = implode('\'', $explodedQuery); } else { $replacedQuery = str_replace($prefix, $this->tablePrefix, $sql); } return $replacedQuery; } /** * Unlocks tables in the database, this command does not exist in PostgreSQL, it is automatically done on commit or rollback. * * @return $this * * @since 1.5.0 * @throws \RuntimeException */ public function unlockTables() { $this->transactionCommit(); return $this; } /** * Updates a row in a table based on an object's properties. * * @param string $table The name of the database table to update. * @param object $object A reference to an object whose public properties match the table fields. * @param array|string $key The name of the primary key. * @param boolean $nulls True to update null fields or false to ignore them. * * @return boolean * * @since 1.5.0 * @throws \RuntimeException */ public function updateObject($table, &$object, $key, $nulls = false) { $columns = $this->getTableColumns($table); $fields = []; $where = []; if (\is_string($key)) { $key = [$key]; } if (\is_object($key)) { $key = (array) $key; } // Create the base update statement. $statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s'; // Iterate over the object variables to build the query fields/value pairs. foreach (get_object_vars($object) as $k => $v) { // Skip columns that don't exist in the table. if (!\array_key_exists($k, $columns)) { continue; } // Only process scalars that are not internal fields. if (\is_array($v) || \is_object($v) || $k[0] === '_') { continue; } // Set the primary key to the WHERE clause instead of a field to update. if (\in_array($k, $key, true)) { $key_val = $this->sqlValue($columns, $k, $v); $where[] = $this->quoteName($k) . '=' . $key_val; continue; } // Prepare and sanitize the fields and values for the database query. if ($v === null) { // If the value is null and we do not want to update nulls then ignore this field. if (!$nulls) { continue; } // If the value is null and we want to update nulls then set it. $val = 'NULL'; } else { // The field is not null so we prep it for update. $val = $this->sqlValue($columns, $k, $v); } // Add the field to be updated. $fields[] = $this->quoteName($k) . '=' . $val; } // We don't have any fields to update. if (empty($fields)) { return true; } // Set the query and execute the update. $this->setQuery(sprintf($statement, implode(',', $fields), implode(' AND ', $where))); return $this->execute(); } /** * Quotes a binary string to database requirements for use in database queries. * * @param string $data A binary string to quote. * * @return string The binary quoted input string. * * @since 1.7.0 */ public function quoteBinary($data) { return "decode('" . bin2hex($data) . "', 'hex')"; } /** * Replace special placeholder representing binary field with the original string. * * @param string|resource $data Encoded string or resource. * * @return string The original string. * * @since 1.7.0 */ public function decodeBinary($data) { if (\is_resource($data)) { return stream_get_contents($data); } return $data; } } PK 9?�\�綿�= �= PgsqlImporter.phpnu �[��� <?php /** * Part of the Joomla Framework Database Package * * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Database\Pgsql; use Joomla\Database\DatabaseImporter; /** * PDO PostgreSQL Database Importer. * * @since 1.5.0 */ class PgsqlImporter extends DatabaseImporter { /** * Checks if all data and options are in order prior to exporting. * * @return $this * * @since 1.5.0 * @throws \RuntimeException if an error is encountered. */ public function check() { // Check if the db connector has been set. if (!($this->db instanceof PgsqlDriver)) { throw new \RuntimeException('Database connection wrong type.'); } // Check if the tables have been specified. if (empty($this->from)) { throw new \RuntimeException('ERROR: No Tables Specified'); } return $this; } /** * Get the SQL syntax to add an index. * * @param \SimpleXMLElement $field The XML index definition. * * @return string * * @since 1.0 */ protected function getAddIndexSql(\SimpleXMLElement $field) { return (string) $field['Query']; } /** * Get alters for table if there is a difference. * * @param \SimpleXMLElement $structure The XML structure of the table. * * @return array * * @since 1.0 */ protected function getAlterTableSql(\SimpleXMLElement $structure) { $table = $this->getRealTableName($structure['name']); $oldFields = $this->db->getTableColumns($table); $oldKeys = $this->db->getTableKeys($table); $oldSequence = $this->db->getTableSequences($table); $alters = []; // Get the fields and keys from the XML that we are aiming for. $newFields = $structure->xpath('field'); $newKeys = $structure->xpath('key'); $newSequence = $structure->xpath('sequence'); /* * Sequence section */ $oldSeq = $this->getSeqLookup($oldSequence); $newSequenceLook = $this->getSeqLookup($newSequence); foreach ($newSequenceLook as $kSeqName => $vSeq) { if (isset($oldSeq[$kSeqName])) { // The field exists, check it's the same. $column = $oldSeq[$kSeqName][0]; // Test whether there is a change. $change = ((string) $vSeq[0]['Type'] !== $column->Type) || ((string) $vSeq[0]['Start_Value'] !== $column->Start_Value) || ((string) $vSeq[0]['Min_Value'] !== $column->Min_Value) || ((string) $vSeq[0]['Max_Value'] !== $column->Max_Value) || ((string) $vSeq[0]['Increment'] !== $column->Increment) || ((string) $vSeq[0]['Cycle_option'] !== $column->Cycle_option) || ((string) $vSeq[0]['Table'] !== $column->Table) || ((string) $vSeq[0]['Column'] !== $column->Column) || ((string) $vSeq[0]['Schema'] !== $column->Schema) || ((string) $vSeq[0]['Name'] !== $column->Name); if ($change) { $alters[] = $this->getChangeSequenceSql($kSeqName, $vSeq); $alters[] = $this->getSetvalSequenceSql($kSeqName, $vSeq); } // Unset this field so that what we have left are fields that need to be removed. unset($oldSeq[$kSeqName]); } else { // The sequence is new $alters[] = $this->getAddSequenceSql($newSequenceLook[$kSeqName][0]); $alters[] = $this->getSetvalSequenceSql($newSequenceLook[$kSeqName][0]); } } // Any sequences left are orphans foreach ($oldSeq as $name => $column) { // Delete the sequence. $alters[] = $this->getDropSequenceSql($name); } /* * Field section */ // Loop through each field in the new structure. foreach ($newFields as $field) { $fName = (string) $field['Field']; if (isset($oldFields[$fName])) { // The field exists, check it's the same. $column = $oldFields[$fName]; // Test whether there is a change. $change = ((string) $field['Type'] !== $column->Type) || ((string) $field['Null'] !== $column->Null) || ((string) $field['Default'] !== $column->Default); if ($change) { $alters[] = $this->getChangeColumnSql($table, $field); } // Unset this field so that what we have left are fields that need to be removed. unset($oldFields[$fName]); } else { // The field is new. $alters[] = $this->getAddColumnSql($table, $field); } } // Any columns left are orphans foreach ($oldFields as $name => $column) { // Delete the column. $alters[] = $this->getDropColumnSql($table, $name); } /* * Index section */ // Get the lookups for the old and new keys $oldLookup = $this->getKeyLookup($oldKeys); $newLookup = $this->getKeyLookup($newKeys); // Loop through each key in the new structure. foreach ($newLookup as $name => $keys) { // Check if there are keys on this field in the existing table. if (isset($oldLookup[$name])) { $same = true; $newCount = \count($newLookup[$name]); $oldCount = \count($oldLookup[$name]); // There is a key on this field in the old and new tables. Are they the same? if ($newCount === $oldCount) { for ($i = 0; $i < $newCount; $i++) { // Check only query field -> different query means different index $same = ((string) $newLookup[$name][$i]['Query'] === $oldLookup[$name][$i]->Query); if (!$same) { // Break out of the loop. No need to check further. break; } } } else { // Count is different, just drop and add. $same = false; } if (!$same) { $alters[] = $this->getDropIndexSql($name); $alters[] = (string) $newLookup[$name][0]['Query']; } // Unset this field so that what we have left are fields that need to be removed. unset($oldLookup[$name]); } else { // This is a new key. $alters[] = (string) $newLookup[$name][0]['Query']; } } // Any keys left are orphans. foreach ($oldLookup as $name => $keys) { if ($oldLookup[$name][0]->is_primary === 'TRUE') { $alters[] = $this->getDropPrimaryKeySql($table, $oldLookup[$name][0]->Index); } else { $alters[] = $this->getDropIndexSql($name); } } return $alters; } /** * Get the SQL syntax to drop a sequence. * * @param string $name The name of the sequence to drop. * * @return string * * @since 1.0 */ protected function getDropSequenceSql($name) { return 'DROP SEQUENCE ' . $this->db->quoteName($name); } /** * Get the syntax to add a sequence. * * @param \SimpleXMLElement $field The XML definition for the sequence. * * @return string * * @since 1.0 */ protected function getAddSequenceSql(\SimpleXMLElement $field) { $sql = 'CREATE SEQUENCE IF NOT EXISTS ' . (string) $field['Name'] . ' INCREMENT BY ' . (string) $field['Increment'] . ' MINVALUE ' . $field['Min_Value'] . ' MAXVALUE ' . (string) $field['Max_Value'] . ' START ' . (string) $field['Start_Value'] . (((string) $field['Cycle_option'] === 'NO') ? ' NO' : '') . ' CYCLE' . ' OWNED BY ' . $this->db->quoteName((string) $field['Schema'] . '.' . (string) $field['Table'] . '.' . (string) $field['Column']); return $sql; } /** * Get the syntax to alter a sequence. * * @param \SimpleXMLElement $field The XML definition for the sequence. * * @return string * * @since 1.0 */ protected function getChangeSequenceSql(\SimpleXMLElement $field) { $sql = 'ALTER SEQUENCE ' . (string) $field['Name'] . ' INCREMENT BY ' . (string) $field['Increment'] . ' MINVALUE ' . (string) $field['Min_Value'] . ' MAXVALUE ' . (string) $field['Max_Value'] . ' START ' . (string) $field['Start_Value'] . ' OWNED BY ' . $this->db->quoteName((string) $field['Schema'] . '.' . (string) $field['Table'] . '.' . (string) $field['Column']); return $sql; } /** * Get the syntax to setval a sequence. * * @param \SimpleXMLElement $field The XML definition for the sequence. * * @return string * * @since 2.0.0 */ protected function getSetvalSequenceSql($field) { $is_called = $field['Is_called'] == 't' || $field['Is_called'] == '1' ? 'TRUE' : 'FALSE'; return 'SELECT setval(\'' . (string) $field['Name'] . '\', ' . (string) $field['Last_Value'] . ', ' . $is_called . ')'; } /** * Get the syntax to alter a column. * * @param string $table The name of the database table to alter. * @param \SimpleXMLElement $field The XML definition for the field. * * @return string * * @since 1.0 */ protected function getChangeColumnSql($table, \SimpleXMLElement $field) { return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ALTER COLUMN ' . $this->db->quoteName((string) $field['Field']) . ' ' . $this->getAlterColumnSql($table, $field); } /** * Get the SQL syntax for a single column that would be included in a table create statement. * * @param string $table The name of the database table to alter. * @param \SimpleXMLElement $field The XML field definition. * * @return string * * @since 1.0 */ protected function getAlterColumnSql($table, \SimpleXMLElement $field) { // TODO Incorporate into parent class and use $this. $blobs = ['text', 'smalltext', 'mediumtext', 'largetext']; $fName = (string) $field['Field']; $fType = (string) $field['Type']; $fNull = (string) $field['Null']; $fDefault = (isset($field['Default']) && $field['Default'] != 'NULL') ? preg_match('/^[0-9]$/', $field['Default']) ? $field['Default'] : $this->db->quote((string) $field['Default']) : null; $sql = ' TYPE ' . $fType; if ($fNull === 'NO') { if ($fDefault === null || \in_array($fType, $blobs, true)) { $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET NOT NULL' . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' DROP DEFAULT'; } else { $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET NOT NULL' . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET DEFAULT ' . $fDefault; } } else { if ($fDefault !== null) { $sql .= ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' DROP NOT NULL' . ",\nALTER COLUMN " . $this->db->quoteName($fName) . ' SET DEFAULT ' . $fDefault; } } // Sequence was created in other function, here is associated a default value but not yet owner if (strpos($fDefault, 'nextval') !== false) { $sequence = $table . '_' . $fName . '_seq'; $owner = $table . '.' . $fName; $sql .= ";\nALTER SEQUENCE " . $this->db->quoteName($sequence) . ' OWNED BY ' . $this->db->quoteName($owner); } return $sql; } /** * Get the SQL syntax for a single column that would be included in a table create statement. * * @param \SimpleXMLElement $field The XML field definition. * * @return string * * @since 1.0 */ protected function getColumnSql(\SimpleXMLElement $field) { $fName = (string) $field['Field']; $fType = (string) $field['Type']; $fNull = (string) $field['Null']; if (strpos($field['Default'], '::') != false) { $fDefault = strstr($field['Default'], '::', true); } else { $fDefault = isset($field['Default']) && strlen($field['Default']) > 0 ? preg_match('/^[0-9]$/', $field['Default']) ? $field['Default'] : $this->db->quote((string) $field['Default']) : null; } // Note, nextval() as default value means that type field is serial. if (strpos($fDefault, 'nextval') !== false) { $sql = $this->db->quoteName($fName) . ' SERIAL'; } else { $sql = $this->db->quoteName($fName) . ' ' . $fType; if ($fNull == 'NO') { if ($fDefault === null) { $sql .= ' NOT NULL'; } else { $sql .= ' NOT NULL DEFAULT ' . $fDefault; } } else { if ($fDefault !== null) { $sql .= ' DEFAULT ' . $fDefault; } } } return $sql; } /** * Get the SQL syntax to drop an index. * * @param string $name The name of the key to drop. * * @return string * * @since 1.0 */ protected function getDropIndexSql($name) { return 'DROP INDEX ' . $this->db->quoteName($name); } /** * Get the SQL syntax to drop a key. * * @param string $table The table name. * @param string $name The constraint name. * * @return string * * @since 1.0 */ protected function getDropPrimaryKeySql($table, $name) { return 'ALTER TABLE ONLY ' . $this->db->quoteName($table) . ' DROP CONSTRAINT ' . $this->db->quoteName($name); } /** * Get the details list of keys for a table. * * @param array $keys An array of objects that comprise the keys for the table. * * @return array The lookup array. array({key name} => array(object, ...)) * * @since 1.2.0 */ protected function getKeyLookup($keys) { // First pass, create a lookup of the keys. $lookup = []; foreach ($keys as $key) { if ($key instanceof \SimpleXMLElement) { $kName = (string) $key['Index']; } else { $kName = $key->Index; } if (empty($lookup[$kName])) { $lookup[$kName] = []; } $lookup[$kName][] = $key; } return $lookup; } /** * Get the SQL syntax to add a unique constraint for a table key. * * @param string $table The table name. * @param array $key The key. * * @return string * * @since 2.0.0 */ protected function getAddUniqueSql($table, $key) { if ($key instanceof \SimpleXMLElement) { $kName = (string) $key['Key_name']; $kIndex = (string) $key['Index']; } else { $kName = $key->Key_name; $kIndex = $key->Index; } $unique = $kIndex . ' UNIQUE (' . $kName . ')'; return 'ALTER TABLE ' . $this->db->quoteName($table) . ' ADD CONSTRAINT ' . $unique; } /** * Get the details list of sequences for a table. * * @param array $sequences An array of objects that comprise the sequences for the table. * * @return array The lookup array. array({key name} => array(object, ...)) * * @since 1.0 */ protected function getSeqLookup($sequences) { // First pass, create a lookup of the keys. $lookup = []; foreach ($sequences as $seq) { if ($seq instanceof \SimpleXMLElement) { $sName = (string) $seq['Name']; } else { $sName = $seq->Name; } if (empty($lookup[$sName])) { $lookup[$sName] = []; } $lookup[$sName][] = $seq; } return $lookup; } /** * Get the SQL syntax to add a table. * * @param \SimpleXMLElement $table The table information. * * @return string * * @since 2.0.0 * @throws \RuntimeException */ protected function xmlToCreate(\SimpleXMLElement $table) { $existingTables = $this->db->getTableList(); $tableName = (string) $table['name']; if (in_array($tableName, $existingTables)) { throw new \RuntimeException('The table you are trying to create already exists'); } $createTableStatement = 'CREATE TABLE ' . $this->db->quoteName($tableName) . ' ('; foreach ($table->xpath('field') as $field) { $createTableStatement .= $this->getColumnSql($field) . ', '; } $createTableStatement = rtrim($createTableStatement, ', '); $createTableStatement .= ');'; foreach ($table->xpath('sequence') as $seq) { $createTableStatement .= $this->getAddSequenceSql($seq) . ';'; $createTableStatement .= $this->getSetvalSequenceSql($seq) . ';'; } foreach ($table->xpath('key') as $key) { if ((($key['is_primary'] == 'f') || ($key['is_primary'] == '')) && (($key['is_unique'] == 't') || ($key['is_unique'] == '1'))) { $createTableStatement .= $this->getAddUniqueSql($tableName, $key) . ';'; } else { $createTableStatement .= $this->getAddIndexSql($key) . ';'; } } return $createTableStatement; } } PK 9?�\ � 7| | PgsqlQuery.phpnu �[��� PK 9?�\ ��� � � PgsqlExporter.phpnu �[��� PK 9?�\ ���p �p � PgsqlDriver.phpnu �[��� PK 9?�\�綿�= �= r� PgsqlImporter.phpnu �[��� PK ? ~�
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings