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, private readonly IDBConnection $connection,
) { ) {
} }
public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
$qb = $this->connection->getQueryBuilder(); $qb = $this->connection->getQueryBuilder();
$qb->update('share') $qb->update('share')
->set('attributes', $qb->createNamedParameter('[["permissions","download",true]]')) ->set('attributes', $qb->createNamedParameter('[["permissions","download",true]]'))
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE, IQueryBuilder::PARAM_INT))) ->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));
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(); $qb->executeStatement();
} }
} }

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

@ -160,8 +160,12 @@ class ExpressionBuilderDBTest extends TestCase {
$query = $this->connection->getQueryBuilder(); $query = $this->connection->getQueryBuilder();
$query->update('share') $query->update('share')
->set('attributes', $query->createNamedParameter('[["permissions","after"]]')) ->set('attributes', $query->createNamedParameter('[["permissions","after"]]'));
->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON)); 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->executeStatement();
$query = $this->connection->getQueryBuilder(); $query = $this->connection->getQueryBuilder();
@ -173,7 +177,7 @@ class ExpressionBuilderDBTest extends TestCase {
$entries = $result->fetchAll(); $entries = $result->fetchAll();
$result->closeCursor(); $result->closeCursor();
self::assertCount(1, $entries); 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 { public function testDateTimeEquals(): void {