import type { Kysely } from 'kysely'; import type { Database } from '@/db/types.js'; import type { NewPerson, NewPet, Person, PersonUpdate, Pet, PetUpdate } from './demo.db-schema.js'; export class DemoRepository { constructor(private db: Kysely) {} // ========================================== // Person Methods // ========================================== async findPersonById(id: number) { return await this.db .selectFrom('person') .where('id', '=', id) .selectAll() .executeTakeFirst(); } async findPeople(criteria: Partial) { let query = this.db.selectFrom('person'); if (criteria.id) { query = query.where('id', '=', criteria.id); } if (criteria.first_name) { query = query.where('first_name', '=', criteria.first_name); } if (criteria.last_name !== undefined) { query = query.where( 'last_name', criteria.last_name === null ? 'is' : '=', criteria.last_name ); } if (criteria.gender) { query = query.where('gender', '=', criteria.gender); } if (criteria.created_at) { query = query.where('created_at', '=', criteria.created_at); } return await query.selectAll().execute(); } async createPerson(person: NewPerson) { return await this.db .insertInto('person') .values(person) .returningAll() .executeTakeFirstOrThrow(); } async updatePerson(id: number, updateWith: PersonUpdate) { await this.db.updateTable('person').set(updateWith).where('id', '=', id).execute(); } async deletePerson(id: number) { return await this.db .deleteFrom('person') .where('id', '=', id) .returningAll() .executeTakeFirst(); } async findPersonWithPets(id: number) { const person = await this.findPersonById(id); if (!person) return null; const pets = await this.db .selectFrom('pet') .where('owner_id', '=', id) .selectAll() .execute(); return { ...person, pets }; } // ========================================== // Pet Methods // ========================================== async findPetById(id: number) { return await this.db.selectFrom('pet').where('id', '=', id).selectAll().executeTakeFirst(); } async findPets(criteria: Partial) { let query = this.db.selectFrom('pet'); if (criteria.id) { query = query.where('id', '=', criteria.id); } if (criteria.name) { query = query.where('name', '=', criteria.name); } if (criteria.owner_id) { query = query.where('owner_id', '=', criteria.owner_id); } if (criteria.species) { query = query.where('species', '=', criteria.species); } return await query.selectAll().execute(); } async createPet(pet: NewPet) { return await this.db.insertInto('pet').values(pet).returningAll().executeTakeFirstOrThrow(); } async updatePet(id: number, updateWith: PetUpdate) { await this.db.updateTable('pet').set(updateWith).where('id', '=', id).execute(); } async deletePet(id: number) { return await this.db .deleteFrom('pet') .where('id', '=', id) .returningAll() .executeTakeFirst(); } async findPetWithOwner(id: number) { return await this.db .selectFrom('pet') .innerJoin('person', 'person.id', 'pet.owner_id') .where('pet.id', '=', id) .select([ 'pet.id as pet_id', 'pet.name as pet_name', 'pet.species', 'person.id as owner_id', 'person.first_name as owner_first_name', 'person.last_name as owner_last_name', 'person.gender as owner_gender', 'person.created_at as owner_created_at', 'person.metadata as owner_metadata', ]) .executeTakeFirst() .then((result) => { if (!result) return null; return { pet: { id: result.pet_id, name: result.pet_name, species: result.species, owner_id: result.owner_id, }, owner: { id: result.owner_id, first_name: result.owner_first_name, last_name: result.owner_last_name, gender: result.owner_gender, created_at: result.owner_created_at, metadata: result.owner_metadata, }, }; }); } }