Fix Postgres Better Auth migration index SQL
This commit is contained in:
72
lib/auth.ts
72
lib/auth.ts
@@ -21,6 +21,67 @@ function parseCsvList(value: string | undefined) {
|
|||||||
.filter((entry) => entry.length > 0);
|
.filter((entry) => entry.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPostgresConnectionString(value: string | undefined) {
|
||||||
|
if (!value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const protocol = new URL(value).protocol.toLowerCase();
|
||||||
|
return protocol === 'postgres:' || protocol === 'postgresql:';
|
||||||
|
} catch {
|
||||||
|
return /^postgres(?:ql)?:\/\//i.test(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitSqlStatements(sqlText: string) {
|
||||||
|
return sqlText
|
||||||
|
.split(';')
|
||||||
|
.map((statement) => statement.trim())
|
||||||
|
.filter((statement) => statement.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPostgresMigrationPlan(sqlText: string) {
|
||||||
|
const immediateStatements: string[] = [];
|
||||||
|
const deferredIndexStatements: string[] = [];
|
||||||
|
const addIndexPattern = /^alter table\s+([^\s]+)\s+add\s+index\s+([^\s]+)\s+\((.+)\)$/i;
|
||||||
|
|
||||||
|
for (const rawStatement of splitSqlStatements(sqlText)) {
|
||||||
|
const statement = rawStatement.replace(/\s+/g, ' ').trim();
|
||||||
|
const match = statement.match(addIndexPattern);
|
||||||
|
if (!match) {
|
||||||
|
immediateStatements.push(statement);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, tableName, indexName, columns] = match;
|
||||||
|
deferredIndexStatements.push(`create index if not exists ${indexName} on ${tableName} (${columns})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...immediateStatements, ...deferredIndexStatements];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runPostgresMigrations(pool: Pool, sqlText: string) {
|
||||||
|
const statements = buildPostgresMigrationPlan(sqlText);
|
||||||
|
if (statements.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await pool.connect();
|
||||||
|
try {
|
||||||
|
await client.query('BEGIN');
|
||||||
|
for (const statement of statements) {
|
||||||
|
await client.query(statement);
|
||||||
|
}
|
||||||
|
await client.query('COMMIT');
|
||||||
|
} catch (error) {
|
||||||
|
await client.query('ROLLBACK');
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
client.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getPool() {
|
function getPool() {
|
||||||
const connectionString = process.env.DATABASE_URL?.trim();
|
const connectionString = process.env.DATABASE_URL?.trim();
|
||||||
if (!connectionString) {
|
if (!connectionString) {
|
||||||
@@ -73,11 +134,18 @@ export function getAuth() {
|
|||||||
|
|
||||||
export async function ensureAuthSchema() {
|
export async function ensureAuthSchema() {
|
||||||
const auth = getAuth();
|
const auth = getAuth();
|
||||||
|
const connectionString = process.env.DATABASE_URL?.trim();
|
||||||
|
|
||||||
if (!migrationPromise) {
|
if (!migrationPromise) {
|
||||||
migrationPromise = (async () => {
|
migrationPromise = (async () => {
|
||||||
const { runMigrations } = await getMigrations(auth.options);
|
const migrations = await getMigrations(auth.options);
|
||||||
await runMigrations();
|
if (isPostgresConnectionString(connectionString)) {
|
||||||
|
const sql = await migrations.compileMigrations();
|
||||||
|
await runPostgresMigrations(getPool(), sql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await migrations.runMigrations();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user