X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FDatabase%2FDatabase.php;h=671425f9d188c8d19a42f0544b177db7aa9a98d6;hb=e8fee5644b5e746f8c09e604caac3d678f376989;hp=a6cc3f875d4cbcade03934afe637e9bad585f676;hpb=24f8ee8e676abf4dd16916fd417562aca7bcbb9f;p=friendica.git diff --git a/src/Database/Database.php b/src/Database/Database.php index a6cc3f875d..671425f9d1 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1,6 +1,6 @@ configCache->get('database', 'password')); $db = trim($this->configCache->get('database', 'database')); $charset = trim($this->configCache->get('database', 'charset')); + $socket = trim($this->configCache->get('database', 'socket')); if (!(strlen($server) && strlen($user))) { return false; @@ -135,9 +136,14 @@ class Database $connect .= ";charset=" . $charset; } + if ($socket) { + $connect .= ";$unix_socket=" . $socket; + } + try { $this->connection = @new PDO($connect, $user, $pass, [PDO::ATTR_PERSISTENT => $persistent]); $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares); + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $this->connected = true; } catch (PDOException $e) { $this->connected = false; @@ -159,6 +165,11 @@ class Database if ($charset) { $this->connection->set_charset($charset); } + + if ($socket) { + $this->connection->set_socket($socket); + } + } } @@ -520,7 +531,7 @@ class Database $called_from_e = ($called_from['function'] == 'e'); if (!isset($this->connection)) { - throw new InternalServerErrorException('The Connection is empty, although connected is set true.'); + throw new ServiceUnavailableException('The Connection is empty, although connected is set true.'); } switch ($this->driver) { @@ -1142,7 +1153,7 @@ class Database * * @return boolean Was the command executed successfully? */ - public function transaction() + public function transaction(): bool { if (!$this->performCommit()) { return false; @@ -1273,11 +1284,12 @@ class Database * @param array $fields contains the fields that are updated * @param array $condition condition array with the key values * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate, false = don't update identical fields) + * @param array $params Parameters: "ignore" If set to "true" then the update is done with the ignore parameter * * @return boolean was the update successfull? * @throws \Exception */ - public function update($table, $fields, $condition, $old_fields = []) + public function update($table, $fields, $condition, $old_fields = [], $params = []) { if (empty($table) || empty($fields) || empty($condition)) { $this->logger->info('Table, fields and condition have to be set'); @@ -1314,7 +1326,13 @@ class Database $condition_string = DBA::buildCondition($condition); - $sql = "UPDATE " . $table_string . " SET " + if (!empty($params['ignore'])) { + $ignore = 'IGNORE '; + } else { + $ignore = ''; + } + + $sql = "UPDATE " . $ignore . $table_string . " SET " . implode(" = ?, ", array_map([DBA::class, 'quoteIdentifier'], array_keys($fields))) . " = ?" . $condition_string; @@ -1367,6 +1385,45 @@ class Database return $this->toArray($this->select($table, $fields, $condition, $params)); } + /** + * Escape fields, adding special treatment for "group by" handling + * + * @param array $fields + * @param array $options + * @return array + */ + private function escapeFields(array $fields, array $options) + { + // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. + // This needs to done to apply the "ANY_VALUE(...)" treatment from below to them. + // Otherwise MySQL would report errors. + if (!empty($options['group_by']) && !empty($options['order'])) { + foreach ($options['order'] as $key => $field) { + if (!is_int($key)) { + if (!in_array($key, $fields)) { + $fields[] = $key; + } + } else { + if (!in_array($field, $fields)) { + $fields[] = $field; + } + } + } + } + + array_walk($fields, function(&$value, $key) use ($options) + { + $field = $value; + $value = '`' . str_replace('`', '``', $value) . '`'; + + if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) { + $value = 'ANY_VALUE(' . $value . ') AS ' . $value; + } + }); + + return $fields; + } + /** * Select rows from a table * @@ -1403,7 +1460,8 @@ class Database } if (count($fields) > 0) { - $select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $fields)); + $fields = $this->escapeFields($fields, $params); + $select_string = implode(', ', $fields); } else { $select_string = '*'; } @@ -1739,4 +1797,32 @@ class Database { array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation); } + + /** + * Replaces a string in the provided fields of the provided table + * + * @param string $table_name + * @param array $fields List of field names in the provided table + * @param string $search + * @param string $replace + * @throws \Exception + */ + public function replaceInTableFields(string $table_name, array $fields, string $search, string $replace) + { + $search = $this->escape($search); + $replace = $this->escape($replace); + + $upd = []; + foreach ($fields as $field) { + $field = DBA::quoteIdentifier($field); + $upd[] = "$field = REPLACE($field, '$search', '$replace')"; + } + + $upds = implode(', ', $upd); + + $r = $this->e(sprintf("UPDATE %s SET %s;", $table_name, $upds)); + if (!$this->isResult($r)) { + throw new \RuntimeException("Failed updating `$table_name`: " . $this->errorMessage()); + } + } }