fix(db): Fix comparing JSON data in MySQL and MariaDB

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/56504/head
Joas Schilling 2025-11-18 10:10:44 +07:00
parent fb8caecbb0
commit 4676b12a32
No known key found for this signature in database
GPG Key ID: F72FA5B49FFA96B0
3 changed files with 18 additions and 5 deletions

@ -21,12 +21,19 @@ class Version33000Date20251106131209 extends SimpleMigrationStep {
private readonly IDBConnection $connection,
) {
}
public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
$qb = $this->connection->getQueryBuilder();
$qb->update('share')
->set('attributes', $qb->createNamedParameter('[["permissions","download",true]]'))
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('attributes', $qb->createNamedParameter('[["permissions","download",null]]'), IQueryBuilder::PARAM_JSON));
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE, IQueryBuilder::PARAM_INT)));
if ($this->connection->getDatabaseProvider(true) === IDBConnection::PLATFORM_MYSQL) {
$qb->andWhere($qb->expr()->eq('attributes', $qb->createFunction("JSON_ARRAY(JSON_ARRAY('permissions','download',null))"), IQueryBuilder::PARAM_JSON));
} else {
$qb->andWhere($qb->expr()->eq('attributes', $qb->createNamedParameter('[["permissions","download",null]]'), IQueryBuilder::PARAM_JSON));
}
$qb->executeStatement();
}
}

@ -44,6 +44,8 @@ class MySqlExpressionBuilder extends ExpressionBuilder {
switch ($type) {
case IQueryBuilder::PARAM_STR:
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS CHAR)');
case IQueryBuilder::PARAM_JSON:
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS JSON)');
default:
return parent::castColumn($column, $type);
}

@ -160,8 +160,12 @@ class ExpressionBuilderDBTest extends TestCase {
$query = $this->connection->getQueryBuilder();
$query->update('share')
->set('attributes', $query->createNamedParameter('[["permissions","after"]]'))
->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON));
->set('attributes', $query->createNamedParameter('[["permissions","after"]]'));
if ($this->connection->getDatabaseProvider(true) === IDBConnection::PLATFORM_MYSQL) {
$query->where($query->expr()->eq('attributes', $query->createFunction("JSON_ARRAY(JSON_ARRAY('permissions','before'))"), IQueryBuilder::PARAM_JSON));
} else {
$query->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON));
}
$query->executeStatement();
$query = $this->connection->getQueryBuilder();
@ -173,7 +177,7 @@ class ExpressionBuilderDBTest extends TestCase {
$entries = $result->fetchAll();
$result->closeCursor();
self::assertCount(1, $entries);
self::assertEquals('[["permissions","after"]]', $entries[0]['attributes']);
self::assertEquals([['permissions','after']], json_decode($entries[0]['attributes'], true));
}
public function testDateTimeEquals(): void {