Ignore:
Timestamp:
12/23/25 04:22:06 (7 months ago)
Author:
Tome <gjorgievtome@…>
Branches:
main
Children:
6196d60
Parents:
226fbbb
Message:

Update and add

File:
1 edited

Legend:

Unmodified
Added
Removed
  • database/drizzle/queries/builds.ts

    r226fbbb rea09e98  
    99} from "../schema";
    1010import {eq, desc, and, sql, ilike} from "drizzle-orm";
     11import {inArray} from "drizzle-orm/sql/expressions/conditions";
    1112
    1213export async function getPendingBuilds(db: Database) {
     
    5152        })
    5253        .where(
    53             eq(buildsTable.id, buildId)
    54         );
    55 
    56     return result.rowCount;
     54            and(
     55                eq(buildsTable.id, buildId),
     56                eq(buildsTable.isApproved, !isApproved)
     57            )
     58        )
     59        .returning({
     60            id: buildsTable.id
     61        })
     62
     63    return result.length;
    5764}
    5865
     
    257264            ...buildDetails,
    258265            components: components.map(c => c.component),
    259             reviews: reviews,
     266            reviews: reviews.map(r => ({
     267                username: r.username,
     268                content: r.content,
     269                createdAt: r.createdAt
     270            })),
    260271            ratingStatistics: ratingStatistics,
    261272            userRating,
     
    302313
    303314export async function setBuildRating(db: Database, userId: number, buildId: number, value: number) {
    304     const result = await db
     315    const [result] = await db
    305316        .insert(ratingBuildsTable)
    306317        .values({
     
    314325                value: value,
    315326            },
    316         });
     327        })
     328        .returning({
     329            userId: ratingBuildsTable.userId,
     330            buildId: ratingBuildsTable.buildId,
     331            value: ratingBuildsTable.value
     332        })
     333
     334    return result;
    317335}
    318336
    319337export async function setBuildReview(db: Database, userId: number,  buildId: number, content: string) {
    320     const existing = await db
    321         .select()
    322         .from(reviewsTable)
    323         .where(
    324             and(
    325                 eq(reviewsTable.userId, userId),
    326                 eq(reviewsTable.buildId, buildId)
    327             )
    328         )
    329         .limit(1);
    330 
    331     if (existing.length) {
    332         const result = await db
    333             .update(reviewsTable)
    334             .set({
    335                 content: content,
    336             })
    337             .where(
    338                 and(
    339                     eq(reviewsTable.userId, userId),
    340                     eq(reviewsTable.buildId, buildId)
    341                 )
    342             );
    343 
    344         return;
    345     }
    346 
    347     const result = await db
     338    const [result] = await db
    348339        .insert(reviewsTable)
    349340        .values({
     
    352343            content,
    353344            createdAt: new Date().toISOString().split('T')[0]
    354         });
     345        })
     346        .onConflictDoUpdate({
     347            target: [reviewsTable.userId, reviewsTable.buildId],
     348            set: {
     349                content: content,
     350                createdAt: new Date().toISOString().split('T')[0]
     351            },
     352        })
     353        .returning({
     354            userId: reviewsTable.userId,
     355            buildId: reviewsTable.buildId,
     356            content: reviewsTable.content,
     357            createdAt: reviewsTable.createdAt
     358        })
     359
     360    return result;
    355361}
    356362
    357363export async function cloneBuild(db: Database, userId: number, buildId: number) {
    358     const [buildToClone] = await db
    359         .select()
    360         .from(buildsTable)
    361         .where(
    362             eq(buildsTable.id, buildId)
    363         )
    364         .limit(1);
    365 
    366     if (!buildToClone) return null;
    367 
    368     const [newBuild] = await db
    369         .insert(buildsTable)
    370         .values({
    371             userId: userId,
    372             name: `${buildToClone.name} (copy)`,
    373             createdAt: new Date().toISOString().split('T')[0],
    374             description: buildToClone.description,
    375             totalPrice: buildToClone.totalPrice,
    376             isApproved: false
    377         })
    378         .returning({ id: buildsTable.id });
    379 
    380     const components = await db
    381         .select()
    382         .from(buildComponentsTable)
    383         .where(
    384             eq(buildComponentsTable.buildId, buildId)
    385         );
    386 
    387     if(components.length) {
    388         await db
    389             .insert(buildComponentsTable)
    390             .values(
    391                 components.map(component => ({
    392                     buildId: newBuild.id,
    393                     componentId: component.componentId
    394                 }))
    395             );
    396     }
    397 
    398     return newBuild.id;
    399 }
     364    return db.transaction(async (tx) => {
     365        const [buildToClone] = await tx
     366            .select({
     367                id: buildsTable.id,
     368                userId: buildsTable.userId,
     369                name: buildsTable.name,
     370                description: buildsTable.description,
     371                totalPrice: buildsTable.totalPrice,
     372            })
     373            .from(buildsTable)
     374            .where(
     375                eq(buildsTable.id, buildId)
     376            )
     377            .limit(1);
     378
     379        if (!buildToClone) return null;
     380
     381        const [newBuild] = await tx
     382            .insert(buildsTable)
     383            .values({
     384                userId: userId,
     385                name: `${buildToClone.name} (copy)`,
     386                createdAt: new Date().toISOString().split('T')[0],
     387                description: buildToClone.description,
     388                totalPrice: buildToClone.totalPrice,
     389                isApproved: false
     390            })
     391            .returning({
     392                id: buildsTable.id
     393            });
     394
     395        const components = await tx
     396            .select()
     397            .from(buildComponentsTable)
     398            .where(
     399                eq(buildComponentsTable.buildId, buildId)
     400            );
     401
     402        if(components.length) {
     403            await tx
     404                .insert(buildComponentsTable)
     405                .values(
     406                    components.map(component => ({
     407                        buildId: newBuild.id,
     408                        componentId: component.componentId
     409                    }))
     410                );
     411        }
     412
     413        const [clonedBuild] = await tx
     414            .select({
     415                id: buildsTable.id,
     416                userId: buildsTable.userId,
     417                name: buildsTable.name,
     418                createdAt: buildsTable.createdAt,
     419                description: buildsTable.description,
     420                totalPrice: buildsTable.totalPrice
     421            })
     422            .from(buildsTable)
     423            .innerJoin(
     424                usersTable,
     425                eq(buildsTable.userId, usersTable.id)
     426            )
     427            .where(
     428                eq(buildsTable.id, newBuild.id)
     429            )
     430            .limit(1);
     431
     432        const clonedComponents = await tx
     433            .select({
     434                componentId: buildComponentsTable.componentId,
     435                component: componentsTable
     436            })
     437            .from(buildComponentsTable)
     438            .innerJoin(
     439                componentsTable,
     440                eq(buildComponentsTable.componentId, componentsTable.id)
     441            )
     442            .where(
     443                eq(buildComponentsTable.buildId, newBuild.id)
     444            );
     445
     446        return {
     447            ...clonedBuild,
     448            components: clonedComponents.map(c => c.component)
     449        };
     450    });
     451}
     452
     453export async function deleteBuild(db: Database, userId: number, buildId: number) {
     454    const result = await db
     455        .delete(buildsTable)
     456        .where(
     457            and(
     458                eq(buildsTable.id, buildId),
     459                eq(buildsTable.userId, userId)
     460            )
     461        )
     462        .returning({
     463            id: buildsTable.id
     464        })
     465
     466    return result.length;
     467}
     468
     469export async function addNewBuild(db: Database, userId: number, name: string, description: string, componentIds: number[]) {
     470    return db.transaction(async (tx) => {
     471        const components = await tx
     472            .select({
     473                price:  componentsTable.price
     474            })
     475            .from(componentsTable)
     476            .where(
     477                inArray(componentsTable.id, componentIds)
     478            );
     479
     480        const totalPrice = components.reduce((sum, c) => sum + Number(c.price), 0);
     481
     482        const [newBuild] = await tx
     483            .insert(buildsTable)
     484            .values({
     485                userId: userId,
     486                name: name,
     487                createdAt: new Date().toISOString().split('T')[0],
     488                description: description,
     489                totalPrice: totalPrice.toFixed(2),
     490                isApproved: false
     491            })
     492            .returning({
     493                id: buildsTable.id
     494            });
     495
     496        if(components.length) {
     497            await tx.insert(buildComponentsTable)
     498                .values(
     499                    componentIds.map(componentId => ({
     500                        buildId: newBuild.id,
     501                        componentId: componentId
     502                    }))
     503                );
     504        }
     505
     506        return newBuild.id;
     507    });
     508}
     509
     510export async function editBuild(db: Database, userId: number, buildId: number, name: string, description: string, componentIds: number[]) {
     511    return db.transaction(async (tx) => {
     512        const [build] = await tx
     513            .select({
     514                id: buildsTable.id,
     515                userId: buildsTable.userId,
     516                isApproved: buildsTable.isApproved
     517            })
     518            .from(buildsTable)
     519            .where(
     520                and(
     521                    eq(buildsTable.id, buildId),
     522                    eq(buildsTable.userId, userId)
     523                )
     524            )
     525            .limit(1);
     526
     527        if (!build) return null;
     528        if (build.isApproved) return null;
     529
     530        const components = await tx
     531            .select({
     532                id: componentsTable.id,
     533                price: componentsTable.price
     534            })
     535            .from(componentsTable)
     536            .where(
     537                inArray(componentsTable.id, componentIds)
     538            );
     539
     540        const totalPrice = components.reduce((sum, c) => sum + Number(c.price), 0);
     541
     542        await tx
     543            .update(buildsTable)
     544            .set({
     545                name: name,
     546                description: description,
     547                totalPrice: totalPrice.toFixed(2),
     548            })
     549            .where(
     550                and(
     551                    eq(buildsTable.id, buildId),
     552                    eq(buildsTable.userId, userId)
     553                )
     554            );
     555
     556        await tx
     557            .delete(buildComponentsTable)
     558            .where(
     559                eq(buildComponentsTable.buildId, buildId)
     560            );
     561
     562        if(components.length) {
     563            await tx.insert(buildComponentsTable)
     564                .values(
     565                    componentIds.map(componentId => ({
     566                        buildId: buildId,
     567                        componentId: componentId
     568                    }))
     569                );
     570        }
     571
     572        return build.id;
     573    });
     574}
Note: See TracChangeset for help on using the changeset viewer.