2022-10-10 22:35:21 +08:00
import crypto from 'crypto' ;
2023-02-16 23:56:00 +08:00
import Database from './database' ;
2022-10-14 14:51:19 +08:00
import { IdentifierError } from './errors/identifier-error' ;
2023-03-05 14:45:56 +08:00
import lodash from 'lodash' ;
2022-10-10 15:40:12 +08:00
2022-10-13 11:15:27 +08:00
export function md5 ( value : string ) {
return crypto . createHash ( 'md5' ) . update ( value ) . digest ( 'hex' ) ;
}
2022-10-14 14:51:19 +08:00
const MAX_IDENTIFIER_LENGTH = 63 ;
export function checkIdentifier ( value : string ) {
if ( value . length > MAX_IDENTIFIER_LENGTH ) {
throw new IdentifierError ( ` Identifier ${ value } is too long ` ) ;
}
}
2023-02-13 21:38:47 +08:00
export function getTableName ( collectionName : string , options ) {
return options . underscored ? snakeCase ( collectionName ) : collectionName ;
}
export function snakeCase ( name : string ) {
return require ( 'sequelize' ) . Utils . underscore ( name ) ;
}
2023-02-16 10:53:04 +08:00
2023-02-23 14:13:32 +08:00
function patchShowConstraintsQuery ( queryGenerator , db ) {
queryGenerator . showConstraintsQuery = ( tableName , constraintName ) = > {
const lines = [
'SELECT constraint_catalog AS "constraintCatalog",' ,
'constraint_schema AS "constraintSchema",' ,
'constraint_name AS "constraintName",' ,
'table_catalog AS "tableCatalog",' ,
'table_schema AS "tableSchema",' ,
'table_name AS "tableName",' ,
'constraint_type AS "constraintType",' ,
'is_deferrable AS "isDeferrable",' ,
'initially_deferred AS "initiallyDeferred"' ,
'from INFORMATION_SCHEMA.table_constraints' ,
2023-03-05 14:45:56 +08:00
` WHERE table_name=' ${ lodash . isPlainObject ( tableName ) ? tableName.tableName : tableName } ' ` ,
2023-02-23 14:13:32 +08:00
] ;
2023-12-12 21:24:52 +08:00
if ( constraintName ) {
2023-02-23 14:13:32 +08:00
lines . push ( ` AND constraint_name=' ${ constraintName } ' ` ) ;
}
2023-03-05 14:45:56 +08:00
if ( lodash . isPlainObject ( tableName ) && tableName . schema ) {
lines . push ( ` AND table_schema=' ${ tableName . schema } ' ` ) ;
2023-02-23 14:13:32 +08:00
}
return lines . join ( ' ' ) ;
} ;
}
function patchDescribeTableQuery ( queryGenerator ) {
const describeTableQuery = function ( tableName , schema ) {
schema = schema || this . options . schema || 'public' ;
return (
'SELECT ' +
'pk.constraint_type as "Constraint",' +
'c.column_name as "Field", ' +
'c.column_default as "Default",' +
'c.is_nullable as "Null", ' +
"(CASE WHEN c.udt_name = 'hstore' THEN c.udt_name ELSE c.data_type END) || (CASE WHEN c.character_maximum_length IS NOT NULL THEN '(' || c.character_maximum_length || ')' ELSE '' END) as \"Type\", " +
'(SELECT array_agg(e.enumlabel) FROM pg_catalog.pg_type t JOIN pg_catalog.pg_enum e ON t.oid=e.enumtypid WHERE t.typname=c.udt_name) AS "special", ' +
'(SELECT pgd.description FROM pg_catalog.pg_statio_all_tables AS st INNER JOIN pg_catalog.pg_description pgd on (pgd.objoid=st.relid) WHERE c.ordinal_position=pgd.objsubid AND c.table_name=st.relname AND st.schemaname = c.table_schema) AS "Comment" ' +
'FROM information_schema.columns c ' +
'LEFT JOIN (SELECT tc.table_schema, tc.table_name, ' +
'cu.column_name, tc.constraint_type ' +
'FROM information_schema.TABLE_CONSTRAINTS tc ' +
'JOIN information_schema.KEY_COLUMN_USAGE cu ' +
'ON tc.table_schema=cu.table_schema and tc.table_name=cu.table_name ' +
'and tc.constraint_name=cu.constraint_name ' +
"and tc.constraint_type='PRIMARY KEY') pk " +
'ON pk.table_schema=c.table_schema ' +
'AND pk.table_name=c.table_name ' +
'AND pk.column_name=c.column_name ' +
` WHERE c.table_name = ${ this . escape ( tableName ) } AND c.table_schema = ${ this . escape ( schema ) } `
) ;
} ;
queryGenerator . describeTableQuery = describeTableQuery . bind ( queryGenerator ) ;
}
2023-02-16 10:53:04 +08:00
export function patchSequelizeQueryInterface ( db : Database ) {
if ( db . inDialect ( 'postgres' ) ) {
//@ts-ignore
const queryGenerator = db . sequelize . dialect . queryGenerator ;
2023-02-23 14:13:32 +08:00
patchShowConstraintsQuery ( queryGenerator , db ) ;
patchDescribeTableQuery ( queryGenerator ) ;
2023-02-16 10:53:04 +08:00
}
}
2023-02-16 23:56:00 +08:00
export function percent2float ( value : string ) {
2023-02-17 18:15:35 +08:00
if ( ! value . endsWith ( '%' ) ) {
return NaN ;
}
2023-04-25 13:12:14 +08:00
const val = value . substring ( 0 , value . length - 1 ) ;
2023-02-17 18:15:35 +08:00
if ( isNaN ( + val ) ) {
return NaN ;
}
2023-02-16 23:56:00 +08:00
const index = value . indexOf ( '.' ) ;
if ( index === - 1 ) {
return parseFloat ( value ) / 100 ;
}
const repeat = value . length - index - 2 ;
const v = parseInt ( '1' + '0' . repeat ( repeat ) ) ;
return ( parseFloat ( value ) * v ) / ( 100 * v ) ;
}