NazCodeland
NazCodeland
Explore posts from servers
KKysely
Created by NazCodeland on 8/5/2023 in #help
Transaction response time
Hey everyone, in my code I have a createUser(), createProfile(), createBusiness(), and createAddress() for this example. Currently, I have creaeUser() execute on it's own and then the other 3 free functions execute as one transaction. Which gives me the benefit of having a fast response time for when a user creates an account. (the loading screen is quick) but I don't know if that benefit outweighs the risk of having user records in the database without a profile, business, and/or address records - *if for some reason the transaction fails but the createUser() executed fine. I really like the fast signup user experience provided by just awaiting createUser() without having to wait for a whole transaction to complete. Is there any way to handle this scenario other than optimizing the functions within the transaction as much as possible?
49 replies
KKysely
Created by NazCodeland on 8/5/2023 in #help
How to handle failed transactions
Hey everyone, this is not directly related to Kysely but I was wondering what is a common solution for handling failed transactions? - is it supposed to be logged somewhere so you can review it?
4 replies
KKysely
Created by NazCodeland on 7/31/2023 in #help
Making Transactions with KyselyAdapter for auth.js
Hey everyone, I am using this KyselyAdapter package for auth.js https://github.com/nextauthjs/next-auth/pull/5464 I made slight changes since I am in a SvetleKit project and it works! This package returns and object of functions, each function creates, updates, deletes a record in the database. I am not sure how I would go about using these functions to create a transaction. Prior to using this package, I wrote my own KyselyAdapter for auth.js but in ( for it wasn't working in some situation, so I switched ) but this is how I wrote a transaction using my own KyselyAdapter
export async function createAccount(
user: NewUser,
profile: NewProfile,
address: NewAddress,
business: NewBusiness
) {
try {
const result = await DB.transaction().execute(async (trx) => {
const newUser = await createUser(user, trx);
const newProfile = await createProfile({ ...profile, userId: newUser.id }, trx);
// prettier-ignore
const newBusiness = await createBusiness({ ...business, userId: newUser.id }, trx);

// prettier-ignore
const newBusinessAddress = await createAddress({ ...address, businessId: newBusiness.id}, trx);
// prettier-ignore
const newProfileAddress = await createAddress({ profileId: newProfile.id, }, trx);
return { newUser, newProfile, newBusiness, newBusinessAddress, newProfileAddress };
});
return result;
} catch (error) {
// Handle the error here
console.error(error);
}
}
export async function createAccount(
user: NewUser,
profile: NewProfile,
address: NewAddress,
business: NewBusiness
) {
try {
const result = await DB.transaction().execute(async (trx) => {
const newUser = await createUser(user, trx);
const newProfile = await createProfile({ ...profile, userId: newUser.id }, trx);
// prettier-ignore
const newBusiness = await createBusiness({ ...business, userId: newUser.id }, trx);

// prettier-ignore
const newBusinessAddress = await createAddress({ ...address, businessId: newBusiness.id}, trx);
// prettier-ignore
const newProfileAddress = await createAddress({ profileId: newProfile.id, }, trx);
return { newUser, newProfile, newBusiness, newBusinessAddress, newProfileAddress };
});
return result;
} catch (error) {
// Handle the error here
console.error(error);
}
}
I realize the purpose of https://github.com/nextauthjs/next-auth/pull/5464 is to be used with auth.js - and it serves that objective But for me to write a transaction like the above code snippet, I would have to modify that packages code - which I don't want to do
14 replies
KKysely
Created by NazCodeland on 6/27/2023 in #help
writing a transaction that calls functions
Hey everyone, I like what I've got going here but before I did this for my whole code base I just wanted to make sure I was on the right path
export async function createUser(user: NewUser, trx: Transaction<DB>) {
return db
.insertInto('User')
.values({
...user
})
.returningAll()
.executeTakeFirstOrThrow();
}

export async function createProfile(profile: NewProfile, trx: Transaction<DB>) {
return db
.insertInto('Profile')
.values({
...profile
})
.returningAll()
.execute();
}

export async function createBusiness(business: NewBusiness, trx: Transaction<trx>) {
return await db
.insertInto('Business')
.values({
...business
})
.returningAll()
.execute();
}

export async function createUserProfileBusiness(
user: NewUser,
profile: NewProfile,
business: NewBusiness
) {
try {
const result = await db.transaction().execute(async (trx) => {
const newUser = await createUser(user, trx);
const newProfile = await createProfile({ ...profile, userId: newUser.id }, trx);
const newBusiness = await createBusiness(business, trx);
return { newUser, newProfile, newBusiness };
});
return result;
} catch (error) {
// Handle the error here
console.error(error);
}
}
export async function createUser(user: NewUser, trx: Transaction<DB>) {
return db
.insertInto('User')
.values({
...user
})
.returningAll()
.executeTakeFirstOrThrow();
}

export async function createProfile(profile: NewProfile, trx: Transaction<DB>) {
return db
.insertInto('Profile')
.values({
...profile
})
.returningAll()
.execute();
}

