UNPKG

@directus/api

Version:

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

83 lines (70 loc) 3.6 kB
import { useEnv } from '@directus/env'; import { getDefaultIndexName } from '../../../../utils/get-default-index-name.js'; import { SchemaHelper } from '../types.js'; const env = useEnv(); export class SchemaHelperMySQL extends SchemaHelper { generateIndexName(type, collection, fields) { return getDefaultIndexName(type, collection, fields, { maxLength: 64 }); } async getDatabaseSize() { try { const result = (await this.knex .sum('size AS size') .from(this.knex .select(this.knex.raw('data_length + index_length AS size')) .from('information_schema.TABLES') .where('table_schema', '=', String(env['DB_DATABASE'])) .as('size'))); return result[0]?.['size'] ? Number(result[0]?.['size']) : null; } catch { return null; } } addInnerSortFieldsToGroupBy(groupByFields, sortRecords, hasRelationalSort) { if (hasRelationalSort) { /* ** MySQL ** MySQL only requires all selected sort columns that are not functionally dependent on the primary key to be included. > If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default), MySQL rejects queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on them. https://dev.mysql.com/doc/refman/8.4/en/group-by-handling.html MySQL allows aliases to be used in the GROUP BY clause > You can use the alias in GROUP BY, ORDER BY, or HAVING clauses to refer to the column: https://dev.mysql.com/doc/refman/8.4/en/problems-with-alias.html ** MariaDB ** MariaDB does not document how it supports functional dependent columns in GROUP BY clauses. But testing shows that it does support the same features as MySQL in this area. MariaDB allows aliases to be used in the GROUP BY clause > The GROUP BY expression can be a computed value, and can refer back to an identifer specified with AS. https://mariadb.com/kb/en/group-by/#group-by-examples */ groupByFields.push(...sortRecords.map(({ alias }) => alias)); } } async createIndex(collection, field, options = {}) { const isUnique = Boolean(options.unique); const constraintName = this.generateIndexName(isUnique ? 'unique' : 'index', collection, field); const blockingQuery = this.knex.raw(`CREATE ${isUnique ? 'UNIQUE ' : ''}INDEX ?? ON ?? (??)`, [ constraintName, collection, field, ]); if (options.attemptConcurrentIndex) { /* Seems it is not possible to determine whether "ALGORITHM=INPLACE LOCK=NONE" will be supported so we're just going to send it and fall back to blocking index creation on error https://dev.mysql.com/doc/refman/8.4/en/create-index.html#:~:text=engine%20is%20changed.-,Table%20Copying%20and%20Locking%20Options,-ALGORITHM%20and%20LOCK */ return this.knex .raw(`CREATE ${isUnique ? 'UNIQUE ' : ''}INDEX ?? ON ?? (??) ALGORITHM=INPLACE LOCK=NONE`, [ constraintName, collection, field, ]) .catch(() => blockingQuery); } return blockingQuery; } }