1- import { eq , type ExtractTablesWithRelations } from "drizzle-orm" ;
2- import { type PgTransaction } from "drizzle-orm/pg-core" ;
3- import { type PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js" ;
4- import { drizzleClient } from "~/db.server" ;
5- import { type User , type Profile , profile } from "~/schema" ;
6- import type * as schema from "~/schema" ;
1+ import {
2+ eq ,
3+ type ExtractTablesWithRelations ,
4+ count ,
5+ inArray ,
6+ } from 'drizzle-orm'
7+ import { type PgTransaction } from 'drizzle-orm/pg-core'
8+ import { type PostgresJsQueryResultHKT } from 'drizzle-orm/postgres-js'
9+ import { drizzleClient } from '~/db.server'
10+ import { type User , type Profile , profile , sensor , measurement } from '~/schema'
11+ import type * as schema from '~/schema'
712
8- export async function getProfileByUserId ( id : Profile [ "id" ] ) {
9- return drizzleClient . query . profile . findFirst ( {
10- where : ( profile , { eq } ) => eq ( profile . userId , id ) ,
11- with : {
12- profileImage : true ,
13- } ,
14- } ) ;
13+ export async function getProfileByUserId ( id : Profile [ 'id' ] ) {
14+ return drizzleClient . query . profile . findFirst ( {
15+ where : ( profile , { eq } ) => eq ( profile . userId , id ) ,
16+ with : {
17+ profileImage : true ,
18+ } ,
19+ } )
1520}
1621
17- export async function getProfileByUsername ( username : Profile [ " username" ] ) {
18- return drizzleClient . query . profile . findFirst ( {
19- where : ( profile , { eq } ) => eq ( profile . username , username ) ,
20- with : {
21- user : {
22- with : {
23- devices : true ,
24- } ,
25- } ,
26- profileImage : true ,
27- } ,
28- } ) ;
22+ export async function getProfileByUsername ( username : Profile [ ' username' ] ) {
23+ return drizzleClient . query . profile . findFirst ( {
24+ where : ( profile , { eq } ) => eq ( profile . username , username ) ,
25+ with : {
26+ user : {
27+ with : {
28+ devices : true ,
29+ } ,
30+ } ,
31+ profileImage : true ,
32+ } ,
33+ } )
2934}
3035
3136export async function updateProfile (
32- id : Profile [ "id" ] ,
33- username : Profile [ " username" ] ,
34- visibility : Profile [ " public" ] ,
37+ id : Profile [ 'id' ] ,
38+ username : Profile [ ' username' ] ,
39+ visibility : Profile [ ' public' ] ,
3540) {
36- try {
37- const result = await drizzleClient
38- . update ( profile )
39- . set ( { username, public : visibility } )
40- . where ( eq ( profile . id , id ) ) ;
41- return result ;
42- } catch ( error ) {
43- throw error ;
44- }
41+ try {
42+ const result = await drizzleClient
43+ . update ( profile )
44+ . set ( { username, public : visibility } )
45+ . where ( eq ( profile . id , id ) )
46+ return result
47+ } catch ( error ) {
48+ throw error
49+ }
4550}
4651
4752export async function createProfile (
48- userId : User [ "id" ] ,
49- username : Profile [ " username" ] ,
53+ userId : User [ 'id' ] ,
54+ username : Profile [ ' username' ] ,
5055) {
51- return drizzleClient . transaction ( t =>
52- createProfileWithTransaction ( t , userId , username ) ) ;
56+ return drizzleClient . transaction ( ( t ) =>
57+ createProfileWithTransaction ( t , userId , username ) ,
58+ )
5359}
5460
5561export async function createProfileWithTransaction (
56- transaction : PgTransaction < PostgresJsQueryResultHKT , typeof schema , ExtractTablesWithRelations < typeof schema > > ,
57- userId : User [ "id" ] ,
58- username : Profile [ "username" ] ,
62+ transaction : PgTransaction <
63+ PostgresJsQueryResultHKT ,
64+ typeof schema ,
65+ ExtractTablesWithRelations < typeof schema >
66+ > ,
67+ userId : User [ 'id' ] ,
68+ username : Profile [ 'username' ] ,
5969) {
60- return transaction
61- . insert ( profile )
62- . values ( {
63- username,
64- public : false ,
65- userId,
66- } ) ;
67- }
70+ return transaction . insert ( profile ) . values ( {
71+ username,
72+ public : false ,
73+ userId,
74+ } )
75+ }
76+
77+ function formatCount ( num : number ) : string {
78+ if ( num >= 1_000_000 ) {
79+ return `${ ( num / 1_000_000 ) . toFixed ( 1 ) . replace ( / \. 0 $ / , '' ) } M`
80+ }
81+ if ( num >= 1_000 ) {
82+ return `${ ( num / 1_000 ) . toFixed ( 1 ) . replace ( / \. 0 $ / , '' ) } k`
83+ }
84+ return num . toString ( )
85+ }
86+
87+ // function to get sensors and measurements count for a profile
88+ export async function getProfileSensorsAndMeasurementsCount ( profile : Profile ) {
89+ const userId = profile . userId
90+ if ( userId == null ) return { sensorsCount : '0' , measurementsCount : '0' }
91+
92+ const devices = await drizzleClient . query . device . findMany ( {
93+ where : ( device , { eq } ) => eq ( device . userId , userId ) ,
94+ } )
95+ const deviceIds = devices . map ( ( device ) => device . id )
96+
97+ if ( deviceIds . length === 0 ) {
98+ return { sensorsCount : '0' , measurementsCount : '0' }
99+ }
100+
101+ // Get sensor IDs for measurements count
102+ const sensors = await drizzleClient . query . sensor . findMany ( {
103+ where : ( s , { inArray } ) => inArray ( s . deviceId , deviceIds ) ,
104+ columns : { id : true } ,
105+ } )
106+ const sensorsCount = sensors . length
107+ const sensorIds = sensors . map ( ( s ) => s . id )
108+
109+ // Count measurements using COUNT query
110+ let measurementsCount = 0
111+ if ( sensorIds . length > 0 ) {
112+ const [ measurementsResult ] = await drizzleClient
113+ . select ( { count : count ( measurement . value ) } )
114+ . from ( measurement )
115+ . where ( inArray ( measurement . sensorId , sensorIds ) )
116+
117+ measurementsCount = measurementsResult . count
118+ }
119+
120+ return {
121+ sensorsCount : formatCount ( sensorsCount ) ,
122+ measurementsCount : formatCount ( measurementsCount ) ,
123+ }
124+ }
0 commit comments