export async function createBusiness(business: NewBusiness, trx: Transaction<trx>) {
return await db
.insertInto('Business')
.values({
...business
})
.returningAll()
.execute();
}

export async function createUserProfileBusiness(
user: NewUser,
profile: NewProfile,
business: NewBusiness
) {
try {
const result = await db.transaction().execute(async (trx) => {
const newUser = await createUser(user, trx);
const newProfile = await createProfile({ ...profile, userId: newUser.id }, trx);
const newBusiness = await createBusiness(business, trx);
return { newUser, newProfile, newBusiness };
});
return result;
} catch (error) {
// Handle the error here
console.error(error);
}
}
22 replies
KKysely
Created by NazCodeland on 6/25/2023 in #help
Should database tables mimic form fields?
Hey everyone, this question is not Kysely specific just wanna point that out don't know where to ask but here. I have a form for business registration that looks like this
49 replies
KKysely
Created by NazCodeland on 6/24/2023 in #help
Best practice around building query functions
Hey, I've looked around the docs somewhat but still not confident if I should do this:
export async function createUser(user: NewUser) {
return await db
.insertInto('User')
.values({
email: user.email,
role: user.role
})
.returning('User.id')
.execute();
}

export async function createProfile(profile: NewProfile) {
return await db
.insertInto('Profile')
.values({
name: profile.name,
userId: // user[0].id
})
.returningAll()
.execute();
}
export async function createUser(user: NewUser) {
return await db
.insertInto('User')
.values({
email: user.email,
role: user.role
})
.returning('User.id')
.execute();
}

export async function createProfile(profile: NewProfile) {
return await db
.insertInto('Profile')
.values({
name: profile.name,
userId: // user[0].id
})
.returningAll()
.execute();
}
Say, I have a createUser function, and then I need access to that returned user object within createProfile. I could also create a findUserById() function like in the docs,
export async function findUserById(id: NewUser['id']) {
return await db.selectFrom('User')
.where('id', '=', id)
.selectAll()
.executeTakeFirst()
}
export async function findUserById(id: NewUser['id']) {
return await db.selectFrom('User')
.where('id', '=', id)
.selectAll()
.executeTakeFirst()
}
and call findUserById() within createProfile() but then I would have to pass the userObject or user.id to createProfile(), which is fine, but before I start implementing it this way, I figure I should ask if this is the ideal way or is there a better way
29 replies
KKysely
Created by NazCodeland on 6/24/2023 in #help
Declaring types under 'kysely-codegen' module
Hey everyone, because I'm using Prisma to push schemas to my database (it's because my Zod Schemas) also getting generated from my Prisma schemas -- it's why I'm still using it incase you're wondering why I'm in this situation: I have a ./types/kysely-codegen.d.ts file which contains
import { Insertable, Selectable, Updateable } from 'kysely';
import { User } from 'kysely-codegen';

declare module 'kysely-codegen' {
export type BaseUser = Selectable<User>;
export type NewUser = Insertable<User>;
export type EditedUser = Updateable<User>;
...
}
import { Insertable, Selectable, Updateable } from 'kysely';
import { User } from 'kysely-codegen';

