X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FDatabase%2FDatabase.php;h=0b38c24ba336b9ab27308dcdbfddeb2f0cca567e;hb=d53f46b9583737668a3314a22d1eeacb00a47db2;hp=7adb88ffa87aec4c6d1cff7025b9b28ffc0a9596;hpb=ce8e200461ed777fb31a9d3c2f07c7e8c31b3b56;p=friendica.git diff --git a/src/Database/Database.php b/src/Database/Database.php index 7adb88ffa8..0b38c24ba3 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -135,8 +135,9 @@ class Database } $this->emulate_prepares = (bool)$this->configCache->get('database', 'emulate_prepares'); + $this->pdo_emulate_prepares = (bool)$this->configCache->get('database', 'pdo_emulate_prepares'); - if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) { + if (!$this->configCache->get('database', 'disable_pdo') && class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) { $this->driver = 'pdo'; $connect = "mysql:host=" . $server . ";dbname=" . $db; @@ -150,7 +151,7 @@ class Database try { $this->connection = @new PDO($connect, $user, $pass); - $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares); $this->connected = true; } catch (PDOException $e) { $this->connected = false; @@ -318,7 +319,7 @@ class Database } $watchlist = explode(',', $this->configCache->get('system', 'db_log_index_watch')); - $blacklist = explode(',', $this->configCache->get('system', 'db_log_index_blacklist')); + $denylist = explode(',', $this->configCache->get('system', 'db_log_index_denylist')); while ($row = $this->fetch($r)) { if ((intval($this->configCache->get('system', 'db_loglimit_index')) > 0)) { @@ -332,7 +333,7 @@ class Database $log = true; } - if (in_array($row['key'], $blacklist) || ($row['key'] == "")) { + if (in_array($row['key'], $denylist) || ($row['key'] == "")) { $log = false; } @@ -342,13 +343,13 @@ class Database $row['key'] . "\t" . $row['rows'] . "\t" . $row['Extra'] . "\t" . basename($backtrace[1]["file"]) . "\t" . $backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" . - substr($query, 0, 2000) . "\n", FILE_APPEND); + substr($query, 0, 4000) . "\n", FILE_APPEND); } } } /** - * Removes every not whitelisted character from the identifier string + * Removes every not allowlisted character from the identifier string * * @param string $identifier * @@ -504,6 +505,7 @@ class Database $sql = "/*" . System::callstack() . " */ " . $sql; } + $is_error = false; $this->error = ''; $this->errorno = 0; $this->affected_rows = 0; @@ -533,6 +535,7 @@ class Database $this->error = $errorInfo[2]; $this->errorno = $errorInfo[1]; $retval = false; + $is_error = true; break; } $this->affected_rows = $retval->rowCount(); @@ -545,6 +548,7 @@ class Database $this->error = $errorInfo[2]; $this->errorno = $errorInfo[1]; $retval = false; + $is_error = true; break; } @@ -562,6 +566,7 @@ class Database $this->error = $errorInfo[2]; $this->errorno = $errorInfo[1]; $retval = false; + $is_error = true; } else { $retval = $stmt; $this->affected_rows = $retval->rowCount(); @@ -580,6 +585,7 @@ class Database $this->error = $this->connection->error; $this->errorno = $this->connection->errno; $retval = false; + $is_error = true; } else { if (isset($retval->num_rows)) { $this->affected_rows = $retval->num_rows; @@ -596,6 +602,7 @@ class Database $this->error = $stmt->error; $this->errorno = $stmt->errno; $retval = false; + $is_error = true; break; } @@ -623,6 +630,7 @@ class Database $this->error = $this->connection->error; $this->errorno = $this->connection->errno; $retval = false; + $is_error = true; } else { $stmt->store_result(); $retval = $stmt; @@ -631,6 +639,16 @@ class Database break; } + // See issue https://github.com/friendica/friendica/issues/8572 + // Ensure that we always get an error message on an error. + if ($is_error && empty($this->errorno)) { + $this->errorno = -1; + } + + if ($is_error && empty($this->error)) { + $this->error = 'Unknown database error'; + } + // We are having an own error logging in the function "e" if (($this->errorno != 0) && !$called_from_e) { // We have to preserve the error code, somewhere in the logging it get lost @@ -642,8 +660,8 @@ class Database } $this->logger->error('DB Error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, 'callstack' => System::callstack(8), 'params' => $this->replaceParameters($sql, $args), ]); @@ -654,21 +672,21 @@ class Database // It doesn't make sense to continue when the database connection was lost if ($this->in_retrial) { $this->logger->notice('Giving up retrial because of database error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, ]); } else { $this->logger->notice('Couldn\'t reconnect after database error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, ]); } exit(1); } else { // We try it again $this->logger->notice('Reconnected after database error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, ]); $this->in_retrial = true; $ret = $this->p($sql, $args); @@ -681,7 +699,7 @@ class Database $this->errorno = $errorno; } - $this->profiler->saveTimestamp($stamp1, 'database', System::callstack()); + $this->profiler->saveTimestamp($stamp1, 'database'); if ($this->configCache->get('system', 'db_log')) { $stamp2 = microtime(true); @@ -694,7 +712,7 @@ class Database @file_put_contents($this->configCache->get('system', 'db_log'), DateTimeFormat::utcNow() . "\t" . $duration . "\t" . basename($backtrace[1]["file"]) . "\t" . $backtrace[1]["line"] . "\t" . $backtrace[2]["function"] . "\t" . - substr($this->replaceParameters($sql, $args), 0, 2000) . "\n", FILE_APPEND); + substr($this->replaceParameters($sql, $args), 0, 4000) . "\n", FILE_APPEND); } } return $retval; @@ -745,8 +763,8 @@ class Database } $this->logger->error('DB Error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, 'callstack' => System::callstack(8), 'params' => $this->replaceParameters($sql, $params), ]); @@ -755,8 +773,8 @@ class Database // A reconnect like in $this->p could be dangerous with modifications if ($errorno == 2006) { $this->logger->notice('Giving up because of database error', [ - 'code' => $this->errorno, - 'error' => $this->error, + 'code' => $errorno, + 'error' => $error, ]); exit(1); } @@ -765,7 +783,7 @@ class Database $this->errorno = $errorno; } - $this->profiler->saveTimestamp($stamp, "database_write", System::callstack()); + $this->profiler->saveTimestamp($stamp, "database_write"); return $retval; } @@ -946,7 +964,7 @@ class Database } } - $this->profiler->saveTimestamp($stamp1, 'database', System::callstack()); + $this->profiler->saveTimestamp($stamp1, 'database'); return $columns; } @@ -961,7 +979,7 @@ class Database * @return boolean was the insert successful? * @throws \Exception */ - public function insert($table, $param, $on_duplicate_update = false) + public function insert($table, array $param, bool $on_duplicate_update = false) { if (empty($table) || empty($param)) { $this->logger->info('Table and fields have to be set'); @@ -1029,7 +1047,7 @@ class Database $success = $this->e("LOCK TABLES " . DBA::buildTableString($table) . " WRITE"); if ($this->driver == 'pdo') { - $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares); } if (!$success) { @@ -1062,7 +1080,7 @@ class Database $success = $this->e("UNLOCK TABLES"); if ($this->driver == 'pdo') { - $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares); $this->e("SET autocommit=1"); } else { $this->connection->autocommit(true); @@ -1449,24 +1467,30 @@ class Database /** * Select rows from a table * - * @param string|array $table Table name or array [schema => table] - * @param array $fields Array of selected fields, empty for all - * @param array $condition Array of fields for condition - * @param array $params Array of several parameters - * - * @return boolean|object * * Example: - * $table = "item"; - * $fields = array("id", "uri", "uid", "network"); + * $table = 'item'; + * or: + * $table = ['schema' => 'table']; + * @see DBA::buildTableString() + * + * $fields = ['id', 'uri', 'uid', 'network']; * - * $condition = array("uid" => 1, "network" => 'dspr'); + * $condition = ['uid' => 1, 'network' => 'dspr', 'blocked' => true]; * or: - * $condition = array("`uid` = ? AND `network` IN (?, ?)", 1, 'dfrn', 'dspr'); + * $condition = ['`uid` = ? AND `network` IN (?, ?)', 1, 'dfrn', 'dspr']; + * @see DBA::buildCondition() * - * $params = array("order" => array("id", "received" => true), "limit" => 10); + * $params = ['order' => ['id', 'received' => true, 'created' => 'ASC'), 'limit' => 10]; + * @see DBA::buildParameter() * * $data = DBA::select($table, $fields, $condition, $params); + * + * @param string|array $table Table name or array [schema => table] + * @param array $fields Array of selected fields, empty for all + * @param array $condition Array of fields for condition + * @param array $params Array of several parameters + * @return boolean|object * @throws \Exception */ public function select($table, array $fields = [], array $condition = [], array $params = []) @@ -1620,7 +1644,7 @@ class Database break; } - $this->profiler->saveTimestamp($stamp1, 'database', System::callstack()); + $this->profiler->saveTimestamp($stamp1, 'database'); return $ret; }