feat(01-02): create EntryRepository with typed CRUD operations
- Implement EntryRepository interface with create, getById, getAll, update, delete, count - SQLiteEntryRepository class using Drizzle ORM - Automatic ID generation with nanoid - Automatic timestamp management (createdAt, updatedAt) - Pagination support via limit/offset - Singleton pattern for consistent access
This commit is contained in:
68
src/lib/server/db/repository.ts
Normal file
68
src/lib/server/db/repository.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { eq, desc } from 'drizzle-orm';
|
||||
import { db } from './index';
|
||||
import { entries, type Entry, type NewEntry } from './schema';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
export interface EntryRepository {
|
||||
create(entry: Omit<NewEntry, 'id' | 'createdAt' | 'updatedAt'>): Entry;
|
||||
getById(id: string): Entry | undefined;
|
||||
getAll(options?: { limit?: number; offset?: number }): Entry[];
|
||||
update(id: string, updates: Partial<Omit<Entry, 'id' | 'createdAt'>>): Entry | undefined;
|
||||
delete(id: string): boolean;
|
||||
count(): number;
|
||||
}
|
||||
|
||||
class SQLiteEntryRepository implements EntryRepository {
|
||||
create(entry: Omit<NewEntry, 'id' | 'createdAt' | 'updatedAt'>): Entry {
|
||||
const now = new Date().toISOString();
|
||||
const newEntry: NewEntry = {
|
||||
...entry,
|
||||
id: nanoid(),
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
};
|
||||
|
||||
db.insert(entries).values(newEntry).run();
|
||||
return this.getById(newEntry.id)!;
|
||||
}
|
||||
|
||||
getById(id: string): Entry | undefined {
|
||||
return db.select().from(entries).where(eq(entries.id, id)).get();
|
||||
}
|
||||
|
||||
getAll(options: { limit?: number; offset?: number } = {}): Entry[] {
|
||||
const { limit = 100, offset = 0 } = options;
|
||||
return db.select().from(entries).orderBy(desc(entries.createdAt)).limit(limit).offset(offset).all();
|
||||
}
|
||||
|
||||
update(id: string, updates: Partial<Omit<Entry, 'id' | 'createdAt'>>): Entry | undefined {
|
||||
const existing = this.getById(id);
|
||||
if (!existing) return undefined;
|
||||
|
||||
db.update(entries)
|
||||
.set({
|
||||
...updates,
|
||||
updatedAt: new Date().toISOString()
|
||||
})
|
||||
.where(eq(entries.id, id))
|
||||
.run();
|
||||
|
||||
return this.getById(id);
|
||||
}
|
||||
|
||||
delete(id: string): boolean {
|
||||
const existing = this.getById(id);
|
||||
if (!existing) return false;
|
||||
|
||||
db.delete(entries).where(eq(entries.id, id)).run();
|
||||
return true;
|
||||
}
|
||||
|
||||
count(): number {
|
||||
const result = db.select().from(entries).all();
|
||||
return result.length;
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
export const entryRepository: EntryRepository = new SQLiteEntryRepository();
|
||||
Reference in New Issue
Block a user