X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fhelpers%2Fdatabase-utils.ts;h=b5dc70c17dbb33ae9871baf9754628259f95a185;hb=a6a12dae10658a1fa7120ad39702c07137143954;hp=11304cafb684988f4c7ebedd88f7d05d0ef62290;hpb=1e11f67be4d1c1ed93b298798ffdc81a2bd50a4e;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts index 11304cafb..b5dc70c17 100644 --- a/server/helpers/database-utils.ts +++ b/server/helpers/database-utils.ts @@ -1,8 +1,18 @@ import * as retry from 'async/retry' import * as Bluebird from 'bluebird' +import { QueryTypes, Transaction } from 'sequelize' import { Model } from 'sequelize-typescript' +import { sequelizeTypescript } from '@server/initializers/database' import { logger } from './logger' +function retryTransactionWrapper ( + functionToRetry: (arg1: A, arg2: B, arg3: C, arg4: D) => Promise | Bluebird, + arg1: A, + arg2: B, + arg3: C, + arg4: D, +): Promise + function retryTransactionWrapper ( functionToRetry: (arg1: A, arg2: B, arg3: C) => Promise | Bluebird, arg1: A, @@ -48,7 +58,7 @@ function transactionRetryer (func: (err: any, data: T) => any) { errorFilter: err => { const willRetry = (err.name === 'SequelizeDatabaseError') - logger.debug('Maybe retrying the transaction function.', { willRetry, err }) + logger.debug('Maybe retrying the transaction function.', { willRetry, err, tags: [ 'sql', 'retry' ] }) return willRetry } }, @@ -58,18 +68,66 @@ function transactionRetryer (func: (err: any, data: T) => any) { }) } -function updateInstanceWithAnother > (instanceToUpdate: Model, baseInstance: Model) { +// --------------------------------------------------------------------------- + +function updateInstanceWithAnother > (instanceToUpdate: T, baseInstance: U) { const obj = baseInstance.toJSON() for (const key of Object.keys(obj)) { - instanceToUpdate.set(key, obj[key]) + instanceToUpdate[key] = obj[key] } } +function resetSequelizeInstance (instance: Model, savedFields: object) { + Object.keys(savedFields).forEach(key => { + instance[key] = savedFields[key] + }) +} + +function deleteNonExistingModels > ( + fromDatabase: T[], + newModels: T[], + t: Transaction +) { + return fromDatabase.filter(f => !newModels.find(newModel => newModel.hasSameUniqueKeysThan(f))) + .map(f => f.destroy({ transaction: t })) +} + +// Sequelize always skip the update if we only update updatedAt field +function setAsUpdated (table: string, id: number, transaction?: Transaction) { + return sequelizeTypescript.query( + `UPDATE "${table}" SET "updatedAt" = :updatedAt WHERE id = :id`, + { + replacements: { table, id, updatedAt: new Date() }, + type: QueryTypes.UPDATE, + transaction + } + ) +} + +// --------------------------------------------------------------------------- + +function runInReadCommittedTransaction (fn: (t: Transaction) => Promise) { + const options = { isolationLevel: Transaction.ISOLATION_LEVELS.READ_COMMITTED } + + return sequelizeTypescript.transaction(options, t => fn(t)) +} + +function afterCommitIfTransaction (t: Transaction, fn: Function) { + if (t) return t.afterCommit(() => fn()) + + return fn() +} + // --------------------------------------------------------------------------- export { + resetSequelizeInstance, retryTransactionWrapper, transactionRetryer, - updateInstanceWithAnother + updateInstanceWithAnother, + afterCommitIfTransaction, + deleteNonExistingModels, + setAsUpdated, + runInReadCommittedTransaction }