2024-03-29 14:25:03 +01:00
|
|
|
import { forceNumber } from '@peertube/peertube-core-utils'
|
|
|
|
import { BindOrReplacements, Op, QueryOptionsWithType, QueryTypes, Sequelize, Transaction } from 'sequelize'
|
2023-07-31 14:34:36 +02:00
|
|
|
import { Fn } from 'sequelize/types/utils'
|
2023-01-10 11:09:30 +01:00
|
|
|
import validator from 'validator'
|
2021-07-28 10:32:40 +02:00
|
|
|
|
2024-03-29 14:25:03 +01:00
|
|
|
async function doesExist (options: {
|
|
|
|
sequelize: Sequelize
|
|
|
|
query: string
|
|
|
|
bind?: BindOrReplacements
|
|
|
|
transaction?: Transaction
|
|
|
|
}) {
|
|
|
|
const { sequelize, query, bind, transaction } = options
|
|
|
|
|
|
|
|
const queryOptions: QueryOptionsWithType<QueryTypes.SELECT> = {
|
|
|
|
type: QueryTypes.SELECT,
|
2021-07-28 10:32:40 +02:00
|
|
|
bind,
|
2024-03-29 14:25:03 +01:00
|
|
|
raw: true,
|
|
|
|
transaction
|
2021-07-28 10:32:40 +02:00
|
|
|
}
|
|
|
|
|
2024-03-29 14:25:03 +01:00
|
|
|
const results = await sequelize.query(query, queryOptions)
|
|
|
|
|
|
|
|
return results.length === 1
|
2021-07-28 10:32:40 +02:00
|
|
|
}
|
|
|
|
|
2023-07-31 14:34:36 +02:00
|
|
|
// FIXME: have to specify the result type to not break peertube typings generation
|
|
|
|
function createSimilarityAttribute (col: string, value: string): Fn {
|
2023-01-10 11:09:30 +01:00
|
|
|
return Sequelize.fn(
|
|
|
|
'similarity',
|
|
|
|
|
|
|
|
searchTrigramNormalizeCol(col),
|
|
|
|
|
|
|
|
searchTrigramNormalizeValue(value)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function buildWhereIdOrUUID (id: number | string) {
|
2023-07-31 14:34:36 +02:00
|
|
|
return validator.default.isInt('' + id) ? { id } : { uuid: id }
|
2023-01-10 11:09:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function parseAggregateResult (result: any) {
|
|
|
|
if (!result) return 0
|
|
|
|
|
|
|
|
const total = forceNumber(result)
|
|
|
|
if (isNaN(total)) return 0
|
|
|
|
|
|
|
|
return total
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseRowCountResult (result: any) {
|
|
|
|
if (result.length !== 0) return result[0].total
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
function createSafeIn (sequelize: Sequelize, toEscape: (string | number)[], additionalUnescaped: string[] = []) {
|
|
|
|
return toEscape.map(t => {
|
|
|
|
return t === null
|
|
|
|
? null
|
|
|
|
: sequelize.escape('' + t)
|
|
|
|
}).concat(additionalUnescaped).join(', ')
|
|
|
|
}
|
|
|
|
|
|
|
|
function searchAttribute (sourceField?: string, targetField?: string) {
|
|
|
|
if (!sourceField) return {}
|
|
|
|
|
|
|
|
return {
|
|
|
|
[targetField]: {
|
|
|
|
// FIXME: ts error
|
|
|
|
[Op.iLike as any]: `%${sourceField}%`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-28 10:32:40 +02:00
|
|
|
export {
|
2024-03-29 14:25:03 +01:00
|
|
|
buildWhereIdOrUUID, createSafeIn, createSimilarityAttribute, doesExist, parseAggregateResult,
|
|
|
|
parseRowCountResult, searchAttribute
|
2023-01-10 11:09:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
function searchTrigramNormalizeValue (value: string) {
|
|
|
|
return Sequelize.fn('lower', Sequelize.fn('immutable_unaccent', value))
|
|
|
|
}
|
|
|
|
|
|
|
|
function searchTrigramNormalizeCol (col: string) {
|
|
|
|
return Sequelize.fn('lower', Sequelize.fn('immutable_unaccent', Sequelize.col(col)))
|
2021-07-28 10:32:40 +02:00
|
|
|
}
|