Current Path : /storage/v11800/testtest/public_html/wp-content/plugins/pagespeed/index-wp-mysql-for-speed/code/ |
Linux v11800 5.3.0-1023-aws #25~18.04.1-Ubuntu SMP Fri Jun 5 15:19:18 UTC 2020 aarch64
|
Current File : /storage/v11800/testtest/public_html/wp-content/plugins/pagespeed/index-wp-mysql-for-speed/code/imsfdb.php |
<?php
/** @noinspection SpellCheckingInspection */
require_once( 'getindexes.php' );
require_once( 'getqueries.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
class ImfsDb {
/** @var bool true if this server can support reindexing at all */
public $canReindex = false;
/** @var int 1 if we have Barracuda, 0 if we have Antelope */
public $unconstrained;
public $messages = [];
public $semver;
public $tableCounts;
public $tableFormats;
public $oldEngineTables;
public $newEngineTables;
public $timings;
private $initialized = false;
private $hasHrTime;
/** @var string[] list of index prefixes to ignore. */
private $indexStopList = [ 'woo_', 'crp_', 'yarpp_', 'index_wp_mysql_protect_' ];
private $pluginOldVersion;
private $pluginVersion;
private $indexQueryCache = [];
/** @var int the time in seconds allowed for each ALTER operation */
private $scriptTimeLimit = 600;
/**
* @param float $pluginVersion
* @param float $pluginOldVersion
*/
public function __construct( $pluginVersion, $pluginOldVersion ) {
$this->pluginOldVersion = $pluginOldVersion;
$this->pluginVersion = $pluginVersion;
}
/**
* @throws ImfsException
* @noinspection PhpRedundantOptionalArgumentInspection
*/
public function init() {
global $wpdb;
if ( ! $this->initialized ) {
$this->initialized = true;
$this->timings = [];
$this->semver = ImfsQueries::getMySQLVersion();
$this->canReindex = $this->semver->canreindex;
$this->unconstrained = $this->semver->unconstrained;
if ( $this->canReindex ) {
$this->tableCounts = $this->getTableCounts();
$this->tableFormats = $this->getTableFormats();
$oldEngineTables = [];
$newEngineTables = [];
/* make sure we only upgrade the engine on WordPress's own tables */
$wpTables = array_flip( $wpdb->tables( 'blog', true ) );
if ( is_main_site() ) {
$wpTables = $wpTables + array_flip( $wpdb->tables( 'global', true ) );
}
foreach ( $this->tableFormats as $name => $info ) {
$activeTable = false;
if ( isset( $wpTables[ $name ] ) ) {
$activeTable = true;
}
/* This ignores an empty prefix. Nevertheless, that is not a supported WordPress configuration. */
if ( ! empty( $wpdb->prefix ) && 0 === strpos( $name, $wpdb->prefix ) ) {
$activeTable = true;
}
if ( $activeTable ) {
/* not InnoDB, we should upgrade */
$wrongEngine = $info->ENGINE !== 'InnoDB';
/* one of the old row formats, probably compact. But ignore if old MySQL version. */
$wrongRowFormat = $this->unconstrained && $info->ROW_FORMAT !== 'Dynamic' && $info->ROW_FORMAT !== 'Compressed';
if ( $wrongEngine || $wrongRowFormat ) {
$oldEngineTables[] = $name;
} else {
$newEngineTables[] = $name;
}
}
}
$this->oldEngineTables = $oldEngineTables;
$this->newEngineTables = $newEngineTables;
}
try {
$this->hasHrTime = function_exists( 'hrtime' );
} catch ( Exception $ex ) {
$this->hasHrTime = false;
}
}
}
private function getTableCounts() {
global $wpdb;
$wpdb->flush();
$query = ImfsQueries::getTableCountsQuery();
return $this->get_results( $query );
}
/** run a SELECT
*
* @param $sql
* @param bool $doTiming
* @param string $outputFormat default OBJECT_K
*
* @return array|object|null
* @throws ImfsException
*/
public function get_results( $sql, $doTiming = false, $outputFormat = OBJECT_K ) {
global $wpdb;
$thentime = $doTiming ? $this->getTime() : - 1;
$results = $wpdb->get_results( $this->tagQuery( $sql ), $outputFormat );
if ( false === $results || $wpdb->last_error ) {
throw new ImfsException( $wpdb->last_error, $wpdb->last_query );
}
if ( $doTiming ) {
$delta = round( floatval( $this->getTime() - $thentime ), 3 );
$this->timings[] = [ 't' => $delta, 'q' => $sql ];
}
return $results;
}
public function getTime() {
try {
/** @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection */
return $this->hasHrTime ? hrtime( true ) * 0.000000001 : time();
} catch ( Exception $ex ) {
return time();
}
}
/** place a tag comment at the end of a SQL statement,
* including text to recognize our queries and
* a random cache-busting number.
* (So WP Total Cache and others won't cache.)
*
* @param $q
*
* @return string
*/
private function tagQuery( $q ) {
return $q . '/*' . index_wp_mysql_for_speed_querytag . rand( 0, 999999999 ) . '*/';
}
private function getTableFormats() {
global $wpdb;
$wpdb->flush();
$query = ImfsQueries::getTableFormatsQuery();
return $this->get_results( $query );
}
function getTableStats() {
return $this->get_results( ImfsQueries::getTableStatsQuery() );
}
/**
* Retrieve all DBMS variables.
*
* @return array Resultset, array of objects with Variable_name and Value attributes.
* @throws ImfsException
*/
public function getVariables() {
return $this->get_results( "SHOW GLOBAL VARIABLES" );
}
/**
* Retrieve one variable.
*
* @param string $name Variable name.
*
* @return null|mixed The variable's value, or null if the variable doesn't exist, or more than one was returned.
*/
public function getVariable( $name ) {
try {
$name = sanitize_key( $name );
$resultset = $this->get_results( "SHOW GLOBAL VARIABLES LIKE '$name'" );
if ( is_array( $resultset ) && 1 === count( $resultset ) ) {
return $resultset[ $name ]->Value;
}
} catch ( Exception $e ) {
return null;
}
return null;
}
/**
* Set a session variable.
*
* @param string $name The variable's name.
* @param string|int|float $value The value.
*
* @return bool False on failure.
*/
function set_session_variable( $name, $value ) {
try {
global $wpdb;
$name = sanitize_key( $name );
$q = "SET SESSION $name=";
$q .= is_numeric( $value ) ? '%d' : '%s';
$sql = $this->tagQuery( $q );
$wpdb->query( $wpdb->prepare( $sql, $value ) );
} catch ( Exception $e ) {
return false;
}
return true;
}
public function getSizes () {
$sizes = $this->get_results( ImfsQueries::getCurrentDbTableSizesQuery(), false, ARRAY_A );
return $sizes[0];
}
function getStatus() {
return $this->get_results( "SHOW GLOBAL STATUS" );
}
/**
* Retrieve one status variable.
*
* @param string $name Variable name.
*
* @return null|mixed The variable's value, or null if the variable doesn't exist, or more than one was returned.
*/
public function getStatusVariable( $name ) {
try {
$name = $this->sanitize_status_variable_name( $name );
$resultset = $this->get_results( "SHOW GLOBAL STATUS LIKE '$name'" );
if ( is_array( $resultset ) && 1 === count( $resultset ) ) {
return $resultset[ $name ]->Value;
}
} catch ( Exception $e ) {
return null;
}
return null;
}
/**
* Sanitizes a status variable name
*
* Keys are used as internal identifiers. Upper and Lowercase alphanumeric characters,
* dashes, and underscores are allowed.
*
* @param string $key String key.
*
* @return string Sanitized key.
*/
function sanitize_status_variable_name( $key ) {
$sanitized_key = '';
if ( is_scalar( $key ) ) {
$sanitized_key = preg_replace( '/[^A-Za-z0-9_\-]/', '', $key );
}
return $sanitized_key;
}
/**
* @param $targetAction int 0 - WordPress standard 1 -- high performance
* @param $tables array tables like ['postmeta','termmeta']
* @param $version
* @param $alreadyPrefixed bool false if wp_ prefix needs to be added to table names
* @param bool $dryrun true when doing a dry run, default false -- do the operation
*
* @return array|string status string, or if
* @throws ImfsException
*/
public function rekeyTables( $targetAction, array $tables, $version, $alreadyPrefixed = false, $dryrun = false ) {
$statements = [];
/* changing indexes: get rid of the cache showing present indexes */
$this->indexQueryCache = [];
$count = 0;
if ( count( $tables ) > 0 ) {
foreach ( $tables as $name ) {
$statements[] = $this->rekeyTable( $targetAction, $name, $version, $alreadyPrefixed, $dryrun );
$count ++;
}
}
wp_cache_flush();
if ( $dryrun ) {
return $statements;
}
$msg = '';
switch ( $targetAction ) {
case 1:
/* translators: 1: number of tables processed */
$msg = __( 'High-performance keys added to %1$d tables.', 'index-wp-mysql-for-speed' );
break;
case 0:
/* translators: 1: number of tables processed */
$msg = __( 'Keys on %1$d tables reverted to WordPress standard.', 'index-wp-mysql-for-speed' );
break;
}
return sprintf( $msg, $count );
}
/** Redo the keys on the selected table.
*
* @param int $targetAction 0 -- WordPress standard. 1 -- high-perf
* @param string $name table name without prefix
* @param bool $dryrun true when doing a dry run, default false -- do the operation
*
* @returns string the text of the SQL statement doing the rekeying
*
* @throws ImfsException
*/
public function rekeyTable( $targetAction, $name, $version, $alreadyPrefixed = false, $dryrun = false ) {
global $wpdb;
$unprefixedName = $alreadyPrefixed ? ImfsQueries::stripPrefix( $name ) : $name;
$prefixedName = $alreadyPrefixed ? $name : $wpdb->prefix . $name;
$actions = $this->getConversionList( $targetAction, $unprefixedName, $version );
if ( count( $actions ) === 0 ) {
return '';
}
$q = 'ALTER TABLE `' . $prefixedName . '` ' . implode( ', ', $actions );
$stats = 'ANALYZE TABLE `' . $prefixedName . '`';
if ( ! $dryrun ) {
$this->set_runtime_limit();
$this->query( $q, true );
$this->query( $stats, true );
}
return $q . ';';
}
/**
* @param float|int|null $seconds Time limit. Default is $this->scriptTimeLimit
*
* @return int|float|null Value to use in setting max_statement_time. Null if not needed.
*/
public function get_max_statement_time( $seconds = null ) {
$seconds = $seconds ?: $this->scriptTimeLimit;
$max_statement_time = $this->getVariable( 'max_statement_time' );
if ( $max_statement_time && is_numeric( $max_statement_time ) ) {
/* The server has a max_statement_time variable */
if ( $max_statement_time > 0 && $max_statement_time < $seconds ) {
/* It is set lower than our runtime limit. Increase it. */
return $seconds;
}
}
return null;
}
/**
* Set the runtime limit for a query.
*
* @param int $seconds The limit. Default from $this->scriptTimeLimit.
*
* @return void
* @throws ImfsException
*/
private function set_runtime_limit( $seconds = null ) {
$seconds = $seconds ?: $this->scriptTimeLimit;
$max_statement_time = $this->get_max_statement_time( $seconds );
if ( $max_statement_time ) {
/* It is set lower than our runtime limit. Increase it. */
$this->set_session_variable( 'max_statement_time', $seconds );
}
set_time_limit( $seconds );
}
/**
* @param int $targetState 0 -- WordPress default 1 -- high-performance
* @param string $name table name
* @param float $version
*
* @return array
* @throws ImfsException
*/
public function getConversionList( $targetState, $name, $version ) {
$target = $targetState === 0
? ImfsGetIndexes::getStandardIndexes( $this->unconstrained )
: ImfsGetIndexes::getHighPerformanceIndexes( $this->unconstrained, $version );
$target = array_key_exists( $name, $target ) ? $target[ $name ] : [];
$current = $this->getKeyDDL( $name );
/* build a list of all index names, target first so UNIQUEs come first */
$indexes = [];
foreach ( $target as $key => $value ) {
if ( ! isset( $indexes[ $key ] ) ) {
$indexes[ $key ] = $key;
}
}
foreach ( $current as $key => $value ) {
if ( ! isset( $indexes[ $key ] ) ) {
$indexes[ $key ] = $key;
}
}
/* Ignore index names prefixed with anything ins
* the indexStoplist array (skip woocommerce indexes) */
foreach ( $this->indexStopList as $stop ) {
foreach ( $indexes as $index => $val ) {
if ( strpos( $index, $stop ) === 0 ) {
unset ( $indexes[ $index ] );
}
}
}
$actions = [];
$curDexes = 'current indexes ' . $name . ':';
foreach ( $current as $value ) {
$curDexes .= $value->add . ' ';
}
foreach ( $indexes as $key => $value ) {
if ( array_key_exists( $key, $current ) && array_key_exists( $key, $target ) && $current[ $key ]->add === $target[ $key ] ) {
/* empty, intentionally. no action required */
} else if ( array_key_exists( $key, $current ) && array_key_exists( $key, $target ) && $current[ $key ]->add !== $target[ $key ] ) {
$actions[] = $current[ $key ]->drop;
$actions[] = $target[ $key ];
} else if ( array_key_exists( $key, $current ) && ! array_key_exists( $key, $target ) ) {
$actions[] = $current[ $key ]->drop;
} else if ( ! array_key_exists( $key, $current ) && array_key_exists( $key, $target ) ) {
$actions[] = $target[ $key ];
} else {
throw new ImfsException( 'weird key compare failure' );
}
}
return $actions;
}
/**
* Retrieve DML for the keys in the named table.
*
* @param string $name table name (without prefix)
* @param bool $addPrefix
*
* @return array
* @throws ImfsException
*/
public function getKeyDDL( $name, $addPrefix = true ) {
global $wpdb;
if ( $addPrefix ) {
$name = $wpdb->prefix . $name;
}
if ( array_key_exists( $name, $this->indexQueryCache ) ) {
return $this->indexQueryCache[ $name ];
}
$stmt = $wpdb->prepare( ImfsQueries::getTableIndexesQuery(), $name );
$result = $this->get_results( $stmt );
$this->indexQueryCache[ $name ] = $result;
return $result;
}
/** run a query*
*
* @param $sql
* @param bool $doTiming
*
* @return bool|int
* @throws ImfsException
*/
public function query( $sql, $doTiming = false ) {
global $wpdb;
$thentime = $doTiming ? $this->getTime() : - 1;
$results = $wpdb->query( $this->tagQuery( $sql ) );
$this->logDDLQuery( $sql );
if ( false === $results || $wpdb->last_error ) {
throw new ImfsException( $wpdb->last_error, $wpdb->last_query );
}
if ( $doTiming ) {
$delta = round( floatval( $this->getTime() - $thentime ), 3 );
$this->timings[] = [ 't' => $delta, 'q' => $sql ];
}
return $results;
}
private function logDDLQuery( $sql ) {
if ( index_mysql_for_speed_log !== null ) {
$log = get_option( index_mysql_for_speed_log );
if ( strlen( $log ) >= 1024 * 1024 ) {
$log = '';
}
$log .= PHP_EOL . $sql;
update_option( index_mysql_for_speed_log, $log );
}
}
/** get the current index situation
* @return array
*/
public function getIndexList() {
$results = [];
try {
$rekeying = $this->getRekeying();
foreach ( $rekeying as $key => $list ) {
if ( is_array( $list ) && count( $list ) > 0 ) {
if ( $key === 'standard' || $key === 'old' || $key === 'fast' || $key === 'upgrade' ) {
$results[ $key ] = $list;
}
}
}
/* nonstandard? show the actual keys */
$nonstandard = $rekeying['nonstandard'];
if ( is_array( $nonstandard ) && count( $nonstandard ) > 0 ) {
$tables = [];
foreach ( $nonstandard as $table ) {
$keys = [];
$current = $this->getKeyDDL( $table );
foreach ( $current as $key => $value ) {
$dex = preg_replace( '/^ADD +/', '', $value->add, 1 );
$keys[] = $dex;
}
$tables[ $table ] = $keys;
}
$results['nonstandard'] = $tables;
}
} catch ( ImfsException $ex ) {
$results[] = $ex->getMessage();
}
return $results;
}
/** figure out, based on current DDL and target DDL,
* what tables need to change, and how they could change.
*
* @return array
* @throws ImfsException
*/
public function getRekeying() {
global $wpdb;
$originalTables = $this->tables();
/* don't process tables still on old storage engines */
$tables = [];
if ( is_array( $this->oldEngineTables ) ) {
foreach ( $originalTables as $name ) {
if ( ! in_array( $wpdb->prefix . $name, $this->oldEngineTables ) ) {
$tables[] = $name;
}
}
}
/* any rekeyable tables? */
$updatable = [];
$newToThisVer = [];
$addable = [];
$revertable = [];
$repairable = [];
$enableList = [];
$oldList = [];
$fastList = [];
if ( is_array( $tables ) && count( $tables ) > 0 ) {
sort( $tables );
foreach ( $tables as $name ) {
$hasFastIndexes = ! $this->anyIndexChangesNeededForAction( 1, $name, $this->pluginVersion );
$hasStandardIndexes = ! $this->anyIndexChangesNeededForAction( 0, $name, $this->pluginVersion );
$hasOldIndexes = ! $this->anyIndexChangesNeededForAction( 1, $name, $this->pluginOldVersion );
if ( ! $hasFastIndexes && ! $hasStandardIndexes && ! $hasOldIndexes ) {
/* some index config we don't recognize */
$repairable[] = $name;
$revertable[] = $name;
} else if ( ! $hasFastIndexes && ! $hasStandardIndexes && $hasOldIndexes ) {
/* indexes from old version of plugin */
$updatable[] = $name;
$revertable[] = $name;
} else if ( ! $hasFastIndexes && $hasStandardIndexes && ! $hasOldIndexes ) {
/* standard indexes, not rekeyed by this or older plugin version */
$addable[] = $name;
} else if ( ! $hasFastIndexes && $hasStandardIndexes && $hasOldIndexes ) {
/* not rekeyed in older version, but rekeyed in this version */
$newToThisVer[] = $name;
} else if ( $hasFastIndexes && ! $hasStandardIndexes && ! $hasOldIndexes ) {
/* already rekeyed by this version */
$revertable[] = $name;
$fastList[] = $name;
} else {
throw new Exception( "Table $name invalid state $hasFastIndexes $hasStandardIndexes $hasOldIndexes" );
}
}
/* handle version update logic */
if ( count( $updatable ) > 0 ) {
/* version update time: offer to update both new and upd */
$oldList = array_merge( $newToThisVer, $updatable );
$enableList = $addable;
} else {
$enableList = array_merge( $newToThisVer, $addable );
}
}
sort( $enableList );
sort( $oldList );
/* What do we return here?
* enable: list of tables that can have fast keys added.
* old: list of tables that have previous-version fast keys,
* including tables the previous version did not touch.
* disable: list of tables that have indexes that can be
* restored to the default.
* fast: list of tables that have this plugin version's fast indexes.
* nonstandard: list of tables with indexes this plugin doesn't recognize.
* standard: list of tables with WordPress standard keys
* upgrade: list of MyISAM and / or COMPACT row-format tables
* needing upgrading.
*/
return [
'enable' => $enableList,
'old' => $oldList,
'disable' => $revertable,
'fast' => $fastList,
'nonstandard' => $repairable,
'standard' => $addable,
'upgrade' => $this->oldEngineTables,
];
}
/** List of tables to manipulate
*
* @param bool $prefixed true if you want wp_postmeta, false if you want postmeta
*
* @return array tables manipulated by this module
* @throws ImfsException
*/
public function tables( $prefixed = false ) {
global $wpdb;
$avail = $wpdb->tables;
if ( is_main_site() ) {
foreach ( $wpdb->global_tables as $table ) {
$avail[] = $table;
}
}
/* match to the tables we know how to reindex */
$allTables = ImfsGetIndexes::getIndexableTables( $this->unconstrained );
$tables = [];
foreach ( $allTables as $table ) {
if ( in_array( $table, $avail ) ) {
$tables[] = $table;
}
}
sort( $tables );
if ( ! $prefixed ) {
return $tables;
}
$result = [];
foreach ( $tables as $table ) {
$result[] = $wpdb->prefix . $table;
}
return $result;
}
/** Check whether a table is ready to be acted upon
*
* @param int $targetAction "enable" or "disable"
* @param $name
* @param $version
*
* @return bool
* @throws ImfsException
*/
public function anyIndexChangesNeededForAction( $targetAction, $name, $version ) {
$actions = $this->getConversionList( $targetAction, $name, $version );
return count( $actions ) > 0;
}
/**
* @param array $list of tables
* @param bool $dryrun true if we're doing a dry run.
*
* @return array|string list of DDL statements, or display messat
* @throws ImfsException
*/
public function upgradeTableStorageEngines( array $list, $dryrun = false ) {
/* reworking tables; flush any index cache */
$this->indexQueryCache = [];
$statements = [];
$counter = 0;
try {
$this->lock( $list, true );
foreach ( $list as $table ) {
$statements[] = $this->upgradeTableStorageEngine( $table, $dryrun );
$counter ++;
}
/* translators: 1: count of tables upgraded from MyISAM to InnoDB */
$msg = __( '%1$d tables upgraded', 'index-wp-mysql-for-speed' );
} catch ( ImfsException $ex ) {
$msg = implode( ', ', $this->clearMessages() );
throw ( $ex );
} finally {
$this->unlock();
}
if ( $dryrun ) {
return $statements;
}
return sprintf( $msg, $counter );
}
/** Put the site into maintenance mode and lock a list of tables
*
* @param $tableList
* @param $alreadyPrefixed
*
* @throws ImfsException
*/
public function lock( $tableList, $alreadyPrefixed ) {
global $wpdb;
if ( ! is_array( $tableList ) || count( $tableList ) === 0 ) {
throw new ImfsException( "Invalid attempt to lock. At least one table must be locked" );
}
$tablesToLock = [];
foreach ( $tableList as $tbl ) {
if ( ! $alreadyPrefixed ) {
$tbl = $wpdb->prefix . $tbl;
}
$tablesToLock[] = $tbl;
}
/* always specify locks in the same order to avoid starving the philosophers */
sort( $tablesToLock );
$tables = [];
foreach ( $tablesToLock as $tbl ) {
$tables[] = '`' . $tbl . '` WRITE';
}
$this->enterMaintenanceMode();
$q = "LOCK TABLES " . implode( ', ', $tables );
$this->query( $q );
}
/**
* @param int $duration how many seconds until maintenance expires
*/
public function enterMaintenanceMode( $duration = 60 ) {
$maintenanceFileName = ABSPATH . '.maintenance';
if ( is_writable( ABSPATH ) ) {
$maintain = [];
$expirationTs = time() + $duration - 600;
array_push( $maintain,
'<?php',
'/* Maintenance Mode was entered by ' .
index_wp_mysql_for_speed_PLUGIN_NAME .
' for table reindexing at ' .
date( "Y-m-d H:i:s" ) . ' */',
/* notice that maintenance expires ten minutes, 600 sec, after the time in the file. */
'$upgrading = ' . $expirationTs . ';',
'?>' );
file_put_contents( $maintenanceFileName, implode( PHP_EOL, $maintain ) );
}
}
/**
* @throws ImfsException
*/
public function upgradeTableStorageEngine( $table, $dryrun = false ) {
$sql = 'ALTER TABLE `' . $table . '` ENGINE=InnoDb, ROW_FORMAT=DYNAMIC;';
if ( $dryrun ) {
return $sql;
}
$this->set_runtime_limit();
$this->query( $sql, true );
return true;
}
/** Resets the messages in this class and returns the previous messages.
* @return array
*/
public function clearMessages() {
$msgs = $this->messages;
$this->messages = [];
return $msgs;
}
/** Undo lock. This is ideally called from a finally{} clause.
* @throws ImfsException
*/
public function unlock() {
$this->query( "UNLOCK TABLES" );
$this->leaveMaintenanceMode();
}
public function leaveMaintenanceMode() {
$maintenanceFileName = ABSPATH . '.maintenance';
if ( is_writable( ABSPATH ) && file_exists( $maintenanceFileName ) ) {
unlink( $maintenanceFileName );
}
}
public function getHealthReport() {
require_once( 'health.php' );
$allStats = imfsGetAllStats( $this );
$allStats['variables']->hostname = DB_HOST;
$health = new Health ( $allStats, time() );
return $health->getReport();
}
}
class ImfsException extends Exception {
protected $message;
private $query;
public function __construct( $message, $query = '', $code = 0, $previous = null ) {
global $wpdb;
$this->query = $query;
parent::__construct( $message, $code, $previous );
$wpdb->flush();
}
public function __toString() {
return __CLASS__ . ": [$this->code]: $this->message in $this->query\n";
}
}