Advertisement
4nd3rs0n

Untitled

Jan 17th, 2024
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import pg from "pg"
  2. import tx from "pg-tx"
  3. import fsp from "fs/promises"
  4. import { VerAndLabel } from "../entities";
  5. import path from "path";
  6. import { verAndLabelToFName } from "./utils";
  7.  
  8.  
  9. // Apply a single migration from a file
  10. export const applyMigration = async (client: pg.PoolClient | pg.PoolClient, fpath: string, version: number, label: string) => {
  11.   let queryBuff = await fsp.readFile(fpath).catch(err => { throw err });
  12.   await tx(client, async (db) => {
  13.     db.query(queryBuff.toString());
  14.     db.query("INSERT INTO applied_migrations (version, label) VALUES ($1, $2)", [version, label]);
  15.   });
  16. };
  17.  
  18.  
  19. // Rollback a single migration using down migration from a file
  20. export const rollbackMigration = async (client: pg.PoolClient | pg.PoolClient, down_fpath: string, version: number) => {
  21.   let queryBuff = await fsp.readFile(down_fpath).catch(err => { throw err });
  22.   await tx(client, async (db) => {
  23.     await db.query(queryBuff.toString());
  24.     await db.query("DELETE FROM applied_migrations WHERE version=$1", [version]);
  25.   });
  26. };
  27.  
  28.  
  29. // Before rolling back be sure that applied migrations contain target version
  30. export const rollbackToVer = async (
  31.   client: pg.PoolClient | pg.PoolClient,
  32.   appliedMigrations: VerAndLabel[],
  33.   migrationsDir: string,
  34.   targetVer: number,
  35. ) => {
  36.   await tx(client, async (db) => {
  37.     for (let i = appliedMigrations.length - 1; i >= 0; i--) {
  38.       const migration = appliedMigrations[i];
  39.       if (migration.version > targetVer) {
  40.         const fname = verAndLabelToFName(migration, "down")
  41.         const queryBuff = await fsp.readFile(path.join(migrationsDir, fname)).catch(err => {
  42.           throw err;
  43.         });
  44.         await db.query(queryBuff.toString());
  45.         await db.query("DELETE FROM applied_migrations WHERE version=$1", [migration.version]);
  46.       } else {
  47.         break; // Stop rolling back when reaching a migration with version <= targetVersion
  48.       };
  49.     }
  50.   });
  51. };
  52.  
  53.  
  54. // Before upgrading u must be sure that DB version is clean
  55. export const upgradeToVer = async (
  56.   client: pg.PoolClient | pg.PoolClient,
  57.   localMigrationsUP: VerAndLabel[],
  58.   migrationsDir: string,
  59.   currentVer: number,
  60.   targetVer: number,
  61. ) => {
  62.   let mLocalUP = localMigrationsUP
  63.   let mLocalUPLen = localMigrationsUP.length
  64.   let idxOfCurrent: number = 0
  65.   for (let i = 0; i < mLocalUPLen; i++) {
  66.     if (localMigrationsUP[i].version === currentVer) {
  67.       idxOfCurrent = i
  68.       break
  69.     }
  70.   }
  71.  
  72.   await tx(client, async (db) => {
  73.     let mVer: number
  74.     for (let i = idxOfCurrent+1; i < mLocalUPLen; i++) {
  75.       mVer = mLocalUP[i].version
  76.       if (mVer > targetVer) {
  77.         break
  78.       }
  79.       const fname = verAndLabelToFName(mLocalUP[i], "up")
  80.       const queryBuff = await fsp.readFile(path.join(migrationsDir, fname)).catch(err => {
  81.         throw err;
  82.       });
  83.       await db.query(queryBuff.toString())
  84.       await db.query("INSERT INTO applied_migrations (version, label) "+
  85.         "VALUES ($1, $2)", [mLocalUP[i].version, mLocalUP[i].label])
  86.     }
  87.   })
  88. }
  89.  
  90.  
  91. export default { applyMigration, rollbackMigration, rollbackToVer, upgradeToVer };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement