From 2c9a33e919f7b4bdcf7049ca626d513f2dc8a7af Mon Sep 17 00:00:00 2001 From: Varun Raj Date: Sun, 18 Aug 2024 20:20:17 +0530 Subject: [PATCH] feat: drizzle setup and docker setup Signed-off-by: Varun Raj --- .env.sample | 3 ++- Dockerfile | 23 ++++++++++++++++ bun.lockb | Bin 193213 -> 223474 bytes package.json | 4 +++ src/config/db.ts | 15 +++++++++++ src/config/environment.ts | 3 ++- src/pages/api/hello.ts | 13 --------- src/pages/api/stats/assets.ts | 21 +++++++++++++++ src/schema/asset.schema.ts | 49 ++++++++++++++++++++++++++++++++++ src/schema/index.ts | 1 + tsconfig.json | 1 + 11 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 Dockerfile create mode 100644 src/config/db.ts delete mode 100644 src/pages/api/hello.ts create mode 100644 src/pages/api/stats/assets.ts create mode 100644 src/schema/asset.schema.ts create mode 100644 src/schema/index.ts diff --git a/.env.sample b/.env.sample index cc9f943..9789cbd 100644 --- a/.env.sample +++ b/.env.sample @@ -1,2 +1,3 @@ NEXT_PUBLIC_IMMICH_URL="" -IMMICH_API_KEY="" \ No newline at end of file +IMMICH_API_KEY="" +DATABASE_URL="" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7b078fa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use an official Node.js runtime as the base image +FROM node:18-alpine + +# Set the working directory in the container +WORKDIR /app + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install dependencies +RUN npm ci + +# Copy the rest of the application code +COPY . . + +# Build the Next.js application +RUN npm run build + +# Expose the port that Next.js uses +EXPOSE 3000 + +# Set the command to run the application +CMD ["npm", "start"] \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 07fe3ec054fa95a2bc7ae988b588f6b17da47d16..51cd29cb423ad9cd40308e1c36e9a19c3b612acf 100755 GIT binary patch delta 57256 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 z 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 delta 38239 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 DfE3TC diff --git a/package.json b/package.json index 5575252..a931d3d 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,10 @@ "clsx": "^2.1.1", "cmdk": "1.0.0", "date-fns": "^3.6.0", + "drizzle-orm": "^0.33.0", "lucide-react": "^0.428.0", "next": "14.2.5", + "pg": "^8.12.0", "qs": "^6.13.0", "react": "^18", "react-day-picker": "9.0.8", @@ -43,9 +45,11 @@ }, "devDependencies": { "@types/node": "^20", + "@types/pg": "^8.11.6", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10.4.20", + "drizzle-kit": "^0.24.0", "eslint": "^8", "eslint-config-next": "14.2.5", "postcss": "^8.4.41", diff --git a/src/config/db.ts b/src/config/db.ts new file mode 100644 index 0000000..717c9d7 --- /dev/null +++ b/src/config/db.ts @@ -0,0 +1,15 @@ +import { drizzle } from 'drizzle-orm/node-postgres'; + +import { Client } from "pg"; +import { ENV } from "./environment"; +import * as schema from "@/schema"; + +console.log(ENV.DATABASE_URL); +const client = new Client({ + connectionString: ENV.DATABASE_URL, +}); + +await client.connect(); +export const db = drizzle(client, { + schema +}); \ No newline at end of file diff --git a/src/config/environment.ts b/src/config/environment.ts index aa34b85..ff98582 100644 --- a/src/config/environment.ts +++ b/src/config/environment.ts @@ -1,4 +1,5 @@ export const ENV = { IMMICH_URL: process.env.NEXT_PUBLIC_IMMICH_URL as string, - IMMICH_API_KEY: process.env.IMMICH_API_KEY as string + IMMICH_API_KEY: process.env.IMMICH_API_KEY as string, + DATABASE_URL: process.env.DATABASE_URL as string, } \ No newline at end of file diff --git a/src/pages/api/hello.ts b/src/pages/api/hello.ts deleted file mode 100644 index ea77e8f..0000000 --- a/src/pages/api/hello.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from "next"; - -type Data = { - name: string; -}; - -export default function handler( - req: NextApiRequest, - res: NextApiResponse, -) { - res.status(200).json({ name: "John Doe" }); -} diff --git a/src/pages/api/stats/assets.ts b/src/pages/api/stats/assets.ts new file mode 100644 index 0000000..7129d66 --- /dev/null +++ b/src/pages/api/stats/assets.ts @@ -0,0 +1,21 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction +import { db } from "@/config/db"; +import { assets } from "@/schema"; +import { count } from "drizzle-orm"; +import type { NextApiRequest, NextApiResponse } from "next"; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + try { + const assetsFromDB = await db.select({ + count: count() + }).from(assets).groupBy(assets.createdAt); + res.status(200).json(assetsFromDB); + } catch (error) { + res.status(500).json({ + name: "Error", + }); + } +} diff --git a/src/schema/asset.schema.ts b/src/schema/asset.schema.ts new file mode 100644 index 0000000..b5e8a9e --- /dev/null +++ b/src/schema/asset.schema.ts @@ -0,0 +1,49 @@ +import { pgTable, uuid, varchar, timestamp, boolean } from 'drizzle-orm/pg-core'; + +export const assets = pgTable('assets', { + id: uuid('id').defaultRandom().primaryKey().notNull(), + deviceAssetId: varchar('deviceAssetId').notNull(), + // ownerId: uuid('ownerId').notNull().references(() => users.id, { onDelete: 'cascade', onUpdate: 'cascade' }), + deviceId: varchar('deviceId').notNull(), + type: varchar('type').notNull(), + originalPath: varchar('originalPath').notNull(), + previewPath: varchar('previewPath'), + fileCreatedAt: timestamp('fileCreatedAt', { withTimezone: true }).notNull(), + fileModifiedAt: timestamp('fileModifiedAt', { withTimezone: true }).notNull(), + isFavorite: boolean('isFavorite').default(false).notNull(), + duration: varchar('duration'), + thumbnailPath: varchar('thumbnailPath').default(''), + encodedVideoPath: varchar('encodedVideoPath').default(''), + // checksum: bytea('checksum').notNull(), + isVisible: boolean('isVisible').default(true).notNull(), + livePhotoVideoId: uuid('livePhotoVideoId').references((): any => assets.id, { onDelete: 'set null', onUpdate: 'cascade' }), + updatedAt: timestamp('updatedAt', { withTimezone: true }).defaultNow().notNull(), + createdAt: timestamp('createdAt', { withTimezone: true }).defaultNow().notNull(), + isArchived: boolean('isArchived').default(false).notNull(), + originalFileName: varchar('originalFileName').notNull(), + sidecarPath: varchar('sidecarPath'), + // thumbhash: bytea('thumbhash'), + isOffline: boolean('isOffline').default(false).notNull(), + // libraryId: uuid('libraryId').references(() => libraries.id, { onDelete: 'cascade', onUpdate: 'cascade' }), + isExternal: boolean('isExternal').default(false).notNull(), + deletedAt: timestamp('deletedAt', { withTimezone: true }), + localDateTime: timestamp('localDateTime', { withTimezone: true }).notNull(), + // stackId: uuid('stackId').references(() => assetStack.id, { onDelete: 'set null', onUpdate: 'cascade' }), + duplicateId: uuid('duplicateId'), +}); + +// // Note: You'll need to define these referenced tables as well +// export const users = pgTable('users', { +// id: uuid('id').primaryKey(), +// // ... other columns +// }); + +// export const libraries = pgTable('libraries', { +// id: uuid('id').primaryKey(), +// // ... other columns +// }); + +// export const assetStack = pgTable('asset_stack', { +// id: uuid('id').primaryKey(), +// // ... other columns +// }); \ No newline at end of file diff --git a/src/schema/index.ts b/src/schema/index.ts new file mode 100644 index 0000000..2f7ae62 --- /dev/null +++ b/src/schema/index.ts @@ -0,0 +1 @@ +export { assets } from './asset.schema'; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index fb68dc1..78a0434 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,7 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, + "target": "ESNext", "paths": { "@/*": ["./src/*"] }