Querying json data now works in mysql

Added prisma extension to convert "path" from array format (postgresql) to string format (mysql)
This commit is contained in:
w35l3y 2025-06-01 17:25:20 -03:00 committed by GitHub
parent 427c994993
commit ebe9b00a9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 99 additions and 2 deletions

View File

@ -0,0 +1,61 @@
import { Prisma } from '@prisma/client'
import { Logger } from '@config/logger.config';
const logger = new Logger('PGPATH2MYSQL');
function convertPgPathToMysql (path) {
if (!Array.isArray(path)) return path
let result = '$'
for (const item of path) {
if (/^\d+$/.test(item)) {
result += `[${item}]`
} else {
result += `.${item}`
}
}
return result
}
function processWhere (obj) {
if (obj && typeof obj === 'object') {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (key === 'path') {
obj[key] = convertPgPathToMysql(obj[key]);
} else {
processWhere(obj[key]);
}
}
}
}
}
// https://www.prisma.io/docs/orm/prisma-client/client-extensions/query#modify-all-operations-in-all-models-of-your-schema
// https://www.prisma.io/docs/orm/prisma-client/client-extensions/query#modify-a-specific-operation-in-a-specific-model
const overriddenOperation = async ({ model, operation, args, query }) => {
if (args?.where) {
processWhere(args.where)
}
const result = await query(args)
logger.debug({ model, operation, args: JSON.stringify(args), result })
return result
}
export default Prisma.defineExtension({
name: 'prisma-extension-pgpath-to-mysql',
query: {
$allModels: {
findFirst: overriddenOperation,
findMany: overriddenOperation,
updateMany: overriddenOperation,
count: overriddenOperation,
deleteMany: overriddenOperation,
delete: overriddenOperation,
findUnique: overriddenOperation,
update: overriddenOperation,
upsert: overriddenOperation,
}
}
})

View File

@ -1,5 +1,5 @@
import { CacheEngine } from '@cache/cacheengine';
import { Chatwoot, configService, ProviderSession } from '@config/env.config';
import { Chatwoot, configService, ProviderSession, Database } from '@config/env.config';
import { eventEmitter } from '@config/event.config';
import { Logger } from '@config/logger.config';
@ -40,6 +40,9 @@ import { ProxyService } from './services/proxy.service';
import { SettingsService } from './services/settings.service';
import { TemplateService } from './services/template.service';
import pgPathToMysql from './extensions/prismaExtensionPgpathToMysql';
import { extendsWithProxy } from '@utils/extendsWithProxy';
const logger = new Logger('WA MODULE');
let chatwootCache: CacheService = null;
@ -55,7 +58,12 @@ if (configService.get<ProviderSession>('PROVIDER').ENABLED) {
providerFiles = new ProviderFiles(configService);
}
export const prismaRepository = new PrismaRepository(configService);
const provider = configService.get<Database>('DATABASE').PROVIDER;
let extendablePrismaRepository: PrismaRepository = new PrismaRepository(configService)
if (provider === "mysql") {
extendablePrismaRepository = extendsWithProxy(extendablePrismaRepository, pgPathToMysql);
}
export const prismaRepository = extendablePrismaRepository;
export const waMonitor = new WAMonitoringService(
eventEmitter,

View File

@ -0,0 +1,27 @@
import { PrismaClient } from '@prisma/client';
type ExtensionArgs = Parameters<PrismaClient['$extends']>[0];
export function extendsWithProxy<T extends PrismaClient>(
instanciaBase: T,
extensao: ExtensionArgs
): T {
const instanciaEstendida = instanciaBase.$extends(extensao);
const proxy = new Proxy(instanciaBase as unknown as object, {
get(target, prop, receiver) {
if (prop === 'toString') {
return () => '[Proxy toString]';
}
if (prop === Symbol.toStringTag) {
return undefined;
}
return prop in instanciaEstendida ? Reflect.get(instanciaEstendida as any, prop, receiver) : Reflect.get(target, prop, receiver);
},
has(target, prop) {
return prop in target || prop in (instanciaEstendida as any);
},
});
return proxy as unknown as T;
}

View File

@ -17,6 +17,7 @@
"strictNullChecks": false,
"incremental": true,
"noImplicitAny": false,
"allowJs": true,
"baseUrl": ".",
"paths": {
"@api/*": ["./src/api/*"],