Changeset 9854393


Ignore:
Timestamp:
12/27/25 02:27:36 (7 months ago)
Author:
Tome <gjorgievtome@…>
Branches:
main
Children:
ad311c3
Parents:
82aa6ae
Message:

implement components query and filtering

Files:
4 edited

Legend:

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

    r82aa6ae r9854393  
    108108export async function getApprovedBuilds(db: Database, limit?: number, sort?: string, q?: string) {
    109109    let queryConditions = [eq(buildsTable.isApproved, true)];
    110     let sortConditions = [];
     110    let sortCondition:any;
    111111
    112112    if (q) {
     
    118118    switch(sort) {
    119119        case 'price_asc':
    120             sortConditions.push(
    121                 asc(buildsTable.totalPrice)
    122             );
     120            sortCondition = asc(buildsTable.totalPrice)
    123121            break;
    124122        case 'price_desc':
    125             sortConditions.push(
    126                 desc(buildsTable.totalPrice)
    127             );
     123            sortCondition = desc(buildsTable.totalPrice)
    128124            break;
    129125        case 'rating_desc':
    130             sortConditions.push(
    131                 desc(sql<number>`COALESCE(AVG(${ratingBuildsTable.value}::float),0)`)
    132             );
     126            sortCondition = desc(sql<number>`COALESCE(AVG(${ratingBuildsTable.value}::float),0)`)
    133127            break;
    134128        case 'oldest':
    135             sortConditions.push(
    136                 asc(buildsTable.createdAt)
    137             );
     129            sortCondition = asc(buildsTable.createdAt)
    138130            break;
    139131        case 'newest':
    140             sortConditions.push(
    141                 desc(buildsTable.createdAt)
    142             );
     132            sortCondition = desc(buildsTable.createdAt)
    143133            break;
    144134        default:
    145             sortConditions.push(
    146                 desc(buildsTable.createdAt)
    147             );
     135            sortCondition = desc(buildsTable.createdAt)
    148136            break;
    149137        }
     
    176164        )
    177165        .orderBy(
    178             ...sortConditions
     166            sortCondition
    179167        )
    180168        .limit(limit || 100); // 100 placeholder
  • database/drizzle/queries/components.ts

    r82aa6ae r9854393  
    1111    ratingBuildsTable, soundCardsTable, storageTable
    1212} from "../schema";
    13 import {and, desc, eq, ilike} from "drizzle-orm";
     13import {and, asc, desc, eq, ilike, SQL, sql} from "drizzle-orm";
    1414import {typeConfigMap, ComponentType} from "../config/componentFieldConfig";
    1515import {AnyPgColumn} from "drizzle-orm/pg-core";
    16 export async function getAllComponents(db: Database, limit?: number, componentType?: string, q?: string) {
     16import {inArray} from "drizzle-orm/sql/expressions/conditions";
     17export async function getAllComponents(db: Database, limit?: number, componentType?: string, sort?: string, q?: string) {
    1718    let queryConditions = [];
     19    let sortConditions = [];
    1820
    1921    if (q) {
     
    2123            ilike(componentsTable.name, `%${q}%`)
    2224        );
     25    }
     26
     27    switch(sort) {
     28        case 'price_asc':
     29            sortConditions.push(
     30                asc(buildsTable.totalPrice)
     31            );
     32            break;
     33        case 'price_desc':
     34            sortConditions.push(
     35                desc(buildsTable.totalPrice)
     36            );
     37            break;
     38        default:
     39            sortConditions.push(
     40                desc(buildsTable.createdAt)
     41            );
     42            break;
    2343    }
    2444
     
    4565        )
    4666        .orderBy(
    47             desc(componentsTable.price)
     67            ...sortConditions
    4868        )
    4969        .limit(limit || 100); // 100 placeholder
     
    213233}
    214234
    215 export async function getCompatibleComponents(db: Database, buildId: number, componentType: string) {
    216     // TO BE IMPLEMENTED
    217     return null;
     235export async function getCompatibleComponents(db: Database, buildId: number, componentType: string, limit?: number, sort?: string) {
     236    let sortCondition: any;
     237
     238    switch(sort) {
     239        case 'price_asc':
     240            sortCondition = asc(componentsTable.price);
     241            break;
     242        case 'price_desc':
     243            sortCondition = desc(componentsTable.price);
     244            break;
     245        default:
     246            sortCondition = desc(componentsTable.price);
     247            break;
     248    }
     249
     250    const existingComponents = await getBuildComponents(db, buildId);
     251
     252    if(!existingComponents) return null;
     253
     254    const existing = {
     255        cpu: existingComponents.find(c => c.type === 'cpu'),
     256        motherboard: existingComponents.find(c => c.type === 'motherboard'),
     257        case: existingComponents.find(c => c.type === 'case'),
     258        cooler: existingComponents.find(c => c.type === 'cooler'),
     259        psu: existingComponents.find(c => c.type === 'power_supply'),
     260        gpu: existingComponents.find(c => c.type === 'gpu'),
     261        memory: existingComponents.filter(c => c.type === 'memory'),
     262        storage: existingComponents.filter(c => c.type === 'storage'),
     263        networkCards: existingComponents.filter(c => c.type === 'network_card'),
     264        networkAdapters: existingComponents.filter(c => c.type === 'network_adapter'),
     265        soundCards: existingComponents.filter(c => c.type === 'sound_card'),
     266    };
     267
     268    const pciExpressSlotsUsed = [
     269        existing.gpu,
     270        ...existing.networkCards,
     271        ...existing.networkAdapters,
     272        ...existing.soundCards
     273    ].filter(Boolean).length;
     274
     275    const existingTDP = existingComponents.reduce((sum, c) => {
     276        const tdp = c.details?.tdp ? Number(c.details.tdp) : 0;
     277        return sum + tdp;
     278    }, 0);
     279
     280
     281    let compatibleComponents: any[] = [];
     282
     283    switch (componentType) {
     284        case 'cpu':
     285            compatibleComponents = await getCompatibleCPUs(db, existing, limit, sortCondition);
     286            break;
     287        case 'motherboard':
     288            compatibleComponents = await getCompatibleMotherboards(db, existing, pciExpressSlotsUsed, limit, sortCondition);
     289            break;
     290        case 'cooler':
     291            compatibleComponents = await getCompatibleCoolers(db, existing, limit, sortCondition);
     292            break;
     293        case 'gpu':
     294            compatibleComponents = await getCompatibleGPUs(db, existing, pciExpressSlotsUsed, limit, sortCondition);
     295            break;
     296        case 'memory':
     297            compatibleComponents = await getCompatibleMemory(db, existing, limit, sortCondition);
     298            break;
     299        case 'storage':
     300            compatibleComponents = await getCompatibleStorage(db, existing, limit, sortCondition);
     301            break;
     302        case 'case':
     303            compatibleComponents = await getCompatibleCases(db, existing, limit, sortCondition);
     304            break;
     305        case 'power_supply':
     306            compatibleComponents = await getCompatiblePSUs(db, existing, existingTDP, limit, sortCondition);
     307            break;
     308        case 'network_card':
     309        case 'network_adapter':
     310        case 'sound_card':
     311            compatibleComponents = await getCompatiblePCIeComponents(db, existing, componentType, pciExpressSlotsUsed, limit, sortCondition);
     312            break;
     313        default:
     314            compatibleComponents = [];
     315    }
     316
     317    if(compatibleComponents.length === 0) return null;
     318
     319    return compatibleComponents;
     320}
     321
     322
     323// Helper functions for checking component-specific compatibility
     324async function getCompatibleCPUs(db: Database, existing: any, limit?: number, sortCondition?: any) {
     325    const conditions = [eq(componentsTable.type, 'cpu')];
     326
     327    if (existing.motherboard) {
     328        conditions.push(
     329            eq(CPUTable.socket, existing.motherboard.details.socket)
     330        );
     331    }
     332
     333    if (existing.cooler) {
     334        conditions.push(
     335            sql`${CPUTable.tdp} <= ${existing.cooler.details.maxTdpSupported}`
     336        );
     337    }
     338
     339    const cpus = await db
     340        .select({
     341            id: componentsTable.id,
     342            name: componentsTable.name,
     343            brand: componentsTable.brand,
     344            price: componentsTable.price,
     345            imgUrl: componentsTable.imgUrl,
     346            type: componentsTable.type,
     347            socket: CPUTable.socket,
     348            cores: CPUTable.cores,
     349            threads: CPUTable.threads,
     350            baseClock: CPUTable.baseClock,
     351            boostClock: CPUTable.boostClock,
     352            tdp: CPUTable.tdp,
     353        })
     354        .from(componentsTable)
     355        .innerJoin(
     356            CPUTable,
     357            eq(componentsTable.id, CPUTable.componentId)
     358        )
     359        .where(
     360            and(
     361                ...conditions
     362            )
     363        )
     364        .orderBy(
     365            sortCondition
     366        )
     367        .limit(limit || 100);
     368
     369    if (existing.cooler?.details?.cpuSockets) {
     370        const coolerSockets = existing.cooler.details.cpuSockets.map((s: any) => s.socket);
     371        return cpus.filter(cpu => coolerSockets.includes(cpu.socket));
     372    }
     373
     374    return cpus;
     375}
     376
     377async function getCompatibleMotherboards(db: Database, existing: any, pciExpressSlotsUsed: number, limit?: number, sortCondition?: any) {
     378    const conditions = [eq(componentsTable.type, 'motherboard')];
     379
     380    if (existing.cpu) {
     381        conditions.push(
     382            eq(motherboardsTable.socket, existing.cpu.details.socket)
     383        );
     384    }
     385
     386    if (existing.memory.length > 0) {
     387        const ramType = existing.memory[0].details.type;
     388        conditions.push(
     389            eq(motherboardsTable.ramType, ramType)
     390        );
     391    }
     392
     393    if (pciExpressSlotsUsed > 0) {
     394        conditions.push(
     395            sql`${motherboardsTable.pciExpressSlots} >= ${pciExpressSlotsUsed}`
     396        );
     397    }
     398
     399    const motherboards = await db
     400        .select({
     401            id: componentsTable.id,
     402            name: componentsTable.name,
     403            brand: componentsTable.brand,
     404            price: componentsTable.price,
     405            imgUrl: componentsTable.imgUrl,
     406            type: componentsTable.type,
     407            socket: motherboardsTable.socket,
     408            chipset: motherboardsTable.chipset,
     409            formFactor: motherboardsTable.formFactor,
     410            ramType: motherboardsTable.ramType,
     411            numRamSlots: motherboardsTable.numRamSlots,
     412            maxRamCapacity: motherboardsTable.maxRamCapacity,
     413            pciExpressSlots: motherboardsTable.pciExpressSlots,
     414        })
     415        .from(componentsTable)
     416        .innerJoin(
     417            motherboardsTable,
     418            eq(componentsTable.id, motherboardsTable.componentId)
     419        )
     420        .where(
     421            and(
     422                ...conditions
     423            )
     424        )
     425        .orderBy(
     426            sortCondition
     427        )
     428        .limit(limit || 100);
     429
     430    const compatibleMotherboards = motherboards.filter(mobo => {
     431        if (existing.memory.length > 0) {
     432            const totalModules = existing.memory.reduce((sum: number, m: any) =>
     433                sum + Number(m.details.modules), 0
     434            );
     435            const totalCapacity = existing.memory.reduce((sum: number, m: any) =>
     436                sum + Number(m.details.capacity), 0
     437            );
     438
     439            if (totalModules > Number(mobo.numRamSlots)) return false;
     440            if (totalCapacity > Number(mobo.maxRamCapacity)) return false;
     441        }
     442
     443        return true;
     444    });
     445
     446    if (existing.case?.details?.moboFormFactors) {
     447        const caseFormFactors = existing.case.details.moboFormFactors.map((f: any) => f.formFactor);
     448        return compatibleMotherboards.filter(mobo => caseFormFactors.includes(mobo.formFactor));
     449    }
     450
     451    return compatibleMotherboards;
     452}
     453
     454async function getCompatibleCoolers(db: Database, existing: any, limit?: number, sortCondition?: any) {
     455    const conditions = [eq(componentsTable.type, 'cooler')];
     456
     457    if (existing.cpu) {
     458        conditions.push(
     459            sql`${coolersTable.maxTdpSupported} >= ${existing.cpu.details.tdp}`
     460        );
     461    }
     462
     463    if (existing.case) {
     464        conditions.push(
     465            sql`${coolersTable.height} <= ${existing.case.details.coolerMaxHeight}`
     466        );
     467    }
     468
     469    const coolers = await db
     470        .select({
     471            id: componentsTable.id,
     472            name: componentsTable.name,
     473            brand: componentsTable.brand,
     474            price: componentsTable.price,
     475            imgUrl: componentsTable.imgUrl,
     476            type: componentsTable.type,
     477            coolerType: coolersTable.type,
     478            height: coolersTable.height,
     479            maxTdpSupported: coolersTable.maxTdpSupported,
     480        })
     481        .from(componentsTable)
     482        .innerJoin(
     483            coolersTable,
     484            eq(componentsTable.id, coolersTable.componentId)
     485        )
     486        .where(
     487            and(
     488                ...conditions
     489            )
     490        )
     491        .orderBy(
     492            sortCondition
     493        )
     494        .limit(limit || 100);
     495
     496
     497    if(existing.cpu && coolers.length > 0) {
     498        const coolerIds = coolers.map(c => c.id);
     499
     500        const allSockets = await db
     501            .select({
     502                coolerId: coolerCPUSocketsTable.coolerId,
     503                socket: coolerCPUSocketsTable.socket
     504            })
     505            .from(coolerCPUSocketsTable)
     506            .where(
     507                inArray(coolerCPUSocketsTable.coolerId, coolerIds)
     508            );
     509        const socketsByCooler = allSockets.reduce((acc, { coolerId, socket }) => {
     510            if (!acc[coolerId]) acc[coolerId] = [];
     511            acc[coolerId].push(socket);
     512            return acc;
     513        }, {} as Record<number, string[]>);
     514
     515        return coolers.filter(cooler => {
     516            const sockets = socketsByCooler[cooler.id] || [];
     517            return sockets.includes(existing.cpu.details.socket);
     518        });
     519    }
     520
     521    return coolers;
     522}
     523
     524async function getCompatibleGPUs(db: Database, existing: any, pciExpressSlotsUsed: number, limit?: number, sortCondition?: any) {
     525    const conditions = [eq(componentsTable.type, 'gpu')];
     526
     527    if (existing.case) {
     528        conditions.push(
     529            sql`${GPUTable.length} <= ${existing.case.details.gpuMaxLength}`
     530        );
     531    }
     532
     533    const gpus = await db
     534        .select({
     535            id: componentsTable.id,
     536            name: componentsTable.name,
     537            brand: componentsTable.brand,
     538            price: componentsTable.price,
     539            imgUrl: componentsTable.imgUrl,
     540            type: componentsTable.type,
     541            vram: GPUTable.vram,
     542            tdp: GPUTable.tdp,
     543            baseClock: GPUTable.baseClock,
     544            boostClock: GPUTable.boostClock,
     545            chipset: GPUTable.chipset,
     546            length: GPUTable.length,
     547        })
     548        .from(componentsTable)
     549        .innerJoin(
     550            GPUTable,
     551            eq(componentsTable.id, GPUTable.componentId)
     552        )
     553        .where(
     554            and(
     555                ...conditions
     556            )
     557        )
     558        .orderBy(
     559            sortCondition
     560        )
     561        .limit(limit || 100);
     562
     563    if (existing.motherboard) {
     564        const availableSlots = Number(existing.motherboard.details.pciExpressSlots);
     565        return gpus.filter(() => (pciExpressSlotsUsed + 1) <= availableSlots);
     566    }
     567
     568    return gpus;
     569}
     570
     571async function getCompatibleMemory(db: Database, existing: any, limit?: number, sortCondition?: any) {
     572    const conditions = [eq(componentsTable.type, 'memory')];
     573
     574    if (existing.motherboard) {
     575        conditions.push(
     576            eq(memoryTable.type, existing.motherboard.details.ramType)
     577        );
     578    }
     579
     580    const memory = await db
     581        .select({
     582            id: componentsTable.id,
     583            name: componentsTable.name,
     584            brand: componentsTable.brand,
     585            price: componentsTable.price,
     586            imgUrl: componentsTable.imgUrl,
     587            type: componentsTable.type,
     588            memoryType: memoryTable.type,
     589            speed: memoryTable.speed,
     590            capacity: memoryTable.capacity,
     591            modules: memoryTable.modules,
     592        })
     593        .from(componentsTable)
     594        .innerJoin(
     595            memoryTable,
     596            eq(componentsTable.id, memoryTable.componentId)
     597        )
     598        .where(
     599            and(
     600                ...conditions
     601            )
     602        )
     603        .orderBy(
     604            sortCondition
     605        )
     606        .limit(limit || 100);
     607
     608    if (existing.motherboard) {
     609        const existingModules = existing.memory.reduce((sum: number, m: any) =>
     610            sum + Number(m.details.modules), 0
     611        );
     612        const existingCapacity = existing.memory.reduce((sum: number, m: any) =>
     613            sum + Number(m.details.capacity), 0
     614        );
     615        const maxSlots = Number(existing.motherboard.details.numRamSlots);
     616        const maxCapacity = Number(existing.motherboard.details.maxRamCapacity);
     617
     618        return memory.filter(mem => {
     619            const newModules = existingModules + Number(mem.modules);
     620            const newCapacity = existingCapacity + Number(mem.capacity);
     621            return newModules <= maxSlots && newCapacity <= maxCapacity;
     622        });
     623    }
     624
     625    return memory;
     626}
     627
     628async function getCompatibleStorage(db: Database, existing: any, limit?: number, sortCondition?: any) {
     629    const storage = await db
     630        .select({
     631            id: componentsTable.id,
     632            name: componentsTable.name,
     633            brand: componentsTable.brand,
     634            price: componentsTable.price,
     635            imgUrl: componentsTable.imgUrl,
     636            type: componentsTable.type,
     637            storageType: storageTable.type,
     638            capacity: storageTable.capacity,
     639            formFactor: storageTable.formFactor,
     640        })
     641        .from(componentsTable)
     642        .innerJoin(
     643            storageTable,
     644            eq(componentsTable.id, storageTable.componentId
     645            )
     646        )
     647        .where(
     648            eq(componentsTable.type, 'storage')
     649        )
     650        .orderBy(
     651            sortCondition
     652        )
     653        .limit(limit || 100);
     654
     655    if (existing.case?.details?.storageFormFactors) {
     656        return storage.filter(stor => {
     657            const caseStorageFormFactor = existing.case.details.storageFormFactors.find(
     658                (sf: any) => sf.formFactor === stor.formFactor
     659            );
     660
     661            if (!caseStorageFormFactor) return false;
     662
     663            const usedSlots = existing.storage.filter(
     664                (s: any) => s.details.formFactor === stor.formFactor
     665            ).length;
     666
     667            return usedSlots < Number(caseStorageFormFactor.numSlots);
     668        });
     669    }
     670
     671    return storage;
     672}
     673
     674async function getCompatibleCases(db: Database, existing: any, limit?: number, sortCondition?: any) {
     675    const conditions = [eq(componentsTable.type, 'case')];
     676
     677    if (existing.gpu) {
     678        conditions.push(
     679            sql`${pcCasesTable.gpuMaxLength} >= ${existing.gpu.details.length}`
     680        );
     681    }
     682
     683    if (existing.cooler) {
     684        conditions.push(
     685            sql`${pcCasesTable.coolerMaxHeight} >= ${existing.cooler.details.height}`
     686        );
     687    }
     688
     689    const cases = await db
     690        .select({
     691            id: componentsTable.id,
     692            name: componentsTable.name,
     693            brand: componentsTable.brand,
     694            price: componentsTable.price,
     695            imgUrl: componentsTable.imgUrl,
     696            type: componentsTable.type,
     697            coolerMaxHeight: pcCasesTable.coolerMaxHeight,
     698            gpuMaxLength: pcCasesTable.gpuMaxLength,
     699        })
     700        .from(componentsTable)
     701        .innerJoin(
     702            pcCasesTable,
     703            eq(componentsTable.id, pcCasesTable.componentId)
     704        )
     705        .where(
     706            and(
     707                ...conditions)
     708        )
     709        .orderBy(
     710            sortCondition
     711        )
     712        .limit(limit || 100);
     713
     714    if(cases.length === 0) return [];
     715
     716    const caseIds = cases.map(c => c.id);
     717
     718    const [allStorageFF, allPsFF, allMoboFF] = await Promise.all([
     719        db.select().from(caseStorageFormFactorsTable)
     720            .where(
     721                inArray(caseStorageFormFactorsTable.caseId, caseIds)
     722            ),
     723        db.select().from(casePsFormFactorsTable)
     724            .where(
     725                inArray(casePsFormFactorsTable.caseId, caseIds)
     726            ),
     727        db.select().from(caseMoboFormFactorsTable)
     728            .where(
     729                inArray(caseMoboFormFactorsTable.caseId, caseIds)
     730            )
     731    ]);
     732
     733    const storageByCase = allStorageFF.reduce((acc, ff) => {
     734        if (!acc[ff.caseId]) acc[ff.caseId] = [];
     735        acc[ff.caseId].push(ff);
     736        return acc;
     737    }, {} as Record<number, any[]>);
     738
     739    const psByCase = allPsFF.reduce((acc, ff) => {
     740        if (!acc[ff.caseId]) acc[ff.caseId] = [];
     741        acc[ff.caseId].push(ff);
     742        return acc;
     743    }, {} as Record<number, any[]>);
     744
     745    const moboByCase = allMoboFF.reduce((acc, ff) => {
     746        if (!acc[ff.caseId]) acc[ff.caseId] = [];
     747        acc[ff.caseId].push(ff);
     748        return acc;
     749    }, {} as Record<number, any[]>);
     750
     751    const casesWithDetails = cases.map(pcCase => ({
     752        ...pcCase,
     753        storageFormFactors: storageByCase[pcCase.id] || [],
     754        psFormFactors: psByCase[pcCase.id] || [],
     755        moboFormFactors: moboByCase[pcCase.id] || []
     756    }));
     757
     758    let filteredCases = casesWithDetails;
     759
     760    if (existing.motherboard) {
     761        filteredCases = filteredCases.filter(pcCase =>
     762            pcCase.moboFormFactors.some((f: any) => f.formFactor === existing.motherboard.details.formFactor)
     763        );
     764    }
     765
     766    if (existing.psu) {
     767        filteredCases = filteredCases.filter(pcCase =>
     768            pcCase.psFormFactors.some((f: any) => f.formFactor === existing.psu.details.formFactor)
     769        );
     770    }
     771
     772    if (existing.storage.length > 0) {
     773        filteredCases = filteredCases.filter(pcCase => {
     774            return existing.storage.every((stor: any) => {
     775                const storageFF = pcCase.storageFormFactors.find(
     776                    (sf: any) => sf.formFactor === stor.details.formFactor
     777                );
     778                if (!storageFF) return false;
     779
     780                const usedSlots = existing.storage.filter(
     781                    (s: any) => s.details.formFactor === stor.details.formFactor
     782                ).length;
     783
     784                return usedSlots <= Number(storageFF.numSlots);
     785            });
     786        });
     787    }
     788
     789    return filteredCases;
     790}
     791
     792async function getCompatiblePSUs(db: Database, existing: any, existingTDP: number, limit?: number, sortCondition?: any) {
     793    const conditions = [eq(componentsTable.type, 'power_supply')];
     794
     795    const minWattage = existingTDP * 1.2;
     796    conditions.push(
     797        sql`${powerSupplyTable.wattage} >= ${minWattage}`
     798    );
     799
     800    const psus = await db
     801        .select({
     802            id: componentsTable.id,
     803            name: componentsTable.name,
     804            brand: componentsTable.brand,
     805            price: componentsTable.price,
     806            imgUrl: componentsTable.imgUrl,
     807            type: componentsTable.type,
     808            psuType: powerSupplyTable.type,
     809            wattage: powerSupplyTable.wattage,
     810            formFactor: powerSupplyTable.formFactor,
     811        })
     812        .from(componentsTable)
     813        .innerJoin(
     814            powerSupplyTable,
     815            eq(componentsTable.id, powerSupplyTable.componentId)
     816        )
     817        .where(
     818            and(
     819                ...conditions
     820            )
     821        )
     822        .orderBy(
     823            sortCondition
     824        )
     825        .limit(limit || 100);
     826
     827    if (existing.case?.details?.psFormFactors) {
     828        const casePSFormFactors = existing.case.details.psFormFactors.map((f: any) => f.formFactor);
     829        return psus.filter(psu => casePSFormFactors.includes(psu.formFactor));
     830    }
     831
     832    return psus;
     833}
     834
     835async function getCompatiblePCIeComponents(db: Database, existing: any, componentType: string, pciExpressSlotsUsed: number, limit?: number, sortCondition?: any) {
     836    let table: any;
     837    let selectFields: any = {
     838        id: componentsTable.id,
     839        name: componentsTable.name,
     840        brand: componentsTable.brand,
     841        price: componentsTable.price,
     842        imgUrl: componentsTable.imgUrl,
     843        type: componentsTable.type,
     844    };
     845
     846    switch (componentType) {
     847        case 'network_card':
     848            table = networkCardsTable;
     849            selectFields = {
     850                ...selectFields,
     851                numPorts: networkCardsTable.numPorts,
     852                speed: networkCardsTable.speed,
     853                interface: networkCardsTable.interface,
     854            };
     855            break;
     856        case 'network_adapter':
     857            table = networkAdaptersTable;
     858            selectFields = {
     859                ...selectFields,
     860                wifiVersion: networkAdaptersTable.wifiVersion,
     861                interface: networkAdaptersTable.interface,
     862                numAntennas: networkAdaptersTable.numAntennas,
     863            };
     864            break;
     865        case 'sound_card':
     866            table = soundCardsTable;
     867            selectFields = {
     868                ...selectFields,
     869                sampleRate: soundCardsTable.sampleRate,
     870                bitDepth: soundCardsTable.bitDepth,
     871                chipset: soundCardsTable.chipset,
     872                interface: soundCardsTable.interface,
     873                channel: soundCardsTable.channel,
     874            };
     875            break;
     876        default:
     877            return [];
     878    }
     879
     880    const components = await db
     881        .select(selectFields)
     882        .from(componentsTable)
     883        .innerJoin(
     884            table,
     885            eq(componentsTable.id, table.componentId)
     886        )
     887        .where(
     888            eq(componentsTable.type, componentType)
     889        )
     890        .orderBy(
     891            sortCondition
     892        )
     893        .limit(limit || 100);
     894
     895    if (existing.motherboard) {
     896        const availableSlots = Number(existing.motherboard.details.pciExpressSlots);
     897        return components.filter(() => (pciExpressSlotsUsed + 1) <= availableSlots);
     898    }
     899
     900    return components;
    218901}
    219902
  • pages/+Layout.telefunc.ts

    r82aa6ae r9854393  
    1010}
    1111
    12 export async function onGetAllComponents({ componentType, limit, q }
    13                                             : { componentType?: string; limit?: number; q?: string }) {
     12export async function onGetAllComponents({ componentType, limit, sort, q }
     13                                            : { componentType?: string; limit?: number; sort?: string, q?: string }) {
    1414    const c = ctx();
    1515
    16     const components = await drizzleQueries.getAllComponents(c.db, limit, componentType, q);
     16    const components = await drizzleQueries.getAllComponents(c.db, limit, componentType, sort, q);
    1717
    1818    return components;
  • pages/forge/forge.telefunc.ts

    r82aa6ae r9854393  
    6262}
    6363
    64 export async function onGetCompatibleComponents({ buildId, componentType }: { buildId: number, componentType: string }) {
     64export async function onGetCompatibleComponents({ buildId, componentType, limit, sort }
     65                                                : { db: Database, buildId: number, componentType: string, limit?: number, sort?: string }) {
    6566    const { c, userId } = requireUser()
    6667
    6768    if(!Number.isInteger(buildId) || buildId <= 0) throw Abort();
    6869
    69     const compatibleComponents = await drizzleQueries.getCompatibleComponents(c.db, buildId, componentType);
     70    const compatibleComponents = await drizzleQueries.getCompatibleComponents(c.db, buildId, componentType, limit, sort);
    7071
    7172    if(!compatibleComponents) throw Abort();
Note: See TracChangeset for help on using the changeset viewer.