Moving drizzle from MySQL to Postgres because more features exist there I like and am used to.

This commit is contained in:
Bradley Shellnut 2024-02-08 18:56:09 -08:00
parent 9a34d0efec
commit baafd75839
22 changed files with 1135 additions and 1134 deletions

View file

@ -4,12 +4,12 @@ import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/schema.ts',
out: './drizzle',
driver: 'mysql2',
driver: 'pg',
dbCredentials: {
host: process.env.DATABASE_HOST || 'localhost',
port: 3306,
port: process.env.DATABASE_PORT || 5432,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE || 'nut-shells'
database: process.env.DATABASE || 'boredgame'
}
});

View file

@ -0,0 +1,233 @@
CREATE TABLE IF NOT EXISTS "artists" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"external_id" integer,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "artists_to_games" (
"artist_id" varchar(255),
"game_id" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "categories" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"external_id" integer,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "categories_to_games" (
"category_id" varchar(255),
"game_id" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "collection_items" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"collection_id" varchar(255) NOT NULL,
"game_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "collections" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"user_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "designers" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"external_id" integer,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "designers_to_games" (
"designer_id" varchar(255),
"game_id" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "expansions" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"base_game_id" varchar(255) NOT NULL,
"game_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "games" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"description" text,
"year_published" integer,
"min_players" integer,
"max_players" integer,
"playtime" integer,
"min_playtime" integer,
"max_playtime" integer,
"min_age" integer,
"image_url" varchar(255),
"thumb_url" varchar(255),
"url" varchar(255),
"external_id" integer,
"last_sync_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6)),
CONSTRAINT "games_external_id_unique" UNIQUE("external_id")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "mechanics" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"external_id" integer,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "mechanics_to_games" (
"mechanic_id" varchar(255),
"game_id" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "publishers" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
"slug" varchar(255),
"external_id" integer,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "publishers_to_games" (
"publisher_id" varchar(255),
"game_id" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "roles" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"name" varchar(255),
CONSTRAINT "roles_name_unique" UNIQUE("name")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "sessions" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"user_id" varchar(255) NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"ip_country" varchar(255),
"ip_address" varchar(255)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "user_roles" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"user_id" varchar(255) NOT NULL,
"role_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "users" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"username" varchar(255),
"hashed_password" varchar(255),
"email" varchar(255),
"first_name" varchar(255),
"last_name" varchar(255),
"verified" boolean DEFAULT false,
"receive_email" boolean DEFAULT false,
"theme" varchar(255) DEFAULT 'system',
"created_at" timestamp DEFAULT (now(6)),
"updated_at" timestamp DEFAULT (now(6)),
CONSTRAINT "users_username_unique" UNIQUE("username"),
CONSTRAINT "users_email_unique" UNIQUE("email")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "wishlist_items" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"wishlist_id" varchar(255) NOT NULL,
"game_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "wishlists" (
"id" varchar(255) PRIMARY KEY NOT NULL,
"user_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT (now(6)),
"updated_at" timestamp with time zone DEFAULT (now(6))
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "collection_items" ADD CONSTRAINT "collection_items_collection_id_collections_id_fk" FOREIGN KEY ("collection_id") REFERENCES "collections"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "collection_items" ADD CONSTRAINT "collection_items_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "games"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "collections" ADD CONSTRAINT "collections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "expansions" ADD CONSTRAINT "expansions_base_game_id_games_id_fk" FOREIGN KEY ("base_game_id") REFERENCES "games"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "expansions" ADD CONSTRAINT "expansions_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "games"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "roles"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "wishlist_items" ADD CONSTRAINT "wishlist_items_wishlist_id_wishlists_id_fk" FOREIGN KEY ("wishlist_id") REFERENCES "wishlists"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "wishlist_items" ADD CONSTRAINT "wishlist_items_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "games"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "wishlists" ADD CONSTRAINT "wishlists_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View file

@ -1,192 +0,0 @@
CREATE TABLE `artists` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`external_id` int,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `artists_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `artists_to_games` (
`artist_id` varchar(255),
`game_id` varchar(255)
);
--> statement-breakpoint
CREATE TABLE `categories` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`external_id` int,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `categories_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `categories_to_games` (
`category_id` varchar(255),
`game_id` varchar(255)
);
--> statement-breakpoint
CREATE TABLE `collection_items` (
`id` varchar(255) NOT NULL,
`collection_id` varchar(255) NOT NULL,
`game_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `collection_items_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `collections` (
`id` varchar(255) NOT NULL,
`user_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `collections_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `designers` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`external_id` int,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `designers_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `designers_to_games` (
`designer_id` varchar(255),
`game_id` varchar(255)
);
--> statement-breakpoint
CREATE TABLE `expansions` (
`id` varchar(255) NOT NULL,
`base_game_id` varchar(255) NOT NULL,
`game_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `expansions_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `games` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`description` text,
`year_published` year,
`min_players` int,
`max_players` int,
`playtime` int,
`min_playtime` int,
`max_playtime` int,
`min_age` int,
`image_url` varchar(255),
`thumb_url` varchar(255),
`url` varchar(255),
`external_id` int,
`last_sync_at` datetime,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `games_id` PRIMARY KEY(`id`),
CONSTRAINT `games_external_id_unique` UNIQUE(`external_id`)
);
--> statement-breakpoint
CREATE TABLE `mechanics` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`external_id` int,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `mechanics_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `mechanics_to_games` (
`mechanic_id` varchar(255),
`game_id` varchar(255)
);
--> statement-breakpoint
CREATE TABLE `publishers` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
`slug` varchar(255),
`external_id` int,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `publishers_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `publishers_to_games` (
`publisher_id` varchar(255),
`game_id` varchar(255)
);
--> statement-breakpoint
CREATE TABLE `roles` (
`id` varchar(255) NOT NULL,
`name` varchar(255),
CONSTRAINT `roles_id` PRIMARY KEY(`id`),
CONSTRAINT `roles_name_unique` UNIQUE(`name`)
);
--> statement-breakpoint
CREATE TABLE `sessions` (
`id` varchar(255) NOT NULL,
`user_id` varchar(255) NOT NULL,
`expires_at` datetime NOT NULL,
CONSTRAINT `sessions_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `user_roles` (
`id` varchar(255) NOT NULL,
`user_id` varchar(255) NOT NULL,
`role_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `user_roles_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `users` (
`id` varchar(255) NOT NULL,
`username` varchar(255),
`hashed_password` varchar(255),
`email` varchar(255),
`first_name` varchar(255),
`last_name` varchar(255),
`verified` boolean DEFAULT false,
`receive_email` boolean DEFAULT false,
`theme` varchar(255) DEFAULT 'system',
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `users_id` PRIMARY KEY(`id`),
CONSTRAINT `users_username_unique` UNIQUE(`username`),
CONSTRAINT `users_email_unique` UNIQUE(`email`)
);
--> statement-breakpoint
CREATE TABLE `wishlist_items` (
`id` varchar(255) NOT NULL,
`wishlist_id` varchar(255) NOT NULL,
`game_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `wishlist_items_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
CREATE TABLE `wishlists` (
`id` varchar(255) NOT NULL,
`user_id` varchar(255) NOT NULL,
`created_at` datetime DEFAULT (now(6)),
`updated_at` datetime DEFAULT (now(6)),
CONSTRAINT `wishlists_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
ALTER TABLE `collection_items` ADD CONSTRAINT `collection_items_collection_id_collections_id_fk` FOREIGN KEY (`collection_id`) REFERENCES `collections`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `collection_items` ADD CONSTRAINT `collection_items_game_id_games_id_fk` FOREIGN KEY (`game_id`) REFERENCES `games`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `collections` ADD CONSTRAINT `collections_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `expansions` ADD CONSTRAINT `expansions_base_game_id_games_id_fk` FOREIGN KEY (`base_game_id`) REFERENCES `games`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `expansions` ADD CONSTRAINT `expansions_game_id_games_id_fk` FOREIGN KEY (`game_id`) REFERENCES `games`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `sessions` ADD CONSTRAINT `sessions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `wishlist_items` ADD CONSTRAINT `wishlist_items_wishlist_id_wishlists_id_fk` FOREIGN KEY (`wishlist_id`) REFERENCES `wishlists`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `wishlist_items` ADD CONSTRAINT `wishlist_items_game_id_games_id_fk` FOREIGN KEY (`game_id`) REFERENCES `games`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `wishlists` ADD CONSTRAINT `wishlists_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;

View file

@ -0,0 +1,51 @@
ALTER TABLE "artists" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "artists" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "artists" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "artists" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "categories" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "categories" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "categories" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "categories" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "collection_items" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "collection_items" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "collection_items" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "collection_items" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "collections" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "collections" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "collections" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "collections" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "designers" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "designers" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "designers" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "designers" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "expansions" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "expansions" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "expansions" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "expansions" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "games" ALTER COLUMN "last_sync_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "games" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "games" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "games" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "games" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "mechanics" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "mechanics" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "mechanics" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "mechanics" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "publishers" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "publishers" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "publishers" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "publishers" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "user_roles" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "user_roles" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "user_roles" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "user_roles" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "users" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "users" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "wishlist_items" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "wishlist_items" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "wishlist_items" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "wishlist_items" ALTER COLUMN "updated_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "wishlists" ALTER COLUMN "created_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "wishlists" ALTER COLUMN "created_at" SET DEFAULT (now());--> statement-breakpoint
ALTER TABLE "wishlists" ALTER COLUMN "updated_at" SET DATA TYPE timestamp (6) with time zone;--> statement-breakpoint
ALTER TABLE "wishlists" ALTER COLUMN "updated_at" SET DEFAULT (now());

View file

@ -1,2 +0,0 @@
ALTER TABLE `sessions` ADD `ip_country` varchar(255);--> statement-breakpoint
ALTER TABLE `sessions` ADD `ip_address` varchar(255);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,19 @@
{
"version": "5",
"dialect": "mysql",
"dialect": "pg",
"entries": [
{
"idx": 0,
"version": "5",
"when": 1707197486310,
"tag": "0000_true_sugar_man",
"when": 1707437865821,
"tag": "0000_oval_wolverine",
"breakpoints": true
},
{
"idx": 1,
"version": "5",
"when": 1707199636963,
"tag": "0001_motionless_old_lace",
"when": 1707438055782,
"tag": "0001_giant_tomorrow_man",
"breakpoints": true
}
]

View file

@ -16,10 +16,10 @@
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write .",
"site:update": "pnpm update -i -L",
"generate": "drizzle-kit generate:mysql",
"generate": "drizzle-kit generate:pg",
"migrate": "tsx ./src/migrate.ts",
"seed": "tsx ./src/seed/insert.ts",
"push": "drizzle-kit push:mysql"
"push": "drizzle-kit push:pg"
},
"prisma": {
"seed": "node --loader ts-node/esm prisma/seed.ts"
@ -56,7 +56,7 @@
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"svelte": "^4.2.10",
"svelte-check": "^3.6.3",
"svelte-check": "^3.6.4",
"svelte-meta-tags": "^3.1.0",
"svelte-preprocess": "^5.1.3",
"svelte-sequential-preprocessor": "^2.0.1",
@ -83,6 +83,7 @@
"@lucia-auth/adapter-drizzle": "^1.0.1",
"@lucia-auth/adapter-prisma": "4.0.0",
"@lukeed/uuid": "^2.0.1",
"@neondatabase/serverless": "^0.8.1",
"@paralleldrive/cuid2": "^2.2.2",
"@planetscale/database": "^1.15.0",
"@prisma/client": "^5.8.1",
@ -108,6 +109,8 @@
"nanoid": "^5.0.5",
"open-props": "^1.6.18",
"oslo": "^1.1.0",
"pg": "^8.11.3",
"postgres": "^3.4.3",
"radix-svelte": "^0.9.0",
"svelte-french-toast": "^1.2.0",
"svelte-lazy-loader": "^1.0.0",

View file

@ -23,6 +23,9 @@ dependencies:
'@lukeed/uuid':
specifier: ^2.0.1
version: 2.0.1
'@neondatabase/serverless':
specifier: ^0.8.1
version: 0.8.1
'@paralleldrive/cuid2':
specifier: ^2.2.2
version: 2.2.2
@ -61,7 +64,7 @@ dependencies:
version: 0.6.0
drizzle-orm:
specifier: ^0.29.3
version: 0.29.3(@planetscale/database@1.15.0)(mysql2@3.9.1)
version: 0.29.3(@neondatabase/serverless@0.8.1)(@planetscale/database@1.15.0)(mysql2@3.9.1)(pg@8.11.3)(postgres@3.4.3)
feather-icons:
specifier: ^4.29.1
version: 4.29.1
@ -98,6 +101,12 @@ dependencies:
oslo:
specifier: ^1.1.0
version: 1.1.0
pg:
specifier: ^8.11.3
version: 8.11.3
postgres:
specifier: ^3.4.3
version: 3.4.3
radix-svelte:
specifier: ^0.9.0
version: 0.9.0(svelte@4.2.10)
@ -215,8 +224,8 @@ devDependencies:
specifier: ^4.2.10
version: 4.2.10
svelte-check:
specifier: ^3.6.3
version: 3.6.3(postcss-load-config@5.0.2)(postcss@8.4.35)(sass@1.70.0)(svelte@4.2.10)
specifier: ^3.6.4
version: 3.6.4(postcss-load-config@5.0.2)(postcss@8.4.35)(sass@1.70.0)(svelte@4.2.10)
svelte-meta-tags:
specifier: ^3.1.0
version: 3.1.0(svelte@4.2.10)(typescript@5.3.3)
@ -1657,6 +1666,13 @@ packages:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
/@jridgewell/trace-mapping@0.3.22:
resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==}
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/@jridgewell/trace-mapping@0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
@ -1762,6 +1778,12 @@ packages:
dev: false
optional: true
/@neondatabase/serverless@0.8.1:
resolution: {integrity: sha512-nxZfTLbGqvDrw0W9WnQxzoPn4KC6SLjkvK4grdf6eWVMQSc24X+8udz9inZWOGu8f0O3wJAq586fCZ32r22lwg==}
dependencies:
'@types/pg': 8.6.6
dev: false
/@noble/hashes@1.3.2:
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'}
@ -3041,6 +3063,14 @@ packages:
dependencies:
undici-types: 5.26.5
/@types/pg@8.6.6:
resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==}
dependencies:
'@types/node': 20.11.16
pg-protocol: 1.6.0
pg-types: 2.2.0
dev: false
/@types/pug@2.0.8:
resolution: {integrity: sha512-QzhsZ1dMGyJbn/D9V80zp4GIA4J4rfAjCCxc3MP+new0E8dyVdSkR735Lx+n3LIaHNFcjHL5+TbziccuT+fdoQ==}
dev: true
@ -3524,6 +3554,11 @@ packages:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/buffer-writer@2.0.0:
resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==}
engines: {node: '>=4'}
dev: false
/cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@ -3604,6 +3639,21 @@ packages:
optionalDependencies:
fsevents: 2.3.3
/chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
dependencies:
anymatch: 3.1.3
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
dev: true
/chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
@ -3931,7 +3981,7 @@ packages:
- supports-color
dev: true
/drizzle-orm@0.29.3(@planetscale/database@1.15.0)(mysql2@3.9.1):
/drizzle-orm@0.29.3(@neondatabase/serverless@0.8.1)(@planetscale/database@1.15.0)(mysql2@3.9.1)(pg@8.11.3)(postgres@3.4.3):
resolution: {integrity: sha512-uSE027csliGSGYD0pqtM+SAQATMREb3eSM/U8s6r+Y0RFwTKwftnwwSkqx3oS65UBgqDOM0gMTl5UGNpt6lW0A==}
peerDependencies:
'@aws-sdk/client-rds-data': '>=3'
@ -4002,8 +4052,11 @@ packages:
sqlite3:
optional: true
dependencies:
'@neondatabase/serverless': 0.8.1
'@planetscale/database': 1.15.0
mysql2: 3.9.1
pg: 8.11.3
postgres: 3.4.3
dev: false
/electron-to-chromium@1.4.576:
@ -4366,17 +4419,6 @@ packages:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
/fast-glob@3.3.1:
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
engines: {node: '>=8.6.0'}
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.5
dev: true
/fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
@ -5502,6 +5544,10 @@ packages:
dependencies:
p-limit: 3.1.0
/packet-reader@1.0.0:
resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==}
dev: false
/pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
@ -5567,6 +5613,70 @@ packages:
estree-walker: 3.0.3
is-reference: 3.0.2
/pg-cloudflare@1.1.1:
resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
requiresBuild: true
dev: false
optional: true
/pg-connection-string@2.6.2:
resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==}
dev: false
/pg-int8@1.0.1:
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
engines: {node: '>=4.0.0'}
dev: false
/pg-pool@3.6.1(pg@8.11.3):
resolution: {integrity: sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==}
peerDependencies:
pg: '>=8.0'
dependencies:
pg: 8.11.3
dev: false
/pg-protocol@1.6.0:
resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==}
dev: false
/pg-types@2.2.0:
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
engines: {node: '>=4'}
dependencies:
pg-int8: 1.0.1
postgres-array: 2.0.0
postgres-bytea: 1.0.0
postgres-date: 1.0.7
postgres-interval: 1.2.0
dev: false
/pg@8.11.3:
resolution: {integrity: sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==}
engines: {node: '>= 8.0.0'}
peerDependencies:
pg-native: '>=3.0.1'
peerDependenciesMeta:
pg-native:
optional: true
dependencies:
buffer-writer: 2.0.0
packet-reader: 1.0.0
pg-connection-string: 2.6.2
pg-pool: 3.6.1(pg@8.11.3)
pg-protocol: 1.6.0
pg-types: 2.2.0
pgpass: 1.0.5
optionalDependencies:
pg-cloudflare: 1.1.1
dev: false
/pgpass@1.0.5:
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
dependencies:
split2: 4.2.0
dev: false
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
@ -6061,6 +6171,33 @@ packages:
picocolors: 1.0.0
source-map-js: 1.0.2
/postgres-array@2.0.0:
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
engines: {node: '>=4'}
dev: false
/postgres-bytea@1.0.0:
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
engines: {node: '>=0.10.0'}
dev: false
/postgres-date@1.0.7:
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
engines: {node: '>=0.10.0'}
dev: false
/postgres-interval@1.2.0:
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
engines: {node: '>=0.10.0'}
dependencies:
xtend: 4.0.2
dev: false
/postgres@3.4.3:
resolution: {integrity: sha512-iHJn4+M9vbTdHSdDzNkC0crHq+1CUdFhx+YqCE+SqWxPjm+Zu63jq7yZborOBF64c8pc58O5uMudyL1FQcHacA==}
engines: {node: '>=12'}
dev: false
/prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@ -6453,6 +6590,11 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
/split2@4.2.0:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
dev: false
/sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
dev: false
@ -6552,15 +6694,15 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/svelte-check@3.6.3(postcss-load-config@5.0.2)(postcss@8.4.35)(sass@1.70.0)(svelte@4.2.10):
resolution: {integrity: sha512-Q2nGnoysxUnB9KjnjpQLZwdjK62DHyW6nuH/gm2qteFnDk0lCehe/6z8TsIvYeKjC6luKaWxiNGyOcWiLLPSwA==}
/svelte-check@3.6.4(postcss-load-config@5.0.2)(postcss@8.4.35)(sass@1.70.0)(svelte@4.2.10):
resolution: {integrity: sha512-mY/dqucqm46p72M8yZmn81WPZx9mN6uuw8UVfR3ZKQeLxQg5HDGO3HHm5AZuWZPYNMLJ+TRMn+TeN53HfQ/vsw==}
hasBin: true
peerDependencies:
svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0
dependencies:
'@jridgewell/trace-mapping': 0.3.20
chokidar: 3.5.3
fast-glob: 3.3.1
'@jridgewell/trace-mapping': 0.3.22
chokidar: 3.6.0
fast-glob: 3.3.2
import-fresh: 3.3.0
picocolors: 1.0.0
sade: 1.8.1
@ -7261,6 +7403,11 @@ packages:
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
/xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
dev: false
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}

View file

@ -158,7 +158,6 @@ model Game {
image_url String?
thumb_url String?
url String?
rules_url String?
categories Category[]
mechanics Mechanic[]
designers Designer[]

View file

@ -1,10 +1,10 @@
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { drizzle } from "drizzle-orm/node-postgres";
import pg from 'pg';
import { DATABASE_USER, DATABASE_PASSWORD, DATABASE_HOST, DATABASE_DB } from '$env/static/private';
import * as schema from '../schema';
// create the connection
const connection = await mysql.createConnection({
const pool = new pg.Pool({
user: DATABASE_USER,
password: DATABASE_PASSWORD,
host: DATABASE_HOST,
@ -12,6 +12,6 @@ const connection = await mysql.createConnection({
database: DATABASE_DB
});
const db = drizzle(connection, { schema: schema, mode: 'default' });
const db = drizzle(pool, { schema: schema });
export default db;

View file

@ -1,11 +1,11 @@
// lib/server/lucia.ts
import { Lucia, TimeSpan } from 'lucia';
import { DrizzleMySQLAdapter } from "@lucia-auth/adapter-drizzle";
import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle";
import { dev } from '$app/environment';
import db from '$lib/drizzle';
import { sessions, users } from '../../schema';
const adapter = new DrizzleMySQLAdapter(db, sessions, users);
const adapter = new DrizzlePostgreSQLAdapter(db, sessions, users);
export const lucia = new Lucia(adapter, {
getSessionAttributes: (attributes) => {

View file

@ -3,6 +3,9 @@ import kebabCase from 'just-kebab-case';
import type { BggLinkDto } from 'boardgamegeekclient/dist/esm/dto/concrete/subdto';
import prisma from '$lib/prisma';
import { mapAPIGameToBoredGame } from './gameMapper';
import db from '$lib/drizzle';
import { games } from '../../schema';
import { eq, sql } from 'drizzle-orm';
export async function createArtist(locals: App.Locals, externalArtist: BggLinkDto) {
try {
@ -331,41 +334,23 @@ export async function createExpansion(
export async function createOrUpdateGameMinimal(locals: App.Locals, game: Game) {
console.log('Creating or updating minimal game data', JSON.stringify(game, null, 2));
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
return await prisma.game.upsert({
where: {
external_id: game.external_id
},
create: {
name: game.name,
slug: kebabCase(game.name),
description: game.description,
external_id: game.external_id,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0
},
update: {
name: game.name,
slug: kebabCase(game.name),
description: game.description,
external_id: game.external_id,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0
}
});
await db.insert(games).values({
external_id: game.external_id,
name: game.name,
slug: kebabCase(game.name),
description: game.description,
url: externalUrl,
thumb_url: game.thumb_url,
image_url: game.image_url,
min_age: game.min_age || 0,
min_players: game.min_players || 0,
max_players: game.max_players || 0,
min_playtime: game.min_playtime || 0,
max_playtime: game.max_playtime || 0,
year_published: game.year_published || 0,
}).onDuplicateKeyUpdate({ set: { external_id: sql`external_id` } });
return db.query.games.findFirst({ where: eq(games.external_id, game.external_id) });
}
export async function createOrUpdateGame(locals: App.Locals, game: Game) {
@ -379,7 +364,10 @@ export async function createOrUpdateGame(locals: App.Locals, game: Game) {
const externalUrl = `https://boardgamegeek.com/boardgame/${game.external_id}`;
console.log('categoryIds', categoryIds);
console.log('mechanicIds', mechanicIds);
return await prisma.game.upsert({
await db.transaction(async (transaction) => {
const
});
await db.insert(games).values({
include: {
mechanics: true,
publishers: true,

View file

@ -222,7 +222,6 @@ const gameSchema = z.object({
image_url: z.string().optional(),
thumb_url: z.string().optional(),
url: z.string().optional(),
rules_url: z.string().optional(),
weight_amount: z.number().optional(),
weight_units: z.enum(['Medium', 'Heavy']).optional(),
categories: z.array(category_schema).optional(),

View file

@ -1,9 +1,9 @@
import 'dotenv/config';
import { drizzle } from 'drizzle-orm/mysql2';
import { migrate } from 'drizzle-orm/mysql2/migrator';
import { createConnection } from 'mysql2';
import { drizzle } from 'drizzle-orm/postgres-js';
import { migrate } from 'drizzle-orm/postgres-js/migrator';
import postgres from 'postgres';
const connection = createConnection({
const connection = postgres({
host: process.env.DATABASE_HOST,
port: 3306,
user: process.env.DATABASE_USER,

View file

@ -82,7 +82,7 @@ async function searchForGames(
if (externalGameResponse.ok) {
const externalGame = await externalGameResponse.json();
console.log('externalGame', externalGame);
let boredGame = mapAPIGameToBoredGame(externalGame);
const boredGame = mapAPIGameToBoredGame(externalGame);
games.push(createOrUpdateGameMinimal(locals, boredGame));
}
}
@ -127,7 +127,8 @@ export const load: PageServerLoad = async ({ locals, fetch, url }) => {
const queryParams: SearchQuery = {
limit: form.data?.limit,
skip: form.data?.skip,
q: form.data?.q
q: form.data?.q,
exact: form.data?.exact
};
try {

View file

@ -1,13 +1,13 @@
import { fail, type Actions } from '@sveltejs/kit';
import { eq, sql } from 'drizzle-orm';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { redirect } from 'sveltekit-flash-message/server';
import { lucia } from '$lib/server/auth';
import { Argon2id } from 'oslo/password';
import { userSchema } from '$lib/config/zod-schemas';
import type { PageServerLoad } from './$types';
import db from '$lib/drizzle';
import { eq, sql } from 'drizzle-orm';
import { collections, users, wishlists } from '../../../schema';
import type { PageServerLoad } from './$types';
const signInSchema = userSchema.pick({
username: true,

View file

@ -1,16 +1,15 @@
import { fail, error, type Actions, redirect } from '@sveltejs/kit';
import { Argon2id } from 'oslo/password';
import { eq } from 'drizzle-orm';
import { nanoid } from 'nanoid';
import { setError, superValidate } from 'sveltekit-superforms/server';
import type { PageServerLoad } from './$types';
import prisma from '$lib/prisma';
import { lucia } from '$lib/server/auth';
import { Argon2id } from 'oslo/password';
import { userSchema } from '$lib/config/zod-schemas';
import { add_user_to_role } from '$server/roles';
import type { Message } from '$lib/types.js';
import db from '$lib/drizzle';
import { collections, users, wishlists } from '../../../schema';
import { eq } from 'drizzle-orm';
import { nanoid } from 'nanoid';
const signUpSchema = userSchema
.pick({
@ -71,7 +70,7 @@ export const actions: Actions = {
const hashedPassword = await new Argon2id().hash(form.data.password);
await db.insert(users)
const user = await db.insert(users)
.values({
username: form.data.username,
hashed_password: hashedPassword,
@ -81,10 +80,7 @@ export const actions: Actions = {
verified: false,
receive_email: false,
theme: 'system'
});
const user = await db.select()
.from(users)
.where(eq(users.username, form.data.username));
}).returning();
console.log('signup user', user);
if (!user || user.length === 0) {

View file

@ -1,6 +1,7 @@
import { error, json } from '@sveltejs/kit';
import { Prisma } from '@prisma/client';
import prisma from '$lib/prisma';
import db from '$lib/drizzle.js';
import { eq, sql } from 'drizzle-orm';
import { games } from '../../../../schema.js';
// Search a user's collection
export const GET = async ({ url, locals }) => {
@ -8,53 +9,61 @@ export const GET = async ({ url, locals }) => {
const q = searchParams?.q?.trim() || '';
const limit = parseInt(searchParams?.limit) || 10;
const skip = parseInt(searchParams?.skip) || 0;
const order: Prisma.SortOrder = <Prisma.SortOrder>searchParams?.order || 'desc';
const order = searchParams?.order || 'desc';
const exact = searchParams?.exact === 'true';
console.log(`q: ${q}, limit: ${limit}, skip: ${skip}, order: ${order}`);
// const sort : Prisma.GameOrderByRelevanceFieldEnum = <Prisma.GameOrderByRelevanceFieldEnum>searchParams?.sort || 'name';
// console.log('url', url);
const exactGameSelect: Prisma.GameSelect = {
id: true,
name: true,
slug: true,
thumb_url: true
};
let orderBy = searchParams?.orderBy || 'slug';
if (orderBy === 'name') {
orderBy = 'slug';
}
console.log(`q: ${q}, limit: ${limit}, skip: ${skip}, order: ${order}, exact: ${exact}`);
console.log(exact);
if (exact) {
console.log('Exact Search API');
const game =
await prisma.game.findFirst({
where: {
name: {
equals: q
}
},
select: exactGameSelect
await db.query.games.findFirst({
where: eq(games.name, q),
columns: {
id: true,
name: true,
slug: true,
thumb_url: true
}
});
if (!game) {
error(404, { message: 'No games found' });
}
const games = [game];
console.log('Games found in Exact Search API', JSON.stringify(games, null, 2));
return json(games);
const foundGames = [game];
console.log('Games found in Exact Search API', JSON.stringify(foundGames, null, 2));
return json(foundGames);
} else {
const games =
(await prisma.game.findMany({
orderBy: {
_relevance: {
fields: ['name'],
search: q,
sort: order
}
},
select: exactGameSelect,
take: limit,
skip
})) || [];
if (games.length === 0) {
const foundGames = await db.select({
id: games.id,
name: games.name,
slug: games.slug,
thumb_url: games.thumb_url
})
.from(games)
.where(sql`match(${games.name}, ${games.slug}) against(${q} in natural language mode)`)
.offset(skip).limit(limit).orderBy(sql`${orderBy} ${order}`) || [];
// const games =
// (await prisma.game.findMany({
// orderBy: {
// _relevance: {
// fields: ['name'],
// search: q,
// sort: order
// }
// },
// select: exactGameSelect,
// take: limit,
// skip
// })) || [];
if (foundGames.length === 0) {
error(404, { message: 'No games found' });
}
console.log('Games found in Search API', JSON.stringify(games, null, 2));
return json(games);
console.log('Games found in Search API', JSON.stringify(foundGames, null, 2));
return json(foundGames);
}
};

View file

@ -1,8 +1,8 @@
import { relations, sql, type InferSelectModel } from 'drizzle-orm';
import { mysqlTable, datetime, varchar, boolean, year, int, text } from 'drizzle-orm/mysql-core';
import { pgTable, timestamp, varchar, boolean, integer, text } from 'drizzle-orm/pg-core';
import { nanoid } from 'nanoid';
export const users = mysqlTable("users", {
export const users = pgTable("users", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -27,8 +27,8 @@ export const users = mysqlTable("users", {
theme: varchar("theme", {
length: 255
}).default("system"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at").default(sql`(now())`),
updated_at: timestamp("updated_at").default(sql`(now())`)
});
export const user_relations = relations(users, ({ many }) => ({
@ -37,7 +37,7 @@ export const user_relations = relations(users, ({ many }) => ({
export type Users = InferSelectModel<typeof users>;
export const sessions = mysqlTable('sessions', {
export const sessions = pgTable('sessions', {
id: varchar('id', {
length: 255
}).primaryKey(),
@ -46,7 +46,10 @@ export const sessions = mysqlTable('sessions', {
})
.notNull()
.references(() => users.id),
expiresAt: datetime('expires_at').notNull(),
expiresAt: timestamp('expires_at', {
withTimezone: true,
mode: "date"
}).notNull(),
ipCountry: varchar('ip_country', {
length: 255
}),
@ -55,7 +58,7 @@ export const sessions = mysqlTable('sessions', {
})
});
export const roles = mysqlTable("roles", {
export const roles = pgTable("roles", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -65,7 +68,7 @@ export const roles = mysqlTable("roles", {
}).unique()
});
export const user_roles = mysqlTable("user_roles", {
export const user_roles = pgTable("user_roles", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -80,8 +83,16 @@ export const user_roles = mysqlTable("user_roles", {
})
.notNull()
.references(() => roles.id, { onDelete: 'cascade' }),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const user_role_relations = relations(user_roles, ({ one }) => ({
@ -95,7 +106,7 @@ export const user_role_relations = relations(user_roles, ({ one }) => ({
})
}));
export const games = mysqlTable("games", {
export const games = pgTable("games", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -107,13 +118,13 @@ export const games = mysqlTable("games", {
length: 255
}),
description: text("description"),
year_published: year("year_published"),
min_players: int("min_players"),
max_players: int("max_players"),
playtime: int("playtime"),
min_playtime: int("min_playtime"),
max_playtime: int("max_playtime"),
min_age: int("min_age"),
year_published: integer("year_published"),
min_players: integer("min_players"),
max_players: integer("max_players"),
playtime: integer("playtime"),
min_playtime: integer("min_playtime"),
max_playtime: integer("max_playtime"),
min_age: integer("min_age"),
image_url: varchar("image_url", {
length: 255
}),
@ -123,10 +134,22 @@ export const games = mysqlTable("games", {
url: varchar("url", {
length: 255
}),
external_id: int("external_id").unique(),
last_sync_at: datetime("last_sync_at"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id").unique(),
last_sync_at: timestamp("last_sync_at", {
withTimezone: true,
mode: "date",
precision: 6
}),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export type Games = InferSelectModel<typeof games>;
@ -139,7 +162,7 @@ export const gameRelations = relations(games, ({ many }) => ({
artists_to_games: many(artists_to_games),
}))
export const expansions = mysqlTable("expansions", {
export const expansions = pgTable("expansions", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -154,8 +177,16 @@ export const expansions = mysqlTable("expansions", {
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
})
export const expansion_relations = relations(expansions, ({ one }) => ({
@ -169,7 +200,7 @@ export const expansion_relations = relations(expansions, ({ one }) => ({
})
}));
export const collections = mysqlTable("collections", {
export const collections = pgTable("collections", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -179,8 +210,16 @@ export const collections = mysqlTable("collections", {
})
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const collection_relations = relations(collections, ({ one }) => ({
@ -190,7 +229,7 @@ export const collection_relations = relations(collections, ({ one }) => ({
}),
}))
export const collection_items = mysqlTable("collection_items", {
export const collection_items = pgTable("collection_items", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -205,8 +244,16 @@ export const collection_items = mysqlTable("collection_items", {
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const collection_item_relations = relations(collection_items, ({ one }) =>({
@ -220,7 +267,7 @@ export const collection_item_relations = relations(collection_items, ({ one }) =
})
}));
export const wishlists = mysqlTable("wishlists", {
export const wishlists = pgTable("wishlists", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -230,8 +277,16 @@ export const wishlists = mysqlTable("wishlists", {
})
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const wishlists_relations = relations(wishlists, ({ one }) => ({
@ -241,7 +296,7 @@ export const wishlists_relations = relations(wishlists, ({ one }) => ({
}),
}))
export const wishlist_items = mysqlTable('wishlist_items', {
export const wishlist_items = pgTable('wishlist_items', {
id: varchar('id', {
length: 255
})
@ -257,8 +312,16 @@ export const wishlist_items = mysqlTable('wishlist_items', {
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
created_at: datetime('created_at').default(sql`(now(6))`),
updated_at: datetime('updated_at').default(sql`(now(6))`)
created_at: timestamp('created_at', {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp('updated_at', {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const wishlist_item_relations = relations(wishlist_items, ({ one }) => ({
@ -272,7 +335,7 @@ export const wishlist_item_relations = relations(wishlist_items, ({ one }) => ({
})
}))
export const publishers = mysqlTable("publishers", {
export const publishers = pgTable("publishers", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -283,16 +346,24 @@ export const publishers = mysqlTable("publishers", {
slug: varchar("slug", {
length: 255
}),
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id"),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const publishers_relations = relations(publishers, ({ many }) => ({
publishers_to_games: many(publishers_to_games)
}));
export const categories = mysqlTable("categories", {
export const categories = pgTable("categories", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -303,16 +374,24 @@ export const categories = mysqlTable("categories", {
slug: varchar("slug", {
length: 255
}),
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id"),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const categories_relations = relations(categories, ({ many }) => ({
categories_to_games: many(categories_to_games)
}));
export const mechanics = mysqlTable("mechanics", {
export const mechanics = pgTable("mechanics", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -323,16 +402,24 @@ export const mechanics = mysqlTable("mechanics", {
slug: varchar("slug", {
length: 255
}),
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id"),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const mechanic_relations = relations(mechanics, ({ many }) => ({
mechanics_to_games: many(mechanics_to_games)
}))
export const designers = mysqlTable("designers", {
export const designers = pgTable("designers", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -343,16 +430,24 @@ export const designers = mysqlTable("designers", {
slug: varchar("slug", {
length: 255
}),
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id"),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const designers_relations = relations(designers, ({ many }) => ({
designers_to_games: many(designers_to_games)
}));
export const artists = mysqlTable("artists", {
export const artists = pgTable("artists", {
id: varchar("id", {
length: 255
}).primaryKey()
@ -363,16 +458,24 @@ export const artists = mysqlTable("artists", {
slug: varchar("slug", {
length: 255
}),
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
external_id: integer("external_id"),
created_at: timestamp("created_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`),
updated_at: timestamp("updated_at", {
withTimezone: true,
mode: "date",
precision: 6
}).default(sql`(now())`)
});
export const artists_relations = relations(artists, ({ many }) => ({
artists_to_games: many(artists_to_games)
}));
export const artists_to_games = mysqlTable('artists_to_games', {
export const artists_to_games = pgTable('artists_to_games', {
artist_id: varchar('artist_id', {
length: 255
}),
@ -392,7 +495,7 @@ export const artists_to_games_relations = relations(artists_to_games, ({ one })
}),
}));
export const categories_to_games = mysqlTable("categories_to_games", {
export const categories_to_games = pgTable("categories_to_games", {
category_id: varchar("category_id", {
length: 255
}),
@ -412,7 +515,7 @@ export const categories_to_games_relations = relations(categories_to_games, ({ o
}),
}))
export const designers_to_games = mysqlTable("designers_to_games", {
export const designers_to_games = pgTable("designers_to_games", {
designer_id: varchar("designer_id", {
length: 255
}),
@ -432,7 +535,7 @@ export const designers_to_games_relations = relations(designers_to_games, ({ one
}),
}))
export const mechanics_to_games = mysqlTable("mechanics_to_games", {
export const mechanics_to_games = pgTable("mechanics_to_games", {
mechanic_id: varchar("mechanic_id", {
length: 255
}),
@ -452,7 +555,7 @@ export const mechanics_to_games_relations = relations(mechanics_to_games, ({ one
}),
}));
export const publishers_to_games = mysqlTable("publishers_to_games", {
export const publishers_to_games = pgTable("publishers_to_games", {
publisher_id: varchar("publisher_id", {
length: 255
}),

View file

@ -1,19 +1,23 @@
import 'dotenv/config';
import { drizzle } from 'drizzle-orm/mysql2';
import { createConnection } from 'mysql2';
import { drizzle } from "drizzle-orm/node-postgres";
import { sql } from 'drizzle-orm';
import pg from 'pg';
import * as schema from '../schema';
const connection = createConnection({
host: process.env.DATABASE_HOST,
port: 3306,
// create the connection
const pool = new pg.Pool({
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
database: process.env.DATABASE_DB
});
const db = drizzle(connection, { schema: schema, mode: 'default' });
const db = drizzle(pool, { schema: schema });
const existingRoles = await db.query.roles.findMany();
if (existingRoles.length === 0) {
console.log('Creating roles ...');
await db.insert(schema.roles).values([{
name: 'admin'
}, {
@ -24,4 +28,20 @@ if (existingRoles.length === 0) {
console.log('Roles already exist. No action taken.');
}
const indexes = await db.execute(sql`select * from pg_catalog.pg_indexes where tablename = 'games'`);
console.log('Indexes', indexes);
const nameSlugIndexExists = indexes[0].flatMap((i) => i.Key_name).indexOf('full_text_name_slug_index') > -1;
console.log('nameSlugIndexExists', nameSlugIndexExists);
if (!nameSlugIndexExists) {
console.log('Full Text Index does not exist. Creating...');
// Create index
await db.execute(sql`alter table games ADD FULLTEXT INDEX full_text_name_slug_index (name, slug)`);
} else {
console.log('Full Text Index already exists. No action taken.');
}
await connection.end();