Add migration for movies table: create a new movies table with necessary fields, migrate existing data from the old movies table, and update database schema to reflect changes.

This commit is contained in:
Norbert Maciaszek 2025-08-11 23:52:04 +02:00
parent 96dd2b177c
commit 556bb38589
6 changed files with 201 additions and 12 deletions

View File

@ -0,0 +1,25 @@
PRAGMA foreign_keys=OFF;--> statement-breakpoint
CREATE TABLE `__new_movies` (
`id` integer PRIMARY KEY NOT NULL,
`title` text NOT NULL,
`adult` integer NOT NULL,
`backdrop_path` text NOT NULL,
`genre_ids` text NOT NULL,
`original_language` text NOT NULL,
`original_title` text NOT NULL,
`overview` text NOT NULL,
`popularity` real NOT NULL,
`poster_path` text NOT NULL,
`release_date` text NOT NULL,
`video` integer NOT NULL,
`vote_average` real NOT NULL,
`vote_count` integer NOT NULL,
`seen` integer DEFAULT false,
`favorite` integer DEFAULT false
);
--> statement-breakpoint
INSERT INTO `__new_movies`("id", "title", "overview", "popularity", "poster_path", "release_date", "seen", "favorite")
SELECT "id", "title", "overview", "popularity", "poster_path", "release_date", "seen", "favorite" FROM `movies`;--> statement-breakpoint
DROP TABLE `movies`;--> statement-breakpoint
ALTER TABLE `__new_movies` RENAME TO `movies`;--> statement-breakpoint
PRAGMA foreign_keys=ON;

View File

@ -0,0 +1,142 @@
{
"version": "6",
"dialect": "sqlite",
"id": "c3b4d292-f58b-4df8-844c-6e534034c832",
"prevId": "19a2bad6-49be-485d-ac5e-291bd3d664ad",
"tables": {
"movies": {
"name": "movies",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"adult": {
"name": "adult",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"backdrop_path": {
"name": "backdrop_path",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"genre_ids": {
"name": "genre_ids",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"original_language": {
"name": "original_language",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"original_title": {
"name": "original_title",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"overview": {
"name": "overview",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"popularity": {
"name": "popularity",
"type": "real",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"poster_path": {
"name": "poster_path",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"release_date": {
"name": "release_date",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"video": {
"name": "video",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"vote_average": {
"name": "vote_average",
"type": "real",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"vote_count": {
"name": "vote_count",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"seen": {
"name": "seen",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
},
"favorite": {
"name": "favorite",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

View File

@ -8,6 +8,13 @@
"when": 1754676538678, "when": 1754676538678,
"tag": "0000_breezy_lester", "tag": "0000_breezy_lester",
"breakpoints": true "breakpoints": true
},
{
"idx": 1,
"version": "6",
"when": 1754948246595,
"tag": "0001_elite_odin",
"breakpoints": true
} }
] ]
} }

View File

@ -2,6 +2,7 @@
import { drizzle } from "drizzle-orm/libsql"; import { drizzle } from "drizzle-orm/libsql";
import { movies } from "./schema"; import { movies } from "./schema";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { Movie } from "@/types/global";
const db = drizzle(process.env.DB_FILE_NAME!); const db = drizzle(process.env.DB_FILE_NAME!);
@ -9,17 +10,20 @@ export const getMovies = async () => {
return await db.select().from(movies).$withCache(); return await db.select().from(movies).$withCache();
}; };
export const addMovie = async (movie: typeof movies.$inferInsert) => { export const addMovie = async (movie: Movie) => {
await db.insert(movies).values(movie).onConflictDoNothing(); await db
.insert(movies)
.values({
...movie,
genre_ids: JSON.stringify(movie.genre_ids),
})
.onConflictDoNothing();
}; };
export const deleteMovie = async (id: number) => { export const deleteMovie = async (id: number) => {
await db.delete(movies).where(eq(movies.id, id)); await db.delete(movies).where(eq(movies.id, id));
}; };
export const updateMovie = async ( export const updateMovie = async (movieId: number, movie: Partial<Movie>) => {
id: number, await db.update(movies).set(movie).where(eq(movies.id, movieId));
movie: Partial<typeof movies.$inferInsert>
) => {
await db.update(movies).set(movie).where(eq(movies.id, id));
}; };

View File

@ -3,11 +3,18 @@ import { integer, real, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const movies = sqliteTable("movies", { export const movies = sqliteTable("movies", {
id: integer("id").primaryKey(), id: integer("id").primaryKey(),
title: text("title").notNull(), title: text("title").notNull(),
adult: integer("adult", { mode: "boolean" }).notNull(),
backdrop_path: text("backdrop_path").notNull(),
genre_ids: text("genre_ids").notNull(),
original_language: text("original_language").notNull(),
original_title: text("original_title").notNull(),
overview: text("overview").notNull(), overview: text("overview").notNull(),
popularity: real("popularity").notNull(), popularity: real("popularity").notNull(),
releaseDate: text("release_date").notNull(), poster_path: text("poster_path").notNull(),
posterPath: text("poster_path").notNull(), release_date: text("release_date").notNull(),
seen: integer("seen").default(0).notNull(), video: integer("video", { mode: "boolean" }).notNull(),
favorite: integer("favorite").default(0).notNull(), vote_average: real("vote_average").notNull(),
notes: text("notes").default("").notNull(), vote_count: integer("vote_count").notNull(),
seen: integer("seen", { mode: "boolean" }).default(false),
favorite: integer("favorite", { mode: "boolean" }).default(false),
}); });

4
src/types/global.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
import { movies } from "@/lib/db/schema";
import { SearchResult } from "@/lib/tmdb/types";
type Movie = typeof movies.$inferSelect;