Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/includes/libs/rdbms/platform/PostgresPlatform.php
Ðазад
<?php /** * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * * @file */ namespace Wikimedia\Rdbms\Platform; use Wikimedia\Rdbms\DBLanguageError; use Wikimedia\Rdbms\Query; use Wikimedia\Timestamp\ConvertibleTimestamp; /** * @since 1.39 * @see ISQLPlatform */ class PostgresPlatform extends SQLPlatform { /** @var string */ private $coreSchema; public function limitResult( $sql, $limit, $offset = false ) { return "$sql LIMIT $limit " . ( is_numeric( $offset ) ? " OFFSET {$offset} " : '' ); } public function buildConcat( $stringList ) { return implode( ' || ', $stringList ); } public function timestamp( $ts = 0 ) { $ct = new ConvertibleTimestamp( $ts ); return $ct->getTimestamp( TS_POSTGRES ); } public function buildStringCast( $field ) { return $field . '::text'; } public function implicitOrderby() { return false; } public function getCoreSchema(): string { return $this->coreSchema; } public function setCoreSchema( string $coreSchema ): void { $this->coreSchema = $coreSchema; } public function selectSQLText( $tables, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = [] ) { if ( is_string( $options ) ) { $options = [ $options ]; } // Change the FOR UPDATE option as necessary based on the join conditions. Then pass // to the parent function to get the actual SQL text. // In Postgres when using FOR UPDATE, only the main table and tables that are inner joined // can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to // do so causes a DB error. This wrapper checks which tables can be locked and adjusts it // accordingly. // MySQL uses "ORDER BY NULL" as an optimization hint, but that is illegal in PostgreSQL. if ( is_array( $options ) ) { $forUpdateKey = array_search( 'FOR UPDATE', $options, true ); if ( $forUpdateKey !== false && $join_conds ) { unset( $options[$forUpdateKey] ); $options['FOR UPDATE'] = []; $toCheck = $tables; reset( $toCheck ); while ( $toCheck ) { $alias = key( $toCheck ); $name = $toCheck[$alias]; unset( $toCheck[$alias] ); $hasAlias = !is_numeric( $alias ); if ( !$hasAlias && is_string( $name ) ) { $alias = $name; } if ( !isset( $join_conds[$alias] ) || !preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_conds[$alias][0] ) ) { if ( is_array( $name ) ) { // It's a parenthesized group, process all the tables inside the group. $toCheck = array_merge( $toCheck, $name ); } else { // Quote alias names so $this->tableName() won't mangle them $options['FOR UPDATE'][] = $hasAlias ? $this->addIdentifierQuotes( $alias ) : $alias; } } } } if ( isset( $options['ORDER BY'] ) && ( $options['ORDER BY'] == 'NULL' || $options['ORDER BY'] == [ 'NULL' ] ) ) { unset( $options['ORDER BY'] ); } } return parent::selectSQLText( $tables, $vars, $conds, $fname, $options, $join_conds ); } protected function makeSelectOptions( array $options ) { $preLimitTail = $postLimitTail = ''; $startOpts = ''; $noKeyOptions = []; foreach ( $options as $key => $option ) { if ( is_numeric( $key ) ) { $noKeyOptions[$option] = true; } } $preLimitTail .= $this->makeGroupByWithHaving( $options ); $preLimitTail .= $this->makeOrderBy( $options ); if ( isset( $options['FOR UPDATE'] ) ) { $postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', array_map( [ $this, 'tableName' ], $options['FOR UPDATE'] ) ); } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) { $postLimitTail .= ' FOR UPDATE'; } if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) { $startOpts .= 'DISTINCT'; } return [ $startOpts, $preLimitTail, $postLimitTail ]; } public function getDatabaseAndTableIdentifier( string $table ) { $components = $this->qualifiedTableComponents( $table ); switch ( count( $components ) ) { case 1: return [ $this->currentDomain->getDatabase(), $components[0] ]; case 2: return [ $this->currentDomain->getDatabase(), $components[1] ]; case 3: return [ $components[0], $components[2] ]; default: throw new DBLanguageError( 'Too many table components' ); } } protected function relationSchemaQualifier() { if ( $this->coreSchema === $this->currentDomain->getSchema() ) { // The schema to be used is now in the search path; no need for explicit qualification return ''; } return parent::relationSchemaQualifier(); } public function buildGroupConcatField( $delim, $tables, $field, $conds = '', $join_conds = [] ) { $fld = "array_to_string(array_agg($field)," . $this->quoter->addQuotes( $delim ) . ')'; return '(' . $this->selectSQLText( $tables, $fld, $conds, static::CALLER_SUBQUERY, [], $join_conds ) . ')'; } public function makeInsertLists( array $rows, $aliasPrefix = '', array $typeByColumn = [] ) { $firstRow = $rows[0]; if ( !is_array( $firstRow ) || !$firstRow ) { throw new DBLanguageError( 'Got an empty row list or empty row' ); } // List of columns that define the value tuple ordering $tupleColumns = array_keys( $firstRow ); $valueTuples = []; foreach ( $rows as $row ) { $rowColumns = array_keys( $row ); // VALUES(...) requires a uniform correspondence of (column => value) if ( $rowColumns !== $tupleColumns ) { throw new DBLanguageError( 'Got row columns (' . implode( ', ', $rowColumns ) . ') ' . 'instead of expected (' . implode( ', ', $tupleColumns ) . ')' ); } // Make the value tuple that defines this row $typedRowValues = []; foreach ( $row as $column => $value ) { $type = $typeByColumn[$column] ?? null; if ( $value === null ) { $typedRowValues[] = 'NULL'; } elseif ( $type !== null ) { $typedRowValues[] = $this->quoter->addQuotes( $value ) . '::' . $type; } else { $typedRowValues[] = $this->quoter->addQuotes( $value ); } } $valueTuples[] = '(' . implode( ',', $typedRowValues ) . ')'; } $magicAliasFields = []; foreach ( $tupleColumns as $column ) { $magicAliasFields[] = $aliasPrefix . $column; } return [ $this->makeList( $tupleColumns, self::LIST_NAMES ), implode( ',', $valueTuples ), $this->makeList( $magicAliasFields, self::LIST_NAMES ) ]; } protected function makeInsertNonConflictingVerbAndOptions() { return [ 'INSERT INTO', 'ON CONFLICT DO NOTHING' ]; } protected function makeUpdateOptionsArray( $options ) { $options = $this->normalizeOptions( $options ); // PostgreSQL doesn't support anything like "ignore" for UPDATE. $options = array_diff( $options, [ 'IGNORE' ] ); return parent::makeUpdateOptionsArray( $options ); } public function isTransactableQuery( Query $sql ) { return parent::isTransactableQuery( $sql ) && !preg_match( '/^SELECT\s+pg_(try_|)advisory_\w+\(/', $sql->getSQL() ); } public function lockSQLText( $lockName, $timeout ) { // http://www.postgresql.org/docs/9.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS $key = $this->quoter->addQuotes( $this->bigintFromLockName( $lockName ) ); return "SELECT (CASE WHEN pg_try_advisory_lock($key) " . "THEN EXTRACT(epoch from clock_timestamp()) " . "ELSE NULL " . "END) AS acquired"; } public function lockIsFreeSQLText( $lockName ) { // http://www.postgresql.org/docs/9.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS $key = $this->quoter->addQuotes( $this->bigintFromLockName( $lockName ) ); return "SELECT (CASE(pg_try_advisory_lock($key)) WHEN FALSE THEN FALSE ELSE pg_advisory_unlock($key) END) AS unlocked"; } public function unlockSQLText( $lockName ) { // http://www.postgresql.org/docs/9.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS $key = $this->quoter->addQuotes( $this->bigintFromLockName( $lockName ) ); return "SELECT pg_advisory_unlock($key) AS released"; } /** * @param string $lockName * @return string Integer */ private function bigintFromLockName( $lockName ) { return \Wikimedia\base_convert( substr( sha1( $lockName ), 0, 15 ), 16, 10 ); } }
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка