zappier-edge/src/db/usage-repo.ts

61 lines
1.9 KiB
TypeScript

import Database from 'better-sqlite3';
import { summarize, UsageEntry, UsageRepo, UsageSummary } from '../usage';
export class SqliteUsageRepo implements UsageRepo {
constructor(private db: Database.Database) {
this.db.exec(`
CREATE TABLE IF NOT EXISTS usage_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id TEXT NOT NULL,
endpoint_id TEXT NOT NULL,
cents INTEGER NOT NULL,
metadata_bytes INTEGER NOT NULL,
attachment_bytes INTEGER NOT NULL,
timestamp_ms INTEGER NOT NULL
)
`);
}
record(entry: UsageEntry): void {
this.db
.prepare(
`INSERT INTO usage_entries
(customer_id, endpoint_id, cents, metadata_bytes, attachment_bytes, timestamp_ms)
VALUES (?, ?, ?, ?, ?, ?)`,
)
.run(
entry.customerId,
entry.endpointId,
entry.cents,
entry.metadataBytes,
entry.attachmentBytes,
entry.timestamp.getTime(),
);
}
listFor(customerId: string, since?: Date): UsageEntry[] {
const rows = (
since
? this.db
.prepare(
'SELECT * FROM usage_entries WHERE customer_id = ? AND timestamp_ms >= ? ORDER BY timestamp_ms',
)
.all(customerId, since.getTime())
: this.db
.prepare('SELECT * FROM usage_entries WHERE customer_id = ? ORDER BY timestamp_ms')
.all(customerId)
) as Record<string, unknown>[];
return rows.map((r) => ({
customerId: r.customer_id as string,
endpointId: r.endpoint_id as string,
cents: r.cents as number,
metadataBytes: r.metadata_bytes as number,
attachmentBytes: r.attachment_bytes as number,
timestamp: new Date(r.timestamp_ms as number),
}));
}
summaryFor(customerId: string, since?: Date): UsageSummary {
return summarize(customerId, this.listFor(customerId, since));
}
}