diff --git a/.changeset/five-carrots-pay.md b/.changeset/five-carrots-pay.md new file mode 100644 index 0000000000..60fa91c163 --- /dev/null +++ b/.changeset/five-carrots-pay.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-tasks': patch +'@backstage/plugin-catalog-backend': patch +--- + +Added support to mysql on some raw queries diff --git a/packages/backend-tasks/src/tasks/TaskWorker.ts b/packages/backend-tasks/src/tasks/TaskWorker.ts index c99c08e4fb..f56c03c3d5 100644 --- a/packages/backend-tasks/src/tasks/TaskWorker.ts +++ b/packages/backend-tasks/src/tasks/TaskWorker.ts @@ -292,14 +292,21 @@ export class TaskWorker { seconds: dt, })}`, ); - nextRun = this.knex.client.config.client.includes('sqlite3') - ? this.knex.raw( - `max(datetime(next_run_start_at, ?), datetime('now'))`, - [`+${dt} seconds`], - ) - : this.knex.raw( - `greatest(next_run_start_at + interval '${dt} seconds', now())`, - ); + + if (this.knex.client.config.client.includes('sqlite3')) { + nextRun = this.knex.raw( + `max(datetime(next_run_start_at, ?), datetime('now'))`, + [`+${dt} seconds`], + ); + } else if (this.knex.client.config.client.includes('mysql')) { + nextRun = this.knex.raw( + `greatest(next_run_start_at + interval ${dt} second, now())`, + ); + } else { + nextRun = this.knex.raw( + `greatest(next_run_start_at + interval '${dt} seconds', now())`, + ); + } } const rows = await this.knex(DB_TASKS_TABLE) diff --git a/packages/backend-tasks/src/tasks/util.ts b/packages/backend-tasks/src/tasks/util.ts index 34280cc2d4..2561203318 100644 --- a/packages/backend-tasks/src/tasks/util.ts +++ b/packages/backend-tasks/src/tasks/util.ts @@ -38,9 +38,16 @@ export function nowPlus(duration: Duration | undefined, knex: Knex) { if (!seconds) { return knex.fn.now(); } - return knex.client.config.client.includes('sqlite3') - ? knex.raw(`datetime('now', ?)`, [`${seconds} seconds`]) - : knex.raw(`now() + interval '${seconds} seconds'`); + + if (knex.client.config.client.includes('sqlite3')) { + return knex.raw(`datetime('now', ?)`, [`${seconds} seconds`]); + } + + if (knex.client.config.client.includes('mysql')) { + return knex.raw(`now() + interval ${seconds} second`); + } + + return knex.raw(`now() + interval '${seconds} seconds'`); } /** diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts index c9b71d096d..1cf2643339 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts @@ -113,7 +113,10 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { // Delete old relations let previousRelationRows: DbRelationsRow[]; - if (tx.client.config.client.includes('sqlite3')) { + if ( + tx.client.config.client.includes('sqlite3') || + tx.client.config.client.includes('mysql') + ) { previousRelationRows = await tx('relations') .select('*') .where({ originating_entity_id: id }); @@ -201,6 +204,13 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { let removedCount = 0; + const rootId = () => { + if (tx.client.config.client.includes('mysql')) { + return tx.raw('CAST(NULL as UNSIGNED INT)', []); + } + + return tx.raw('CAST(NULL as INT)', []); + }; for (const refs of lodash.chunk(toRemove, 1000)) { /* WITH RECURSIVE @@ -266,7 +276,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .withRecursive('ancestors', function ancestors(outer) { return outer .select({ - root_id: tx.raw('CAST(NULL as INT)', []), + root_id: rootId(), via_entity_ref: 'entity_ref', to_entity_ref: 'entity_ref', }) @@ -435,15 +445,26 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .orderBy('next_update_at', 'asc'); const interval = this.options.refreshInterval(); + + const nextUpdateAt = (refreshInterval: number) => { + if (tx.client.config.client.includes('sqlite3')) { + return tx.raw(`datetime('now', ?)`, [`${refreshInterval} seconds`]); + } + + if (tx.client.config.client.includes('mysql')) { + return tx.raw(`now() + interval ${refreshInterval} second`); + } + + return tx.raw(`now() + interval '${refreshInterval} seconds'`); + }; + await tx('refresh_state') .whereIn( 'entity_ref', items.map(i => i.entity_ref), ) .update({ - next_update_at: tx.client.config.client.includes('sqlite3') - ? tx.raw(`datetime('now', ?)`, [`${interval} seconds`]) - : tx.raw(`now() + interval '${interval} seconds'`), + next_update_at: nextUpdateAt(interval), }); return {