realworld-hono-drizzle
Version:
A RealWorld backend built with Hono and Drizzle
150 lines (136 loc) • 3.75 kB
text/typescript
import { relations, sql } from "drizzle-orm";
import {
customType,
int,
primaryKey,
sqliteTable,
text,
} from "drizzle-orm/sqlite-core";
const date = customType<{
data: string;
driverData: string;
}>({
dataType() {
return "text";
},
fromDriver(value: string): string {
const [date, time] = value.split(" ");
return `${date}T${time}.000Z`;
},
});
export const usersTable = sqliteTable("users", {
id: int().primaryKey({ autoIncrement: true }),
email: text().notNull().unique(),
username: text().notNull().unique(),
bio: text(),
image: text(),
passwordHash: text().notNull(),
});
export const userFollowTable = sqliteTable(
"user_follow",
{
followerId: int()
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
followedId: int()
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
},
(t) => [primaryKey({ columns: [t.followerId, t.followedId] })],
);
export const userFollowRelations = relations(userFollowTable, ({ one }) => ({
follower: one(usersTable, {
fields: [userFollowTable.followerId],
references: [usersTable.id],
}),
followed: one(usersTable, {
fields: [userFollowTable.followedId],
references: [usersTable.id],
}),
}));
export const tagsTable = sqliteTable("tags", {
tag: text().notNull().unique(),
});
export const articlesTable = sqliteTable("articles", {
slug: text().primaryKey(),
title: text().notNull(),
description: text().notNull(),
body: text().notNull(),
createdAt: date().notNull().default(sql`(CURRENT_TIMESTAMP)`),
updatedAt: date().notNull().default(sql`(CURRENT_TIMESTAMP)`),
authorId: int()
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
});
export const commentsTable = sqliteTable("comments", {
id: int().primaryKey({ autoIncrement: true }),
createdAt: date().notNull().default(sql`(CURRENT_TIMESTAMP)`),
updatedAt: date().notNull().default(sql`(CURRENT_TIMESTAMP)`),
body: text().notNull(),
articleSlug: text()
.notNull()
.references(() => articlesTable.slug, {
onDelete: "cascade",
onUpdate: "cascade",
}),
authorId: int()
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
});
export const articleTagTable = sqliteTable(
"article_tag",
{
articleSlug: text()
.notNull()
.references(() => articlesTable.slug, {
onDelete: "cascade",
onUpdate: "cascade",
}),
tag: text()
.notNull()
.references(() => tagsTable.tag, { onDelete: "cascade" }),
},
(t) => [primaryKey({ columns: [t.articleSlug, t.tag] })],
);
export const articleFavoriteTable = sqliteTable(
"article_favorite",
{
articleSlug: text()
.notNull()
.references(() => articlesTable.slug, {
onDelete: "cascade",
onUpdate: "cascade",
}),
userId: int()
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
},
(t) => [primaryKey({ columns: [t.articleSlug, t.userId] })],
);
export const articleRelations = relations(articlesTable, ({ one, many }) => ({
author: one(usersTable, {
fields: [articlesTable.authorId],
references: [usersTable.id],
}),
tagList: many(articleTagTable),
commentRelations: many(commentsTable),
}));
export const tagRelations = relations(tagsTable, ({ many }) => ({
articles: many(articleTagTable),
}));
export const articleTagRelations = relations(articleTagTable, ({ one }) => ({
article: one(articlesTable, {
fields: [articleTagTable.articleSlug],
references: [articlesTable.slug],
}),
tag: one(tagsTable, {
fields: [articleTagTable.tag],
references: [tagsTable.tag],
}),
}));
export const commentRelations = relations(commentsTable, ({ one }) => ({
article: one(articlesTable, {
fields: [commentsTable.articleSlug],
references: [articlesTable.slug],
}),
}));