declare module 'kysely-codegen' {
export type BaseUser = Selectable<User>;
export type NewUser = Insertable<User>;
export type EditedUser = Updateable<User>;
...
}
in another file I have
import type { DB, BaseUser } from 'kysely-codegen';
import type { DB, BaseUser } from 'kysely-codegen';
BaseUser gives me the error that
Module '"kysely-codegen"' has no exported member 'BaseUser'.ts(2305)
Module '"kysely-codegen"' has no exported member 'BaseUser'.ts(2305)
19 replies
KKysely
Created by NazCodeland on 6/23/2023 in #help
From Prisma Model to Kysely Schema
Hey everyone, I'm using this package https://github.com/valtyr/prisma-kysely, the output of this Prisma Model
model Business {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
email String
name String @db.VarChar(100)
phone String
description String?
bannerUrl String?
address Address @relation(fields: [addressId], references: [id])
addressId String @unique @db.Uuid
workingHours WorkingHours?
services Service[]
businessType BusinessType[]
appointments Appointment[]
user User @relation(fields: [userId], references: [id])
userId String @unique @db.Uuid
}
model Business {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
email String
name String @db.VarChar(100)
phone String
description String?
bannerUrl String?
address Address @relation(fields: [addressId], references: [id])
addressId String @unique @db.Uuid
workingHours WorkingHours?
services Service[]
businessType BusinessType[]
appointments Appointment[]
user User @relation(fields: [userId], references: [id])
userId String @unique @db.Uuid
}
is
export type Business = {
id: Generated<string>;
email: string;
name: string;
phone: string;
description: string | null;
bannerUrl: string | null;
addressId: string;
userId: string;
};
export type Business = {
id: Generated<string>;
email: string;
name: string;
phone: string;
description: string | null;
bannerUrl: string | null;
addressId: string;
userId: string;
};
so when I have Kysely code such as
const business = await db
.insertInto('Business')
.values({
email: `business${i}@example.com`
name: `businessName${i}`,
phone: `phone${i}`,
userId: user[0].id,
addressId: address[0].id,
businessType: businessType[0].id // gives error because it's not in the `schema.d.ts` file
})
.returning('Business.id')
.execute();
const business = await db
.insertInto('Business')
.values({
email: `business${i}@example.com`
name: `businessName${i}`,
phone: `phone${i}`,
userId: user[0].id,
addressId: address[0].id,
businessType: businessType[0].id // gives error because it's not in the `schema.d.ts` file
})
.returning('Business.id')
.execute();
8 replies
KKysely
Created by NazCodeland on 6/17/2023 in #help
Triggers vs stored procedures
Hey everyone, I don't think this is related to Kysely directly, so excuse me but this is the only SQL type of server I am in. I am wondering what is the best way to automatically update a table attribute based on when another attribute changes (in the same table or another table). For example, if I want to have the attributes updatedAt and lastLogin updated on their own from the Model below
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now()) @db.Date
updatedAt DateTime @db.Timestamp()
lastLogIn DateTime? @db.Timestamp()
...
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now()) @db.Date
updatedAt DateTime @db.Timestamp()
lastLogIn DateTime? @db.Timestamp()
...
I need these values determines automatically. I have some sources saying use Triggers and some saying just have functions that you can invoke yourself in server side logic. Based on an article, this seems to be the main con of triggers
You don't see where the trigger is invoked by examining code alone without knowing they exist. You see their effect when you see the data changes and it is sometimes puzzling to figure out why the change occurred unless you know there is a trigger or more acting on the table(s).
You don't see where the trigger is invoked by examining code alone without knowing they exist. You see their effect when you see the data changes and it is sometimes puzzling to figure out why the change occurred unless you know there is a trigger or more acting on the table(s).
and the main pro seems to be that
it's enforced by the database so you won't have data integrity problems
it's enforced by the database so you won't have data integrity problems
whereas, functions on the server have a chance of not running due to an errorr occuring right before the attributes updatedAt, lastLogin are updated
14 replies
KKysely
Created by NazCodeland on 6/16/2023 in #help
`Selectable`, `Insertable` and `Updateable` wrappers
Hey everyone, I am using this package: https://github.com/valtyr/prisma-kysely and I noticed that the output file does not include
export type Person = Selectable<PersonTable>
export type NewPerson = Insertable<PersonTable>
export type EditedPerson = Updateable<PersonTable>
export type Person = Selectable<PersonTable>
export type NewPerson = Insertable<PersonTable>
export type EditedPerson = Updateable<PersonTable>
for the tables that I have in my schema, I don't know if that's not required because of my setup or if that is still required, I opened an issue in the repo but figured I ask here too
39 replies
KKysely
Created by NazCodeland on 6/11/2023 in #help
intellisense providing Table name in `select()` along with columns
9 replies
KKysely
Created by NazCodeland on 6/10/2023 in #help
Unable to connect to DB
Thank God there is a Discord server xD I been trying to make this work for like 2 hours and I can't get it to work
import { Pool } from 'pg';
import {
Kysely,
PostgresDialect,
Generated,
ColumnType,
Selectable,
Insertable,
Updateable
} from 'kysely';

interface UserTable {
id: Generated<number>;
email: string;
firstName: string | null;
lastName: string | null;
}

interface Database {
User: UserTable;
}

const db = new Kysely<Database>({
dialect: new PostgresDialect({
pool: new Pool({
user: 'postgres',
password: 'secretPassword',
host: 'localhost',
port: 5432,
database: 'Barbercate'
})
})
});

console.log(db);

export async function getUser() {
console.log('inside kysely.ts');
const person = await db.selectFrom('User').select('firstName').executeTakeFirst();
console.log('person:', person);
return person;
}

export async function getAllTables(): Promise<string[]> {
const tables = await db.select('*').from('pg_catalog.pg_tables').execute();
return tables;
}
import { Pool } from 'pg';
import {
Kysely,
PostgresDialect,
Generated,
ColumnType,
Selectable,
Insertable,
Updateable
} from 'kysely';

interface UserTable {
id: Generated<number>;
email: string;
firstName: string | null;
lastName: string | null;
}

interface Database {
User: UserTable;
}

const db = new Kysely<Database>({
dialect: new PostgresDialect({
pool: new Pool({
user: 'postgres',
password: 'secretPassword',
host: 'localhost',
port: 5432,
database: 'Barbercate'
})
})
});

console.log(db);

export async function getUser() {
console.log('inside kysely.ts');
const person = await db.selectFrom('User').select('firstName').executeTakeFirst();
console.log('person:', person);
return person;
}

export async function getAllTables(): Promise<string[]> {
const tables = await db.select('*').from('pg_catalog.pg_tables').execute();
return tables;
}
40 replies