feat: drizzle setup and docker setup

Signed-off-by: Varun Raj <mailme@varunraj.in>
This commit is contained in:
Varun Raj
2024-08-18 20:20:17 +05:30
parent 29581e0bb3
commit 2c9a33e919
11 changed files with 118 additions and 15 deletions
+1
View File
@@ -1,2 +1,3 @@
NEXT_PUBLIC_IMMICH_URL=""
IMMICH_API_KEY=""
DATABASE_URL=""
+23
View File
@@ -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"]
BIN
View File
Binary file not shown.
+4
View File
@@ -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",
+15
View File
@@ -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
});
+2 -1
View File
@@ -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,
}
-13
View File
@@ -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<Data>,
) {
res.status(200).json({ name: "John Doe" });
}
+21
View File
@@ -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",
});
}
}
+49
View File
@@ -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
// });
+1
View File
@@ -0,0 +1 @@
export { assets } from './asset.schema';
+1
View File
@@ -12,6 +12,7 @@
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"target": "ESNext",
"paths": {
"@/*": ["./src/*"]
}