import db from '@adonisjs/lucid/services/db' import env from '#start/env' /** Months ahead that always have a release_chunks partition. */ const AHEAD = 2 /** * release_chunks is partitioned by month of writing (REBUILD.md, decision a). * Inserts fail without a partition for now(), so the current and the next * months' partitions are created before they are needed. */ class ChunkPartitions { async ensure(now = new Date()) { // Checked each time, not remembered: a rolled-back transaction can take a created partition along. const current = `release_chunks_${now.toISOString().slice(0, 7).replace('-', '')}` const { rows } = await db.rawQuery(`SELECT to_regclass(?) IS NOT NULL AS present`, [current]) if (rows[0].present) return const tablespace = env.get('CHUNK_TABLESPACE') for (let i = 0; i <= AHEAD; i++) { const from = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + i, 1)) const to = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + i + 1, 1)) const name = `release_chunks_${from.toISOString().slice(0, 7).replace('-', '')}` await db.rawQuery( `CREATE TABLE IF NOT EXISTS ${name} PARTITION OF release_chunks FOR VALUES FROM ('${from.toISOString()}') TO ('${to.toISOString()}')${tablespace ? ` TABLESPACE ${tablespace}` : ''}` ) } } } export default new ChunkPartitions()