Skip to content

Commit

Permalink
use shared schema
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Dec 5, 2024
1 parent 44a360d commit 809a50e
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 103 deletions.
81 changes: 4 additions & 77 deletions src/__tests__/setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PGlite } from '@electric-sql/pglite';
import { initializeDatabase, dropTables } from '../schema';

// Set up test environment variables before any tests run
process.env.SKIP_SIGNING_VERIFICATION = 'true';
Expand Down Expand Up @@ -29,94 +30,20 @@ class DatabaseManager {
if (!this.db) {
this.db = new PGlite('memory://');
await this.db.ready;

// Wrap table creation in a transaction
await this.db.query('BEGIN');
try {
// Create sessions table
await this.db.query(`
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
address TEXT NOT NULL,
nonce TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
domain TEXT NOT NULL
)
`);

// Create nonces table
await this.db.query(`
CREATE TABLE IF NOT EXISTS nonces (
id TEXT PRIMARY KEY,
chain_id TEXT NOT NULL,
nonce TEXT NOT NULL,
consumed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE(chain_id, nonce)
)
`);

// Create compacts table
await this.db.query(`
CREATE TABLE IF NOT EXISTS compacts (
id TEXT PRIMARY KEY,
chain_id TEXT NOT NULL,
claim_hash TEXT NOT NULL,
arbiter TEXT NOT NULL,
sponsor TEXT NOT NULL,
nonce TEXT NOT NULL,
expires BIGINT NOT NULL,
compact_id TEXT NOT NULL,
amount TEXT NOT NULL,
witness_type_string TEXT,
witness_hash TEXT,
signature TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE(chain_id, claim_hash)
)
`);

// Create indexes
await this.db.query(
'CREATE INDEX IF NOT EXISTS idx_sessions_address ON sessions(address)'
);
await this.db.query(
'CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at)'
);
await this.db.query(
'CREATE INDEX IF NOT EXISTS idx_compacts_sponsor ON compacts(sponsor)'
);
await this.db.query(
'CREATE INDEX IF NOT EXISTS idx_compacts_chain_claim ON compacts(chain_id, claim_hash)'
);
await this.db.query(
'CREATE INDEX IF NOT EXISTS idx_nonces_chain_nonce ON nonces(chain_id, nonce)'
);

await this.db.query('COMMIT');
} catch (error) {
await this.db.query('ROLLBACK');
throw error;
}
await initializeDatabase(this.db);
}
return;
}

async getDb(): Promise<PGlite> {
if (!this.db) {
return this.initialize().then(() => this.db as PGlite);
await this.initialize();
}
return this.db as PGlite;
}

async cleanup(): Promise<void> {
if (this.db) {
// Drop all tables
await this.db.query('DROP TABLE IF EXISTS sessions CASCADE');
await this.db.query('DROP TABLE IF EXISTS nonces CASCADE');
await this.db.query('DROP TABLE IF EXISTS compacts CASCADE');

// Reset the database connection
await dropTables(this.db);
this.db = null;
}
}
Expand Down
28 changes: 2 additions & 26 deletions src/database.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,10 @@
import { FastifyInstance } from 'fastify';
import { PGlite } from '@electric-sql/pglite';
import { initializeDatabase } from './schema';

export async function setupDatabase(server: FastifyInstance): Promise<void> {
const db = new PGlite();

// Create sessions table
await db.query(`
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
address TEXT NOT NULL,
nonce TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
domain TEXT NOT NULL
)
`);

// Create compacts table
await db.query(`
CREATE TABLE IF NOT EXISTS compacts (
id TEXT PRIMARY KEY,
address TEXT NOT NULL,
nonce TEXT NOT NULL,
signature TEXT NOT NULL,
message TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
domain TEXT NOT NULL
)
`);
await initializeDatabase(db);

// Add the database instance to the server
server.decorate('db', db);
Expand Down
88 changes: 88 additions & 0 deletions src/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { PGlite } from '@electric-sql/pglite';

export const schemas = {
sessions: `
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
address TEXT NOT NULL,
nonce TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
domain TEXT NOT NULL
)
`,
nonces: `
CREATE TABLE IF NOT EXISTS nonces (
id TEXT PRIMARY KEY,
chain_id TEXT NOT NULL,
nonce TEXT NOT NULL,
consumed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE(chain_id, nonce)
)
`,
compacts: `
CREATE TABLE IF NOT EXISTS compacts (
id TEXT PRIMARY KEY,
chain_id TEXT NOT NULL,
claim_hash TEXT NOT NULL,
arbiter TEXT NOT NULL,
sponsor TEXT NOT NULL,
nonce TEXT NOT NULL,
expires BIGINT NOT NULL,
compact_id TEXT NOT NULL,
amount TEXT NOT NULL,
witness_type_string TEXT,
witness_hash TEXT,
signature TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
UNIQUE(chain_id, claim_hash)
)
`,
};

export const indexes = {
sessions: [
'CREATE INDEX IF NOT EXISTS idx_sessions_address ON sessions(address)',
'CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at)',
],
compacts: [
'CREATE INDEX IF NOT EXISTS idx_compacts_sponsor ON compacts(sponsor)',
'CREATE INDEX IF NOT EXISTS idx_compacts_chain_claim ON compacts(chain_id, claim_hash)',
],
nonces: [
'CREATE INDEX IF NOT EXISTS idx_nonces_chain_nonce ON nonces(chain_id, nonce)',
],
};

export async function initializeDatabase(db: PGlite): Promise<void> {
await db.query('BEGIN');
try {
// Create tables
await Promise.all(Object.values(schemas).map((schema) => db.query(schema)));

// Create indexes
await Promise.all(
Object.values(indexes)
.flat()
.map((index) => db.query(index))
);

await db.query('COMMIT');
} catch (error) {
await db.query('ROLLBACK');
throw error;
}
}

export async function dropTables(db: PGlite): Promise<void> {
await db.query('BEGIN');
try {
for (const table of Object.keys(schemas)) {
await db.query(`DROP TABLE IF EXISTS ${table} CASCADE`);
}
await db.query('COMMIT');
} catch (error) {
await db.query('ROLLBACK');
throw error;
}
}

0 comments on commit 809a50e

Please sign in to comment.