diff options
| author | Dhravya Shah <[email protected]> | 2024-06-18 17:58:46 -0500 |
|---|---|---|
| committer | Dhravya Shah <[email protected]> | 2024-06-18 17:58:46 -0500 |
| commit | f4bb71e8f7e07bb2e919b7f222d5acb2905eb8f2 (patch) | |
| tree | 7310dc521ef3559055bbe71f50c3861be2fa0503 /apps/web/server/db | |
| parent | darkmode by default - so that the colors don't f up on lightmode devices (diff) | |
| parent | Create Embeddings for Canvas (diff) | |
| download | supermemory-default-darkmode.tar.xz supermemory-default-darkmode.zip | |
Diffstat (limited to 'apps/web/server/db')
| -rw-r--r-- | apps/web/server/db/index.ts | 5 | ||||
| -rw-r--r-- | apps/web/server/db/schema.ts | 156 |
2 files changed, 161 insertions, 0 deletions
diff --git a/apps/web/server/db/index.ts b/apps/web/server/db/index.ts new file mode 100644 index 00000000..4d671bea --- /dev/null +++ b/apps/web/server/db/index.ts @@ -0,0 +1,5 @@ +import { drizzle } from "drizzle-orm/d1"; + +import * as schema from "./schema"; + +export const db = drizzle(process.env.DATABASE, { schema, logger: true }); diff --git a/apps/web/server/db/schema.ts b/apps/web/server/db/schema.ts new file mode 100644 index 00000000..1ff23c82 --- /dev/null +++ b/apps/web/server/db/schema.ts @@ -0,0 +1,156 @@ +import { relations, sql } from "drizzle-orm"; +import { + index, + int, + primaryKey, + sqliteTableCreator, + text, + integer, +} from "drizzle-orm/sqlite-core"; +import type { AdapterAccountType } from "next-auth/adapters"; + +export const createTable = sqliteTableCreator((name) => `${name}`); + +export const users = createTable("user", { + id: text("id") + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + name: text("name"), + email: text("email").notNull(), + emailVerified: integer("emailVerified", { mode: "timestamp_ms" }), + image: text("image"), +}); + +export type User = typeof users.$inferSelect; + +export const accounts = createTable( + "account", + { + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + type: text("type").$type<AdapterAccountType>().notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), + }, + (account) => ({ + compoundKey: primaryKey({ + columns: [account.provider, account.providerAccountId], + }), + }), +); + +export const sessions = createTable("session", { + sessionToken: text("sessionToken").primaryKey(), + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + expires: integer("expires", { mode: "timestamp_ms" }).notNull(), +}); + +export const verificationTokens = createTable( + "verificationToken", + { + identifier: text("identifier").notNull(), + token: text("token").notNull(), + expires: integer("expires", { mode: "timestamp_ms" }).notNull(), + }, + (verificationToken) => ({ + compositePk: primaryKey({ + columns: [verificationToken.identifier, verificationToken.token], + }), + }), +); + +export const authenticators = createTable( + "authenticator", + { + credentialID: text("credentialID").notNull().unique(), + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + providerAccountId: text("providerAccountId").notNull(), + credentialPublicKey: text("credentialPublicKey").notNull(), + counter: integer("counter").notNull(), + credentialDeviceType: text("credentialDeviceType").notNull(), + credentialBackedUp: integer("credentialBackedUp", { + mode: "boolean", + }).notNull(), + transports: text("transports"), + }, + (authenticator) => ({ + compositePK: primaryKey({ + columns: [authenticator.userId, authenticator.credentialID], + }), + }), +); + +export const storedContent = createTable( + "storedContent", + { + id: integer("id").notNull().primaryKey({ autoIncrement: true }), + content: text("content").notNull(), + title: text("title", { length: 255 }), + description: text("description", { length: 255 }), + url: text("url").notNull(), + savedAt: int("savedAt", { mode: "timestamp" }).notNull(), + baseUrl: text("baseUrl", { length: 255 }), + ogImage: text("ogImage", { length: 255 }), + type: text("type").default("page"), + image: text("image", { length: 255 }), + userId: text("user").references(() => users.id, { + onDelete: "cascade", + }), + }, + (sc) => ({ + urlIdx: index("storedContent_url_idx").on(sc.url), + savedAtIdx: index("storedContent_savedAt_idx").on(sc.savedAt), + titleInx: index("storedContent_title_idx").on(sc.title), + userIdx: index("storedContent_user_idx").on(sc.userId), + }), +); + +export type Content = typeof storedContent.$inferSelect; + +export const contentToSpace = createTable( + "contentToSpace", + { + contentId: integer("contentId") + .notNull() + .references(() => storedContent.id, { onDelete: "cascade" }), + spaceId: integer("spaceId") + .notNull() + .references(() => space.id, { onDelete: "cascade" }), + }, + (cts) => ({ + compoundKey: primaryKey({ columns: [cts.contentId, cts.spaceId] }), + }), +); + +export const space = createTable( + "space", + { + id: integer("id").notNull().primaryKey({ autoIncrement: true }), + name: text("name").notNull().unique().default("none"), + user: text("user", { length: 255 }).references(() => users.id, { + onDelete: "cascade", + }), + }, + (space) => ({ + nameIdx: index("spaces_name_idx").on(space.name), + userIdx: index("spaces_user_idx").on(space.user), + }), +); + +export type StoredContent = Omit<typeof storedContent.$inferSelect, "user">; +export type StoredSpace = typeof space.$inferSelect; +export type ChachedSpaceContent = StoredContent & { + space: number; +}; |