import { PostgreSQL } from "../types" ; import { callback2 } from "@cocalc/util/async-utils" ; import { copy_with , len } from "@cocalc/util/misc" ; const TIMEOUT_S = 30 ; export async function number_of_running_projects_using_license ( db , license_id ) { const query = `SELECT COUNT(*) FROM projects WHERE state#>>'{state}' = 'running' AND site_license#>>'{${ license_id }}'!='{}'` ; const x = await db . async_query ( { query , timeout_s : TIMEOUT_S } ) ; return parseInt ( x . rows [ 0 ] . count ) ; } export async function number_of_projects_with_license_applied ( db , license_id ) { const query = `SELECT COUNT(*) FROM projects WHERE site_license#>>'{${ license_id }}' IS NOT NULL` ; const x = await db . async_query ( { query , timeout_s : TIMEOUT_S } ) ; return parseInt ( x . rows [ 0 ] . count ) ; } export async function site_license_usage_stats ( db ) { const query = "select site_license from projects where state#>>'{state}' in ('running', 'starting') and site_license!='{}'" ; const result = await db . async_query ( { query } ) ; const usage = { } ; for ( let row of result . rows ) { for ( const license_id in row . site_license ) { if ( len ( row . site_license [ license_id ] ) > 0 ) { if ( usage [ license_id ] == null ) { usage [ license_id ] = 1 ; } else { usage [ license_id ] += 1 ; } } } } return usage ; } function query_projects_using_site_license ( license_id , cutoff ? ) { const params = [ ] ; let query ; if ( cutoff ) { query = `FROM projects, site_license_usage_log WHERE  ` ; query += "projects.project_id = site_license_usage_log.project_id AND " ; query += "site_license_usage_log.license_id = $1 AND" ; query += "(site_license_usage_log.start >= $2 OR " ; query += " site_license_usage_log.stop >= $2 OR " ; query += " site_license_usage_log.stop IS NULL)" ; params . push ( license_id ) ; params . push ( cutoff ) ; } else { query = `FROM projects` ; query += ` WHERE state#>>'{state}' IN ('running', 'starting') AND site_license#>>'{${ license_id }}'!='{}'` ; } return { query , params } ; } export async function projects_using_site_license ( db , opts ) { const query_fields = process_fields ( opts . fields , opts . truncate ) ; const { query , params } = query_projects_using_site_license ( opts . license_id , opts . cutoff ) ; const select = `SELECT ${ query_fields . join ( "," ) } ` ; const x = await callback2 ( db . _query . bind ( db ) , { query : select + " " + query , limit : opts . limit , params , } ) ; const v = [ ] ; for ( const row of x . rows ) { v . push ( copy_with ( row , opts . fields ) ) ; } return v ; } function process_fields ( fields , truncate ) { const v = [ ] ; for ( let field of fields ) { if ( truncate && ( field == "title" || field == "description" ) ) { field = `left(projects.${ field },${ truncate }) as ${ field }` ; } else if ( field == "project_id" ) { field = `distinct(projects.project_id)` ; } else { field = `projects.${ field }` ; } v . push ( field ) ; } return v ; } export async function number_of_projects_using_site_license ( db , opts ) { const { query , params } = query_projects_using_site_license ( opts . license_id , opts . cutoff ) ; const x = await db . async_query ( { query : "SELECT COUNT(DISTINCT(projects.project_id)) " + query , params , timeout_s : TIMEOUT_S , } ) ; return parseInt ( x . rows [ 0 ] . count ) ; }