AdapterMySQL.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC\DB;
  8. class AdapterMySQL extends Adapter {
  9. /** @var string */
  10. protected $collation;
  11. /**
  12. * @param string $tableName
  13. */
  14. public function lockTable($tableName) {
  15. $this->conn->executeUpdate('LOCK TABLES `' .$tableName . '` WRITE');
  16. }
  17. public function unlockTable() {
  18. $this->conn->executeUpdate('UNLOCK TABLES');
  19. }
  20. public function fixupStatement($statement) {
  21. $statement = str_replace(' ILIKE ', ' COLLATE ' . $this->getCollation() . ' LIKE ', $statement);
  22. return $statement;
  23. }
  24. protected function getCollation(): string {
  25. if (!$this->collation) {
  26. $params = $this->conn->getParams();
  27. $this->collation = $params['collation'] ?? (($params['charset'] ?? 'utf8') . '_general_ci');
  28. }
  29. return $this->collation;
  30. }
  31. public function insertIgnoreConflict(string $table, array $values): int {
  32. $builder = $this->conn->getQueryBuilder();
  33. $builder->insert($table);
  34. $updates = [];
  35. foreach ($values as $key => $value) {
  36. $builder->setValue($key, $builder->createNamedParameter($value));
  37. }
  38. /*
  39. * We can't use ON DUPLICATE KEY UPDATE here because Nextcloud use the CLIENT_FOUND_ROWS flag
  40. * With this flag the MySQL returns the number of selected rows
  41. * instead of the number of affected/modified rows
  42. * It's impossible to change this behaviour at runtime or for a single query
  43. * Then, the result is 1 if a row is inserted and also 1 if a row is updated with same or different values
  44. *
  45. * With INSERT IGNORE, the result is 1 when a row is inserted, 0 otherwise
  46. *
  47. * Risk: it can also ignore other errors like type mismatch or truncated data…
  48. */
  49. $res = $this->conn->executeStatement(
  50. preg_replace('/^INSERT/i', 'INSERT IGNORE', $builder->getSQL()),
  51. $builder->getParameters(),
  52. $builder->getParameterTypes()
  53. );
  54. return $res;
  55. }
  56. }