UNPKG

@directus/api

Version:

Directus is a real-time API and App dashboard for managing SQL database content

87 lines (80 loc) 3.91 kB
import { getDefaultIndexName } from '../../../../utils/get-default-index-name.js'; import { SchemaHelper } from '../types.js'; import { prepQueryParams } from '../utils/prep-query-params.js'; export class SchemaHelperMSSQL extends SchemaHelper { generateIndexName(type, collection, fields) { return getDefaultIndexName(type, collection, fields, { maxLength: 128 }); } applyLimit(rootQuery, limit) { // The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, // and common table expressions, unless TOP, OFFSET or FOR XML is also specified. if (limit === -1) { rootQuery.limit(Number.MAX_SAFE_INTEGER); } else { rootQuery.limit(limit); } } applyOffset(rootQuery, offset) { rootQuery.offset(offset); rootQuery.orderBy(1); } formatUUID(uuid) { return uuid.toUpperCase(); } async getDatabaseSize() { try { const result = await this.knex.raw('SELECT SUM(size) * 8192 AS size FROM sys.database_files;'); return result[0]?.['size'] ? Number(result[0]?.['size']) : null; } catch { return null; } } prepQueryParams(queryParams) { return prepQueryParams(queryParams, { format: (index) => `@p${index}` }); } addInnerSortFieldsToGroupBy(groupByFields, sortRecords, _hasRelationalSort) { /* MSSQL requires all selected columns that are not aggregated over are to be present in the GROUP BY clause > When the select list has no aggregations, each column in the select list must be included in the GROUP BY list. https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16#g-syntax-variations-for-group-by MSSQL does not support aliases in the GROUP BY clause > The column expression cannot contain: A column alias that is defined in the SELECT list. It can use a column alias for a derived table that is defined in the FROM clause. https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16 */ if (sortRecords.length > 0) { groupByFields.push(...sortRecords.map(({ column }) => column)); } } getColumnNameMaxLength() { return 128; } getTableNameMaxLength() { return 128; } async createIndex(collection, field, options = {}) { const isUnique = Boolean(options.unique); const constraintName = this.generateIndexName(isUnique ? 'unique' : 'index', collection, field); /* Online index operations are not available in every edition of Microsoft SQL Server. For a list of features that are supported by the editions of SQL Server, see Editions and supported features of SQL Server 2022. https://learn.microsoft.com/en-us/sql/sql-server/editions-and-components-of-sql-server-2022?view=sql-server-ver16#rdbms-high-availability */ const edition = await this.knex .raw(`SELECT SERVERPROPERTY('edition') AS edition`) .then((data) => data?.[0]?.['edition']); if (options.attemptConcurrentIndex && typeof edition === 'string' && edition.startsWith('Enterprise')) { // https://learn.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-ver16#online---on--off- return this.knex.raw(`CREATE ${isUnique ? 'UNIQUE ' : ''}INDEX ?? ON ?? (??) WITH (ONLINE = ON)`, [ constraintName, collection, field, ]); } // Fall back to blocking index creation for non-enterprise editions return this.knex.raw(`CREATE ${isUnique ? 'UNIQUE ' : ''}INDEX ?? ON ?? (??)`, [constraintName, collection, field]); } }