source: database/drizzle/queries/components.ts@ 82aa6ae

main
Last change on this file since 82aa6ae was e7f1bfa, checked in by Tome <gjorgievtome@…>, 7 months ago

implement forge features

  • Property mode set to 100644
File size: 10.0 KB
RevLine 
[1ebac59]1import type { Database } from "../db";
[ea09e98]2import {
[83fb5e2]3 buildComponentsTable,
[ea09e98]4 buildsTable, cablesTable, caseMoboFormFactorsTable, casePsFormFactorsTable, caseStorageFormFactorsTable,
5 componentsTable, coolerCPUSocketsTable, coolersTable,
6 CPUTable,
7 GPUTable, memoryCardsTable,
8 memoryTable, motherboardsTable,
9 networkAdaptersTable,
[83fb5e2]10 networkCardsTable, opticalDrivesTable, pcCasesTable, powerSupplyTable,
11 ratingBuildsTable, soundCardsTable, storageTable
[ea09e98]12} from "../schema";
[c4dd17d]13import {and, desc, eq, ilike} from "drizzle-orm";
[e7f1bfa]14import {typeConfigMap, ComponentType} from "../config/componentFieldConfig";
15import {AnyPgColumn} from "drizzle-orm/pg-core";
[83fb5e2]16export async function getAllComponents(db: Database, limit?: number, componentType?: string, q?: string) {
[c4dd17d]17 let queryConditions = [];
[1ebac59]18
[c4dd17d]19 if (q) {
20 queryConditions.push(
21 ilike(componentsTable.name, `%${q}%`)
22 );
23 }
24
25 if(componentType && componentType.trim() !== 'all') {
26 queryConditions.push(
27 eq(componentsTable.type, componentType.trim().toLowerCase())
28 );
29 }
[1ebac59]30
[e7f1bfa]31 const components = await db
[c4dd17d]32 .select({
33 id: componentsTable.id,
34 name: componentsTable.name,
35 brand: componentsTable.brand,
36 price: componentsTable.price,
37 })
38 .from(componentsTable)
39 .where(
40 queryConditions.length > 0 ?
41 and (
42 ...queryConditions
43 )
44 : undefined
45 )
46 .orderBy(
47 desc(componentsTable.price)
48 )
49 .limit(limit || 100); // 100 placeholder
[1ebac59]50
[e7f1bfa]51 return components;
[1ebac59]52}
53
[c4dd17d]54export async function getComponentDetails(db: Database, componentId: number) {
[ea09e98]55 const [component] = await db
[c4dd17d]56 .select()
57 .from(componentsTable)
58 .where(
59 eq(componentsTable.id, componentId)
60 )
61 .limit(1);
[1ebac59]62
[ea09e98]63 if(!component) return null;
64
[e7f1bfa]65 const config = typeConfigMap[component.type as ComponentType];
[ea09e98]66
[e7f1bfa]67 const [details] = await db
68 .select()
69 .from(config.table)
70 .where(
71 eq(config.table.componentId, componentId)
72 )
73 .limit(1);
74
75 if (component.type === 'case') {
76 details.storageFormFactors = await db.select().from(caseStorageFormFactorsTable).where(eq(caseStorageFormFactorsTable.caseId, componentId));
77 details.psFormFactors = await db.select().from(casePsFormFactorsTable).where(eq(casePsFormFactorsTable.caseId, componentId));
78 details.moboFormFactors = await db.select().from(caseMoboFormFactorsTable).where(eq(caseMoboFormFactorsTable.caseId, componentId));
79 }
80
81 if (component.type === 'cooler') {
82 details.cpuSockets = await db.select().from(coolerCPUSocketsTable).where(eq(coolerCPUSocketsTable.coolerId, componentId));
[ea09e98]83 }
84
85 return {
86 ...component,
[e7f1bfa]87 details: details
[ea09e98]88 };
89}
90
91export async function addNewComponent(db: Database, name: string, brand: string, price: number, imgUrl: string, type: string, specificData: any) {
92 return db.transaction(async (tx) => {
93 const [newComponent] = await tx
94 .insert(componentsTable)
95 .values({
96 name: name,
97 brand: brand,
98 price: price.toFixed(2),
99 imgUrl: imgUrl,
100 type: type
101 })
102 .returning({
103 id: componentsTable.id
104 });
105
106 const componentId = newComponent.id;
107
[e7f1bfa]108 const config = typeConfigMap[type as ComponentType];
[ea09e98]109
[e7f1bfa]110 await tx
111 .insert(config.table)
112 .values({
113 componentId: componentId,
114 ...specificData
115 });
[ea09e98]116
[e7f1bfa]117 if (type === 'case') {
118 if (specificData.storageFormFactors) {
119 await tx.insert(caseStorageFormFactorsTable).values(
120 specificData.storageFormFactors.map((sf: any) => ({
121 caseId: componentId,
122 formFactor: sf.formFactor,
123 numSlots: sf.numSlots,
124 }))
125 );
126 }
127 if (specificData.psFormFactors) {
128 await tx.insert(casePsFormFactorsTable).values(
129 specificData.psFormFactors.map((pf: any) => ({
130 caseId: componentId,
131 formFactor: pf.formFactor,
132 }))
133 );
134 }
135 if (specificData.moboFormFactors) {
136 await tx.insert(caseMoboFormFactorsTable).values(
137 specificData.moboFormFactors.map((mf: any) => ({
138 caseId: componentId,
139 formFactor: mf.formFactor,
140 }))
141 );
142 }
143 }
[ea09e98]144
[e7f1bfa]145 if (type === 'cooler' && specificData.cpuSockets) {
146 await tx.insert(coolerCPUSocketsTable).values(
147 specificData.cpuSockets.map((socket: any) => ({ coolerId: componentId, socket }))
148 );
149 }
[ea09e98]150
[e7f1bfa]151 return componentId;
152 });
153}
[ea09e98]154
[e7f1bfa]155export async function getBuildComponents(db: Database, buildId: number) {
156 const [build] = await db
157 .select({
158 buildId: buildsTable.id,
159 userId: buildsTable.userId,
160 })
161 .from(buildsTable)
162 .where(
163 eq(buildsTable.id, buildId)
164 )
165 .limit(1);
[ea09e98]166
[e7f1bfa]167 if(!build) return null;
[ea09e98]168
[e7f1bfa]169 const components = await db
170 .select({
171 id: componentsTable.id,
172 type: componentsTable.type,
173 })
174 .from(buildComponentsTable)
175 .where(
176 eq(buildComponentsTable.buildId, buildId)
177 )
178 .innerJoin(
179 componentsTable,
180 eq(buildComponentsTable.componentId, componentsTable.id)
181 );
[ea09e98]182
[e7f1bfa]183 const componentsDetails = [];
[ea09e98]184
[e7f1bfa]185 for (const comp of components) {
186 const config = typeConfigMap[comp.type as ComponentType];
[ea09e98]187
[e7f1bfa]188 const [details] = await db
189 .select()
190 .from(config.table)
191 .where(
192 eq(config.table.componentId, comp.id)
193 )
194 .limit(1);
[ea09e98]195
[e7f1bfa]196 if (comp.type === 'case') {
197 details.storageFormFactors = await db.select().from(caseStorageFormFactorsTable).where(eq(caseStorageFormFactorsTable.caseId, comp.id));
198 details.psFormFactors = await db.select().from(casePsFormFactorsTable).where(eq(casePsFormFactorsTable.caseId, comp.id));
199 details.moboFormFactors = await db.select().from(caseMoboFormFactorsTable).where(eq(caseMoboFormFactorsTable.caseId, comp.id));
200 }
[ea09e98]201
[e7f1bfa]202 if (comp.type === 'cooler') {
203 details.cpuSockets = await db.select().from(coolerCPUSocketsTable).where(eq(coolerCPUSocketsTable.coolerId, comp.id));
[ea09e98]204 }
205
[e7f1bfa]206 componentsDetails.push({
207 ...comp,
208 details: details
209 });
210 }
211
212 return componentsDetails;
[83fb5e2]213}
214
215export async function getCompatibleComponents(db: Database, buildId: number, componentType: string) {
[e7f1bfa]216 // TO BE IMPLEMENTED
[83fb5e2]217 return null;
218}
219
220export async function addComponentToBuild(db: Database, buildId: number, componentId: number) {
221 const [build] = await db
222 .select()
223 .from(buildsTable)
224 .where(
225 eq(buildsTable.id, buildId)
226 )
227 .limit(1);
228
229 if(!build) return null;
230
231 const [component] = await db
232 .select()
233 .from(componentsTable)
234 .where(
235 eq(componentsTable.id, componentId)
236 )
237 .limit(1);
238
239 if(!component) return null;
240
241 const existing = await db
242 .select()
243 .from(buildComponentsTable)
244 .where(
245 and(
246 eq(buildComponentsTable.buildId, buildId),
247 eq(buildComponentsTable.componentId, componentId)
248 )
249 )
250 .limit(1);
251
252 if(existing.length > 0) return null;
253
254 const [result] = await db
255 .insert(buildComponentsTable)
256 .values({
257 buildId,
258 componentId
259 })
260 .returning({
261 id: buildComponentsTable.buildId
262 });
263
264 const buildComponents = await db
265 .select({
266 price: componentsTable.price,
267 })
268 .from(buildComponentsTable)
269 .innerJoin(
270 componentsTable,
271 eq(buildComponentsTable.componentId, componentsTable.id)
272 )
273 .where(
274 eq(buildComponentsTable.buildId, buildId)
275 );
276
277 const totalPrice = buildComponents.reduce((sum, c) => sum + Number(c.price), 0);
278
279 await db
280 .update(buildsTable)
281 .set({
282 totalPrice: totalPrice.toFixed(2)
283 })
284 .where(
285 eq(buildsTable.id, buildId)
286 );
287
288 return result?.id ?? null;
289}
290
291export async function removeComponentFromBuild(db: Database, buildId: number, componentId: number) {
292 const [build] = await db
293 .select()
294 .from(buildsTable)
295 .where(
296 eq(buildsTable.id, buildId)
297 )
298 .limit(1);
299
300 if(!build) return null;
301
302 const [component] = await db
303 .select()
304 .from(componentsTable)
305 .where(
306 eq(componentsTable.id, componentId)
307 )
308 .limit(1);
309
310 if(!component) return null;
311
312 const result = await db
313 .delete(buildComponentsTable)
314 .where(
315 and(
316 eq(buildComponentsTable.buildId, buildId),
317 eq(buildComponentsTable.componentId, componentId)
318 )
319 );
320
321 if(result.rowCount === 0) return null;
322
323 const buildComponents = await db
324 .select({
325 price: componentsTable.price,
326 })
327 .from(buildComponentsTable)
328 .innerJoin(
329 componentsTable,
330 eq(buildComponentsTable.componentId, componentsTable.id)
331 )
332 .where(
333 eq(buildComponentsTable.buildId, buildId)
334 );
335
336 const totalPrice = buildComponents.reduce((sum, c) => sum + Number(c.price), 0);
337
338 await db
339 .update(buildsTable)
340 .set({
341 totalPrice: totalPrice.toFixed(2)
342 })
343 .where(
344 eq(buildsTable.id, buildId)
345 );
346
347 return result;
348}
349
Note: See TracBrowser for help on using the repository browser.