165 lines
3.9 KiB
TypeScript

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<Database>) {}
// ==========================================
// Person Methods
// ==========================================
async findPersonById(id: number) {
return await this.db
.selectFrom('person')
.where('id', '=', id)
.selectAll()
.executeTakeFirst();
}
async findPeople(criteria: Partial<Person>) {
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<Pet>) {
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,
},
};
});
}
}