Drizzle type question

I swapped over to Drizzle, and I've got this schema right
export const User = mysqlTable('users', {
id: serial('id').primaryKey(),
username: text('username').unique(),
passwordHash: text('password_hash'),
passwordSalt: text('password_salt'),
role: mysqlEnum('role', ['user', 'admin']),
createdAt: timestamp('created_at').notNull().default(new Date()),
updatedAt: timestamp('updated_at').notNull().default(new Date()),
});
export const Session = mysqlTable('sessions', {
id: serial('id').primaryKey(),
token: text('token').unique(),
csrfToken: text('csrf_token'),
expiresAt: timestamp('expires_at').notNull(),
userid: int('user_id').references(() => User.id),
});
export const User = mysqlTable('users', {
id: serial('id').primaryKey(),
username: text('username').unique(),
passwordHash: text('password_hash'),
passwordSalt: text('password_salt'),
role: mysqlEnum('role', ['user', 'admin']),
createdAt: timestamp('created_at').notNull().default(new Date()),
updatedAt: timestamp('updated_at').notNull().default(new Date()),
});
export const Session = mysqlTable('sessions', {
id: serial('id').primaryKey(),
token: text('token').unique(),
csrfToken: text('csrf_token'),
expiresAt: timestamp('expires_at').notNull(),
userid: int('user_id').references(() => User.id),
});
And I'm trying to get a session based on an id coming from the client
const session = await db
.select()
.from(Session)
.where(eq(Session.token, sessionToken))
.innerJoin(User, eq(Session.userid, User.id)).limit(1)
.execute();
const session = await db
.select()
.from(Session)
.where(eq(Session.token, sessionToken))
.innerJoin(User, eq(Session.userid, User.id)).limit(1)
.execute();
This seems right, right? But why in the world is the type of session an array consisting of an object with a users and sessions prop?
session: {
sessions: {
id: number;
token: string | null;
csrfToken: string | null;
expiresAt: Date;
userid: number | null;
};
users: {
id: number;
username: string | null;
passwordHash: string | null;
passwordSalt: string | null;
role: "user" | ... 1 more ... | null;
createdAt: Date;
updatedAt: Date;
};
}[]
session: {
sessions: {
id: number;
token: string | null;
csrfToken: string | null;
expiresAt: Date;
userid: number | null;
};
users: {
id: number;
username: string | null;
passwordHash: string | null;
passwordSalt: string | null;
role: "user" | ... 1 more ... | null;
createdAt: Date;
updatedAt: Date;
};
}[]
Solution:
And limit 1 still returns an array btw. So you have to do data[0].sessions
Jump to solution
5 Replies
barry
barry11mo ago
To use this I'd have to do this session.at(0)?.sessions session.at(0)?.users Which seems like an odd thing
Kasper
Kasper11mo ago
It's called session because you called the cost session. Just switch to cost data and then it's data.session and data.users Or you can do a spread operator in the select() select({ ...session, users: users })
Solution
Kasper
Kasper11mo ago
And limit 1 still returns an array btw. So you have to do data[0].sessions
Kasper
Kasper11mo ago
If I want one of something, I usually write it like this:
async function getCustomer(cid: string) {
const res = await db.select().from(customers).where(eq(customers.id, cid));

if (res.length === 0) {
return null;
}

return res[0];
}

export default async function Page({
params: { cid },
}: {
params: { cid: string };
}) {
const customer = await getCustomer(cid);

if (!customer) {
return <p>Something went wrong.</p>;
}

return (
<>
<h1 className="text-2xl font-medium">{customer.name}</h1>
</>
);
}
async function getCustomer(cid: string) {
const res = await db.select().from(customers).where(eq(customers.id, cid));

if (res.length === 0) {
return null;
}

return res[0];
}

export default async function Page({
params: { cid },
}: {
params: { cid: string };
}) {
const customer = await getCustomer(cid);

if (!customer) {
return <p>Something went wrong.</p>;
}

return (
<>
<h1 className="text-2xl font-medium">{customer.name}</h1>
</>
);
}
barry
barry11mo ago
Thx