- Timestamp:
- 12/20/25 04:03:51 (7 months ago)
- Branches:
- main
- Children:
- 5ce5904
- Parents:
- 37bcb87
- Location:
- database/drizzle
- Files:
-
- 4 edited
-
queries/builds.ts (modified) (8 diffs)
-
queries/components.ts (modified) (1 diff)
-
queries/users.ts (modified) (4 diffs)
-
schema/components.ts (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
database/drizzle/queries/builds.ts
r37bcb87 rc4dd17d 1 1 import type { Database } from "../db"; 2 import {buildComponentsTable, buildsTable, favoriteBuildsTable, ratingBuildsTable, reviewsTable} from "../schema"; 2 import { 3 buildComponentsTable, 4 buildsTable, 5 componentsTable, 6 favoriteBuildsTable, 7 ratingBuildsTable, 8 reviewsTable, usersTable 9 } from "../schema"; 3 10 import {eq, desc, and, sql, ilike} from "drizzle-orm"; 4 11 … … 72 79 73 80 export async function getApprovedBuilds(db: Database, limit?: number, q?: string) { 74 let queryConditions = [ ];81 let queryConditions = [eq(buildsTable.isApproved, true)]; 75 82 76 83 if (q) { … … 91 98 .where( 92 99 and ( 93 eq(buildsTable.isApproved, true),94 100 ...queryConditions 95 101 ) … … 110 116 name: buildsTable.name, 111 117 created_at: buildsTable.createdAt, 112 total_price: buildsTable.totalPrice 118 total_price: buildsTable.totalPrice, 119 avgRating: sql<number>`AVG(${ratingBuildsTable.value}::float)` 113 120 }) 114 121 .from(buildsTable) … … 120 127 eq(buildsTable.isApproved, true) 121 128 ) 122 .groupBy( 123 buildsTable.id 124 ) 129 .groupBy(buildsTable.id) 125 130 .orderBy( 126 131 desc(sql<number>`AVG(${ratingBuildsTable.value}::float)`) … … 131 136 } 132 137 133 export async function getBuildDetails(db: Database, buildId: number) { 134 const buildDetails = await db 135 .select() 136 .from(buildsTable) 137 .where( 138 eq(buildsTable.id, buildId) 139 ) 140 .limit(1); 141 142 return buildDetails[0] ?? null; 138 export async function getBuildDetails(db: Database, buildId: number, userId?: number) { 139 return db.transaction(async (tx) => { 140 const [buildDetails] = await tx 141 .select({ 142 id: buildsTable.id, 143 userId: buildsTable.userId, 144 name: buildsTable.name, 145 createdAt: buildsTable.createdAt, 146 description: buildsTable.description, 147 totalPrice: buildsTable.totalPrice, 148 isApproved: buildsTable.isApproved, 149 creator: usersTable.username 150 }) 151 .from(buildsTable) 152 .innerJoin( 153 usersTable, 154 eq(buildsTable.userId, usersTable.id) 155 ) 156 .where( 157 eq(buildsTable.id, buildId) 158 ) 159 .limit(1); 160 161 if (!buildDetails) return null; 162 163 const components = await tx 164 .select({ 165 componentId: buildComponentsTable.componentId, 166 component: componentsTable 167 }) 168 .from(buildComponentsTable) 169 .innerJoin( 170 componentsTable, 171 eq(buildComponentsTable.componentId, componentsTable.id) 172 ) 173 .where( 174 eq(buildComponentsTable.buildId, buildId) 175 ); 176 177 const reviews = await tx 178 .select({ 179 username: usersTable.username, 180 content: reviewsTable.content, 181 createdAt: reviewsTable.createdAt 182 }) 183 .from(reviewsTable) 184 .innerJoin( 185 usersTable, 186 eq(reviewsTable.userId, usersTable.id) 187 ) 188 .where( 189 eq(reviewsTable.buildId, buildId) 190 ) 191 .orderBy( 192 desc(reviewsTable.createdAt) 193 ); 194 195 let [ratingStatistics] = await tx 196 .select({ 197 averageRating: sql<number>`COALESCE(AVG(${ratingBuildsTable.value}::float), 0)`.as("averageRating"), 198 ratingCount: sql<number>`COUNT(${ratingBuildsTable.value})`.as("ratingCount") 199 }) 200 .from(ratingBuildsTable) 201 .where( 202 eq(ratingBuildsTable.buildId, buildId) 203 ) 204 .groupBy(ratingBuildsTable.buildId); 205 206 ratingStatistics = { 207 averageRating: Number(ratingStatistics?.averageRating ?? 0), 208 ratingCount: Number(ratingStatistics?.ratingCount ?? 0), 209 } 210 211 let userRating = null; 212 let isFavorite = false; 213 let userReview = null; 214 215 if(userId) { 216 const [rating] = await tx 217 .select() 218 .from(ratingBuildsTable) 219 .where( 220 and( 221 eq(ratingBuildsTable.buildId, buildId), 222 eq(ratingBuildsTable.userId, userId) 223 ) 224 ) 225 .limit(1); 226 227 userRating = rating?.value ? Number(rating.value) : null; 228 229 const [favorite] = await tx 230 .select() 231 .from(favoriteBuildsTable) 232 .where( 233 and( 234 eq(favoriteBuildsTable.buildId, buildId), 235 eq(favoriteBuildsTable.userId, userId) 236 ) 237 ) 238 .limit(1); 239 240 isFavorite = !!favorite; 241 242 const [review] = await tx 243 .select() 244 .from(reviewsTable) 245 .where( 246 and( 247 eq(reviewsTable.buildId, buildId), 248 eq(reviewsTable.userId, userId) 249 ) 250 ) 251 .limit(1); 252 253 userReview = review?.content; 254 } 255 256 return { 257 ...buildDetails, 258 components: components.map(c => c.component), 259 reviews: reviews, 260 ratingStatistics: ratingStatistics, 261 userRating, 262 userReview, 263 isFavorite 264 }; 265 }); 143 266 } 144 267 … … 184 307 userId, 185 308 buildId, 186 value: value .toString()309 value: value 187 310 }) 188 311 .onConflictDoUpdate({ 189 312 target: [ratingBuildsTable.userId, ratingBuildsTable.buildId], 190 313 set: { 191 value: value .toString(),314 value: value, 192 315 }, 193 316 }); … … 275 398 return newBuild.id; 276 399 } 277 278 279 -
database/drizzle/queries/components.ts
r37bcb87 rc4dd17d 1 1 import type { Database } from "../db"; 2 import { componentsTable, suggestionsTable } from "../schema"; 2 import {buildsTable, componentsTable } from "../schema"; 3 import {and, desc, eq, ilike} from "drizzle-orm"; 3 4 4 export async function getComponentSuggestions(db: Database) { 5 export async function getAllComponents(db: Database, limit?: number, q?: string, componentType?: string) { 6 let queryConditions = []; 5 7 8 if (q) { 9 queryConditions.push( 10 ilike(componentsTable.name, `%${q}%`) 11 ); 12 } 13 14 if(componentType && componentType.trim() !== 'all') { 15 queryConditions.push( 16 eq(componentsTable.type, componentType.trim().toLowerCase()) 17 ); 18 } 19 20 const componentsList = await db 21 .select({ 22 id: componentsTable.id, 23 name: componentsTable.name, 24 brand: componentsTable.brand, 25 price: componentsTable.price, 26 }) 27 .from(componentsTable) 28 .where( 29 queryConditions.length > 0 ? 30 and ( 31 ...queryConditions 32 ) 33 : undefined 34 ) 35 .orderBy( 36 desc(componentsTable.price) 37 ) 38 .limit(limit || 100); // 100 placeholder 39 40 return componentsList; 6 41 } 7 42 8 export async function setComponentSuggestionStatus(db: Database, suggestionId: number, status: string, adminComment: string) { 43 export async function getComponentDetails(db: Database, componentId: number) { 44 const [componentDetails] = await db 45 .select() 46 .from(componentsTable) 47 .where( 48 eq(componentsTable.id, componentId) 49 ) 50 .limit(1); 9 51 52 return componentDetails ?? null; 10 53 } 11 12 export async function getAllComponents(db: Database, componentType?: string, q?: string, page?: number, pageSize?: number) {13 14 } -
database/drizzle/queries/users.ts
r37bcb87 rc4dd17d 1 1 import type { Database } from "../db"; 2 import {adminsTable, usersTable} from "../schema";3 import { eq} from "drizzle-orm";2 import {adminsTable, suggestionsTable, usersTable} from "../schema"; 3 import {desc, eq} from "drizzle-orm"; 4 4 5 5 export async function createUser(db: Database, username: string, email: string, passwordHash: string) { … … 14 14 15 15 export async function getUserProfile(db: Database, userId: number) { 16 const user= await db16 const [user] = await db 17 17 .select({ 18 18 username: usersTable.username, … … 25 25 .limit(1); 26 26 27 return user [0]?? null;27 return user ?? null; 28 28 } 29 29 … … 39 39 return admin.length > 0; 40 40 } 41 42 export async function getComponentSuggestions(db: Database) { 43 const suggestionsList = await db 44 .select() 45 .from(suggestionsTable) 46 .where( 47 eq(suggestionsTable.status, 'pending') 48 ) 49 .orderBy( 50 desc(suggestionsTable.id) 51 ) 52 53 return suggestionsList; 54 } 55 56 export async function setComponentSuggestionStatus(db: Database, suggestionId: number, adminId: number, status: string, adminComment: string) { 57 const result = await db 58 .update(suggestionsTable) 59 .set({ 60 adminId: adminId, 61 status: status, 62 adminComment: adminComment 63 }) 64 .where( 65 eq(suggestionsTable.id, suggestionId) 66 ); 67 68 return result.rowCount; 69 } 70 71 export async function addComponentSuggestion(db: Database, userId: number, link: string, description: string, componentType: string) { 72 const [newSuggestion] = await db 73 .insert(suggestionsTable) 74 .values({ 75 userId: userId, 76 link: link, 77 description: description, 78 componentType: componentType 79 }) 80 .returning({ id: suggestionsTable.id }); 81 82 return newSuggestion.id ?? null; 83 } -
database/drizzle/schema/components.ts
r37bcb87 rc4dd17d 1 import { pgTable, serial, integer, text, numeric, boolean, date, primaryKey } from "drizzle-orm/pg-core"; 1 import {pgTable, serial, integer, text, numeric, boolean, date, primaryKey, check} from "drizzle-orm/pg-core"; 2 import {sql} from "drizzle-orm"; 2 3 3 4 export const componentsTable = pgTable("components", { … … 7 8 price: numeric("price").notNull(), 8 9 imgUrl: text("img_url"), 9 }); 10 type: text("type").notNull() 11 }, 12 (t) => ({ 13 checkType: check("check_type", sql`${t.type} in 14 ('cpu', 'gpu', 'memory', 'storage', 'power_supply', 'motherboard', 'case', 'cooler', 'memory_card', 'optical_drive', 'sound_card', 'cables', 'network_adapter', 'network_card')`) 15 }), 16 ); 10 17 11 18 // Base Components
Note:
See TracChangeset
for help on using the changeset viewer.
