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
Line 
1import type { Database } from "../db";
2import {
3 buildComponentsTable,
4 buildsTable, cablesTable, caseMoboFormFactorsTable, casePsFormFactorsTable, caseStorageFormFactorsTable,
5 componentsTable, coolerCPUSocketsTable, coolersTable,
6 CPUTable,
7 GPUTable, memoryCardsTable,
8 memoryTable, motherboardsTable,
9 networkAdaptersTable,
10 networkCardsTable, opticalDrivesTable, pcCasesTable, powerSupplyTable,
11 ratingBuildsTable, soundCardsTable, storageTable
12} from "../schema";
13import {and, desc, eq, ilike} from "drizzle-orm";
14import {typeConfigMap, ComponentType} from "../config/componentFieldConfig";
15import {AnyPgColumn} from "drizzle-orm/pg-core";
16export async function getAllComponents(db: Database, limit?: number, componentType?: string, q?: string) {
17 let queryConditions = [];
18
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 }
30
31 const components = await db
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
50
51 return components;
52}
53
54export async function getComponentDetails(db: Database, componentId: number) {
55 const [component] = await db
56 .select()
57 .from(componentsTable)
58 .where(
59 eq(componentsTable.id, componentId)
60 )
61 .limit(1);
62
63 if(!component) return null;
64
65 const config = typeConfigMap[component.type as ComponentType];
66
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));
83 }
84
85 return {
86 ...component,
87 details: details
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
108 const config = typeConfigMap[type as ComponentType];
109
110 await tx
111 .insert(config.table)
112 .values({
113 componentId: componentId,
114 ...specificData
115 });
116
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 }
144
145 if (type === 'cooler' && specificData.cpuSockets) {
146 await tx.insert(coolerCPUSocketsTable).values(
147 specificData.cpuSockets.map((socket: any) => ({ coolerId: componentId, socket }))
148 );
149 }
150
151 return componentId;
152 });
153}
154
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);
166
167 if(!build) return null;
168
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 );
182
183 const componentsDetails = [];
184
185 for (const comp of components) {
186 const config = typeConfigMap[comp.type as ComponentType];
187
188 const [details] = await db
189 .select()
190 .from(config.table)
191 .where(
192 eq(config.table.componentId, comp.id)
193 )
194 .limit(1);
195
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 }
201
202 if (comp.type === 'cooler') {
203 details.cpuSockets = await db.select().from(coolerCPUSocketsTable).where(eq(coolerCPUSocketsTable.coolerId, comp.id));
204 }
205
206 componentsDetails.push({
207 ...comp,
208 details: details
209 });
210 }
211
212 return componentsDetails;
213}
214
215export async function getCompatibleComponents(db: Database, buildId: number, componentType: string) {
216 // TO BE IMPLEMENTED
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.