Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
uasan committed Sep 4, 2023
1 parent a8bba16 commit c49713c
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 67 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"typescript": "next",
"@types/node": "latest",
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.31.0",
"@uah/postgres": "uasan/postgres"
"@uah/postgres": "file:../../Postgres"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "latest",
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/entities/migrations/maker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function makeMigrations() {
let classes = [];
let source = `import { migrate } from '${URL_LIB_RUNTIME}migration/app.js';\n\n`;

source += `import { Migration as _0 } from '../${DIR_LIB}/Migration.js';\n`;
source += `import { Migration } from '../${DIR_LIB}/Migration.js';\n`;

for (const { className, url } of migrations)
if (className) {
Expand All @@ -22,7 +22,7 @@ export function makeMigrations() {
source += `import { ${className} as ${alias} } from '../${url}';\n`;
}

source += `\nawait migrate(_0, [${classes.join(', ')}]);\n`;
source += `\nawait migrate(Migration, [${classes.join(', ')}]);\n`;

host.hooks.saveFile(DIR_BIN + '/migrate.js', source);
}
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/postgres/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface PostgresOptions {
database?: string;
username?: string;
password?: string;
maxConnections?: number;
}

export declare function Postgres(
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/migration/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { connect, disconnect } from './database.js';

export async function migrate(context, migrations) {
console.log('MIGRATIONS', migrations);
console.log(await context.prototype.sql`SELECT 1`);
const ctx = await connect(context);

await disconnect(ctx);
}
98 changes: 37 additions & 61 deletions src/runtime/migration/database.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,55 @@
import { LOCK_ID } from '../constants.js';
import { presets } from '#env';
import { green, yellow, red } from '#utils/console.js';
import { setDataBaseContext } from '#db/context.js';
import { getConnectOptions, createClient } from '#db/client.js';
import { green, yellow, red } from '../console/colors.js';

export const defaultOptions = {
max: 1,
prepare: false,
username: 'postgres',
password: 'pass',
};
export const LOCK_ID = 0;
export const DEFAULT_DATABASE = 'postgres';
export const ERROR_DATABASE_NOT_EXIST = '3D000';

const createDatabase = async context => {
const { connection } = context.config;
await context.db.end({ timeout: 0 });
export async function createDatabase(ctx) {
const { options } = ctx.postgres;

const client = createClient({ ...connection, database: 'postgres' });
await client.unsafe(`CREATE DATABASE "${connection.database}"`);
await client.end({ timeout: 0 });
await ctx.postgres.setOptions({ ...options, database: DEFAULT_DATABASE });
await ctx.postgres.query(`CREATE DATABASE "${options.database}"`);
await ctx.postgres.setOptions(options);
}

context.db = createClient(connection);
};
export async function dropDatabase(ctx) {
const { options } = ctx.postgres;

export const dropDatabase = async context => {
const { connection } = context.config;
await context.db.end({ timeout: 0 });
await ctx.postgres.setOptions({ ...options, database: DEFAULT_DATABASE });
await ctx.postgres.query(`DROP DATABASE IF EXISTS "${options.database}"`);
}

const client = createClient({ ...connection, database: 'postgres' });
await client.unsafe(`DROP DATABASE IF EXISTS "${connection.database}"`);
await client.end({ timeout: 0 });
};

export const lockMigrate = async ({ sql }) => {
const isLock = await sql`
SELECT pg_try_advisory_lock(${LOCK_ID}::bigint) AS "0"
`.findOneValue();
export async function lockMigrate(ctx) {
const isLock =
await ctx.sql`SELECT pg_try_advisory_lock(${LOCK_ID}::bigint)`.asValue();

if (isLock === false) {
console.log(yellow(`Migrate: `) + red(`waiting release lock ${LOCK_ID}`));
await sql`SELECT pg_advisory_lock(${LOCK_ID}::bigint)`;
}

if (!presets.app.isTesting)
console.log(green(`Migrate: start lock ${LOCK_ID}`));
};
await ctx.sql`SELECT pg_advisory_lock(${LOCK_ID}::bigint)`;
}

export const unlockMigrate = async ({ sql }) =>
await sql`SELECT pg_advisory_unlock_all()`;
console.log(green(`Migrate: start lock ${LOCK_ID}`));
}

export const connect = async context => {
context.config.connection = getConnectOptions(
{
...presets.db,
...defaultOptions,
...context.config.connection,
},
'MASTER'
);
export async function unlockMigrate(ctx) {
await ctx.sql`SELECT pg_advisory_unlock_all()`;
}

setDataBaseContext(context, context.config.connection);
export async function connect(context) {
const ctx = context.prototype;

try {
await lockMigrate(context);
await ctx.postgres.connect();
} catch (error) {
if (error?.code === '3D000') {
await createDatabase(context);
await lockMigrate(context);
} else {
throw error;
}
if (error.code === ERROR_DATABASE_NOT_EXIST) await createDatabase(ctx);
else throw error;
}
};

export const disconnect = async context => {
if (context.db) {
await context.db.end({ timeout: 0 });
}
};
await lockMigrate(ctx);
return ctx;
}

export async function disconnect(ctx) {
await ctx.postgres.disconnect();
}
6 changes: 5 additions & 1 deletion src/runtime/postgres/context.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Pool } from '@uah/postgres/src/pool.js';
import { Client } from '@uah/postgres/src/client.js';
import { signal } from '../process.js';

export function initPostgres({ prototype }, options) {
prototype.postgres = new Pool({ signal, ...options });
prototype.postgres =
options.maxConnections > 1
? new Pool({ signal, ...options })
: new Client({ signal, ...options });
}

0 comments on commit c49713c

Please sign in to comment.