|
8 | 8 |
|
9 | 9 | namespace OC\DB; |
10 | 10 |
|
| 11 | +use OCP\DB\QueryBuilder\IQueryBuilder; |
| 12 | + |
11 | 13 | class AdapterMySQL extends Adapter { |
12 | 14 | /** @var string */ |
13 | 15 | protected $collation; |
@@ -40,19 +42,32 @@ protected function getCollation(): string { |
40 | 42 | return $this->collation; |
41 | 43 | } |
42 | 44 |
|
43 | | - /** |
44 | | - * We can't use ON DUPLICATE KEY UPDATE here because Nextcloud use the CLIENT_FOUND_ROWS flag |
45 | | - * With this flag the MySQL returns the number of selected rows |
46 | | - * instead of the number of affected/modified rows |
47 | | - * It's impossible to change this behaviour at runtime or for a single query |
48 | | - * Then, the result is 1 if a row is inserted and also 1 if a row is updated with same or different values |
49 | | - * |
50 | | - * With INSERT IGNORE, the result is 1 when a row is inserted, 0 otherwise |
51 | | - * |
52 | | - * Risk: it can also ignore other errors like type mismatch or truncated data… |
53 | | - */ |
54 | 45 | #[\Override] |
55 | | - public function getInsertIgnoreConflictSql(string $sql): string { |
56 | | - return preg_replace('/^INSERT/i', 'INSERT IGNORE', $sql) ?? $sql; |
| 46 | + public function insertIgnoreConflict(string $table, array $values, array $types = []): int { |
| 47 | + $builder = $this->conn->getQueryBuilder(); |
| 48 | + $builder->insert($table); |
| 49 | + $updates = []; |
| 50 | + foreach ($values as $key => $value) { |
| 51 | + $builder->setValue($key, $builder->createNamedParameter($value, $types[$key] ?? IQueryBuilder::PARAM_STR)); |
| 52 | + } |
| 53 | + |
| 54 | + /* |
| 55 | + * We can't use ON DUPLICATE KEY UPDATE here because Nextcloud use the CLIENT_FOUND_ROWS flag |
| 56 | + * With this flag the MySQL returns the number of selected rows |
| 57 | + * instead of the number of affected/modified rows |
| 58 | + * It's impossible to change this behaviour at runtime or for a single query |
| 59 | + * Then, the result is 1 if a row is inserted and also 1 if a row is updated with same or different values |
| 60 | + * |
| 61 | + * With INSERT IGNORE, the result is 1 when a row is inserted, 0 otherwise |
| 62 | + * |
| 63 | + * Risk: it can also ignore other errors like type mismatch or truncated data… |
| 64 | + */ |
| 65 | + $res = $this->conn->executeStatement( |
| 66 | + preg_replace('/^INSERT/i', 'INSERT IGNORE', $builder->getSQL()), |
| 67 | + $builder->getParameters(), |
| 68 | + $builder->getParameterTypes() |
| 69 | + ); |
| 70 | + |
| 71 | + return $res; |
57 | 72 | } |
58 | 73 | } |
0 commit comments