diff --git a/migrate/spaces.js b/migrate/spaces.js new file mode 100644 index 0000000..e2830e3 --- /dev/null +++ b/migrate/spaces.js @@ -0,0 +1,12 @@ +import { pool } from '../lib/db/pool.js'; +import * as spaces from '../lib/db/repos/spaces.js'; + +const SYS = { kind: 'system', id: null }; + +// Returns the id of the space with `slug`, creating it if absent. Idempotent. +export async function ensureSpace(slug, name) { + const { rows: [r] } = await pool.query(`SELECT id FROM spaces WHERE slug=$1`, [slug]); + if (r) return r.id; + const created = await spaces.create({ slug, name }, SYS); + return created.id; +} diff --git a/tests/migrate/spaces.test.js b/tests/migrate/spaces.test.js new file mode 100644 index 0000000..5609e64 --- /dev/null +++ b/tests/migrate/spaces.test.js @@ -0,0 +1,14 @@ +import { describe, it, expect, beforeAll } from 'vitest'; +import { resetDb } from '../helpers/db.js'; +import { migrateUp } from '../../lib/db/migrate.js'; +import { ensureSpace } from '../../migrate/spaces.js'; + +beforeAll(async () => { await resetDb(); await migrateUp(); }); + +describe('ensureSpace', () => { + it('creates a space once and reuses it by slug', async () => { + const a = await ensureSpace('void1', 'Void 1'); + const b = await ensureSpace('void1', 'Void 1'); + expect(a).toBe(b); + }); +});