X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=blobdiff_plain;f=includes%2Flibs%2Frdbms%2Fdatabase%2FDatabase.php;h=13bf8f023edb39a34b18cc2bd036d957f6398c15;hb=e895217711438e8ba84ec8232daf90b9c0d6cf1d;hp=49b2792210b2f38b0f1730c04a1760ac09c0ae71;hpb=e9a27a78e455de664144d0c3cfc789bcc411fab2;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index 49b2792210..13bf8f023e 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -260,7 +260,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware /** @var int[] Prior flags member variable values */ private $priorFlags = []; - /** @var mixed Class name or object With profileIn/profileOut methods */ + /** @var callable|null */ protected $profiler; /** @var TransactionProfiler */ protected $trxProfiler; @@ -308,7 +308,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $this->srvCache = $params['srvCache'] ?? new HashBagOStuff(); - $this->profiler = $params['profiler']; + $this->profiler = is_callable( $params['profiler'] ) ? $params['profiler'] : null; $this->trxProfiler = $params['trxProfiler']; $this->connLogger = $params['connLogger']; $this->queryLogger = $params['queryLogger']; @@ -408,9 +408,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware * used to adjust lock timeouts or encoding modes and the like. * - connLogger: Optional PSR-3 logger interface instance. * - queryLogger: Optional PSR-3 logger interface instance. - * - profiler: Optional class name or object with profileIn()/profileOut() methods. - * These will be called in query(), using a simplified version of the SQL that also - * includes the agent as a SQL comment. + * - profiler : Optional callback that takes a section name argument and returns + * a ScopedCallback instance that ends the profile section in its destructor. + * These will be called in query(), using a simplified version of the SQL that + * also includes the agent as a SQL comment. * - trxProfiler: Optional TransactionProfiler instance. * - errorLogger: Optional callback that takes an Exception and logs it. * - deprecationLogger: Optional callback that takes a string and logs it. @@ -1236,7 +1237,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware # option is ROLLBACK, since the snapshots would have been released. $this->trxStatus = self::STATUS_TRX_ERROR; $this->trxStatusCause = - $this->makeQueryException( $lastError, $lastErrno, $sql, $fname ); + $this->getQueryExceptionAndLog( $lastError, $lastErrno, $sql, $fname ); $tempIgnore = false; // cannot recover $this->trxStatusIgnoredCause = null; } @@ -1272,19 +1273,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $queryProf .= $this->trxShortId ? " [TRX#{$this->trxShortId}]" : ""; $startTime = microtime( true ); - if ( $this->profiler ) { - $this->profiler->profileIn( $queryProf ); - } + $ps = $this->profiler ? ( $this->profiler )( $queryProf ) : null; $this->affectedRowCount = null; $ret = $this->doQuery( $commentedSql ); $this->affectedRowCount = $this->affectedRows(); - if ( $this->profiler ) { - $this->profiler->profileOut( $queryProf ); - } + unset( $ps ); // profile out (if set) $queryRuntime = max( microtime( true ) - $startTime, 0.0 ); - unset( $queryProfSection ); // profile out (if set) - if ( $ret !== false ) { $this->lastPing = $startTime; if ( $isWrite && $this->trxLevel ) { @@ -1489,7 +1484,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware if ( $tempIgnore ) { $this->queryLogger->debug( "SQL ERROR (ignored): $error\n" ); } else { - $exception = $this->makeQueryException( $error, $errno, $sql, $fname ); + $exception = $this->getQueryExceptionAndLog( $error, $errno, $sql, $fname ); throw $exception; } @@ -1502,7 +1497,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware * @param string $fname * @return DBError */ - private function makeQueryException( $error, $errno, $sql, $fname ) { + private function getQueryExceptionAndLog( $error, $errno, $sql, $fname ) { $sql1line = mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 ); $this->queryLogger->error( "{fname}\t{db_server}\t{errno}\t{error}\t{sql1line}", @@ -1512,6 +1507,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware 'error' => $error, 'sql1line' => $sql1line, 'fname' => $fname, + 'trace' => ( new RuntimeException() )->getTraceAsString() ] ) ); $this->queryLogger->debug( "SQL ERROR: " . $error . "\n" ); @@ -2782,6 +2778,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware return; } + $uniqueIndexes = (array)$uniqueIndexes; // Single row case if ( !is_array( reset( $rows ) ) ) { $rows = [ $rows ]; @@ -2861,13 +2858,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $this->query( $sql, $fname ); } - public function upsert( $table, array $rows, array $uniqueIndexes, array $set, + public function upsert( $table, array $rows, $uniqueIndexes, array $set, $fname = __METHOD__ ) { if ( $rows === [] ) { return true; // nothing to do } + $uniqueIndexes = (array)$uniqueIndexes; if ( !is_array( reset( $rows ) ) ) { $rows = [ $rows ]; }