From cacbbd48c4b984dc89286fddf6f455909845db2b Mon Sep 17 00:00:00 2001 From: Marcel <65048232+dromzeh@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:08:30 +0100 Subject: [PATCH] fallback to crud for asset querying --- src/v2/db/schema.ts | 5 +- src/v2/routes/auth/authRoute.ts | 16 ++-- src/v2/routes/auth/games/createGame.ts | 4 +- src/v2/routes/search/asset/searchAssets.ts | 94 +++++++++++----------- 4 files changed, 61 insertions(+), 58 deletions(-) diff --git a/src/v2/db/schema.ts b/src/v2/db/schema.ts index 66d30b18..3a7822ae 100644 --- a/src/v2/db/schema.ts +++ b/src/v2/db/schema.ts @@ -429,8 +429,9 @@ export const savedOcGenerators = sqliteTable( game: text("game").notNull(), dateCreated: integer("date_created").notNull(), isPublic: integer("is_public").default(0).notNull(), - content: text("content").notNull(), // this is stored as json, which is then parsed on the frontend - savedColorPalette: text("saved_color_palette"), // array of 5 hex values, completely optional + content: text("content").notNull(), + savedColorPalette: text("saved_color_palette"), // array of 5 hex values, completely optional for the user to save + sakuraUrl: text("sakura_url"), }, (savedOcGenerators) => { return { diff --git a/src/v2/routes/auth/authRoute.ts b/src/v2/routes/auth/authRoute.ts index a498d345..d91cf1bd 100644 --- a/src/v2/routes/auth/authRoute.ts +++ b/src/v2/routes/auth/authRoute.ts @@ -31,6 +31,14 @@ authRoute.post("/login", async (c) => { return login(c) }) +authRoute.get("/validate", async (c) => { + return validate(c) +}) + +authRoute.post("/logout", async (c) => { + return logout(c) +}) + authRoute.post("/update/attributes", async (c) => { return updateUserAttributes(c) }) @@ -79,12 +87,4 @@ authRoute.post("/oc-generator/delete", async (c) => { return deleteOCGeneratorResponse(c) }) -authRoute.get("/validate", async (c) => { - return validate(c) -}) - -authRoute.post("/logout", async (c) => { - return logout(c) -}) - export default authRoute diff --git a/src/v2/routes/auth/games/createGame.ts b/src/v2/routes/auth/games/createGame.ts index 93cb9f37..be4d075f 100644 --- a/src/v2/routes/auth/games/createGame.ts +++ b/src/v2/routes/auth/games/createGame.ts @@ -35,8 +35,8 @@ export async function createGame(c: APIContext): Promise { } // check if game.name exists - const gameExists = await drizzle.query.assetCategories.findFirst({ - where: (assetCategories, { eq }) => eq(assetCategories.name, game.name), + const gameExists = await drizzle.query.games.findFirst({ + where: (games, { eq }) => eq(games.name, game.name), }) if (gameExists) { diff --git a/src/v2/routes/search/asset/searchAssets.ts b/src/v2/routes/search/asset/searchAssets.ts index 04fe9928..cf355996 100644 --- a/src/v2/routes/search/asset/searchAssets.ts +++ b/src/v2/routes/search/asset/searchAssets.ts @@ -1,9 +1,8 @@ import { responseHeaders } from "@/v2/lib/responseHeaders" import { getConnection } from "@/v2/db/turso" -import { like } from "drizzle-orm" -import { assets } from "@/v2/db/schema" -import { desc } from "drizzle-orm" +import { assetTagsAssets, assets, assetTags, users } from "@/v2/db/schema" +import { desc, like, sql, eq, and, or } from "drizzle-orm" import { SplitQueryByCommas } from "@/v2/lib/helpers/splitQueryByCommas" export async function searchForAssets(c: APIContext): Promise { @@ -12,7 +11,8 @@ export async function searchForAssets(c: APIContext): Promise { let response = await cache.match(cacheKey) if (response) return response - const { query, game, assetCategory, assetTags } = c.req.query() + const { query, gameQuery, assetCategoryQuery, assetTagsQuery } = + c.req.query() // search parameters can include optional search params: query, game, assetCategory, assetTags // query?: string => ?query=keqing @@ -22,60 +22,62 @@ export async function searchForAssets(c: APIContext): Promise { const drizzle = getConnection(c.env).drizzle - // check if certian search parameters are present, if not, set them to null const searchQuery = query ?? null - const gameList = game ? SplitQueryByCommas(game) : null - const assetCategoryList = assetCategory - ? SplitQueryByCommas(assetCategory) + const gameList = gameQuery + ? SplitQueryByCommas(gameQuery.toLowerCase()) : null - const assetTagsList = assetTags ? SplitQueryByCommas(assetTags) : null + const assetCategoryList = assetCategoryQuery + ? SplitQueryByCommas(assetCategoryQuery.toLowerCase()) + : null + const assetTagsList = assetTagsQuery + ? SplitQueryByCommas(assetTagsQuery.toLowerCase()) + : // TODO(dromzeh): allow for no tags to be specified, this is just temporary as it creates unnecessary complexity + ["official", "fanmade"] - console.log(searchQuery, gameList, assetCategoryList, assetTagsList) + const assetTagResponse = drizzle.$with("sq").as( + drizzle + .select({ + assetId: assetTagsAssets.assetId, + tags: sql`array_agg(${assetTags})`.as("tags"), + }) + .from(assetTagsAssets) + .leftJoin(assetTags, eq(assetTags.id, assetTagsAssets.assetTagId)) + .where(or(...assetTagsList.map((tag) => eq(assetTags.name, tag)))) + .groupBy(assetTagsAssets.assetId) + ) - // query the database for assets that match the search parameters - const assetResponse = await drizzle.query.assets.findMany({ - where: (assets, { and, or, eq }) => { - return and( - searchQuery ? like(assets.name, `%${searchQuery}%`) : null, - gameList - ? or(...gameList.map((game) => eq(assets.game, game))) - : null, - assetCategoryList - ? or( - ...assetCategoryList.map((assetCategory) => - eq(assets.assetCategory, assetCategory) - ) - ) - : null, + const result = await drizzle + .with(assetTagResponse) + .select() + .from(assets) + .innerJoin(assetTagResponse, eq(assetTagResponse.assetId, assets.id)) + .where( + and( + searchQuery && like(assets.name, `%${searchQuery}%`), + gameList && + or(...gameList.map((game) => eq(assets.game, game))), + assetCategoryList && + or( + ...assetCategoryList.map((category) => + eq(assets.assetCategory, category) + ) + ), eq(assets.status, 1) ) - }, - with: { - assetTagsAssets: { - with: { - assetTags: true, - }, - }, - users: { - columns: { - email: false, - emailVerified: false, - }, - }, - }, - orderBy: desc(assets.id), - limit: 500, - }) + ) + .leftJoin(users, eq(users.id, assets.uploadedById)) + .orderBy(desc(assets.uploadedDate)) + .limit(500) response = c.json( { success: true, status: "ok", query, - game, - assetCategory, - assetTags, - results: assetResponse ? assetResponse : [], + gameQuery, + assetCategoryQuery, + assetTagsQuery, + results: result ?? [], }, 200, responseHeaders