feat: session queries
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { getDb, resetDb } from '../../db';
|
||||
import { insertSession, getSessionByDate, getSessionsInRange, getRecentSessions } from '../../db/sessions';
|
||||
|
||||
beforeEach(() => {
|
||||
resetDb();
|
||||
});
|
||||
|
||||
describe('sessions', () => {
|
||||
it('inserts a session and retrieves it by date', () => {
|
||||
const db = getDb();
|
||||
insertSession(db, '2026-05-20', 60, null);
|
||||
const s = getSessionByDate(db, '2026-05-20');
|
||||
expect(s).not.toBeNull();
|
||||
expect(s!.duration_min).toBe(60);
|
||||
expect(s!.notes).toBeNull();
|
||||
});
|
||||
|
||||
it('inserts a session with notes', () => {
|
||||
const db = getDb();
|
||||
insertSession(db, '2026-05-20', 45, 'felt good');
|
||||
const s = getSessionByDate(db, '2026-05-20');
|
||||
expect(s!.notes).toBe('felt good');
|
||||
});
|
||||
|
||||
it('returns null for a date with no session', () => {
|
||||
const db = getDb();
|
||||
expect(getSessionByDate(db, '2026-05-20')).toBeNull();
|
||||
});
|
||||
|
||||
it('returns sessions in date range ordered by date asc', () => {
|
||||
const db = getDb();
|
||||
insertSession(db, '2026-05-22', 60, null);
|
||||
insertSession(db, '2026-05-20', 45, null);
|
||||
const rows = getSessionsInRange(db, '2026-05-20', '2026-05-22');
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0]!.date).toBe('2026-05-20');
|
||||
});
|
||||
|
||||
it('returns the N most recent sessions ordered by date desc', () => {
|
||||
const db = getDb();
|
||||
insertSession(db, '2026-05-18', 30, null);
|
||||
insertSession(db, '2026-05-19', 45, null);
|
||||
insertSession(db, '2026-05-20', 60, null);
|
||||
const rows = getRecentSessions(db, 2);
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0]!.date).toBe('2026-05-20');
|
||||
expect(rows[1]!.date).toBe('2026-05-19');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Database } from 'better-sqlite3';
|
||||
|
||||
export interface Session {
|
||||
id: number;
|
||||
date: string;
|
||||
duration_min: number;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export function insertSession(db: Database, date: string, duration_min: number, notes: string | null): Session {
|
||||
const result = db.prepare(
|
||||
'INSERT INTO sessions (date, duration_min, notes) VALUES (?, ?, ?)'
|
||||
).run(date, duration_min, notes);
|
||||
return getSessionById(db, result.lastInsertRowid as number)!;
|
||||
}
|
||||
|
||||
function getSessionById(db: Database, id: number): Session | null {
|
||||
return (db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session | undefined) ?? null;
|
||||
}
|
||||
|
||||
export function getSessionByDate(db: Database, date: string): Session | null {
|
||||
return (db.prepare('SELECT * FROM sessions WHERE date = ?').get(date) as Session | undefined) ?? null;
|
||||
}
|
||||
|
||||
export function getSessionsInRange(db: Database, from: string, to: string): Session[] {
|
||||
return db.prepare(
|
||||
'SELECT * FROM sessions WHERE date >= ? AND date <= ? ORDER BY date ASC'
|
||||
).all(from, to) as Session[];
|
||||
}
|
||||
|
||||
export function getRecentSessions(db: Database, limit: number): Session[] {
|
||||
return db.prepare(
|
||||
'SELECT * FROM sessions ORDER BY date DESC LIMIT ?'
|
||||
).all(limit) as Session[];
|
||||
}
|
||||
Reference in New Issue
Block a user