@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
122 lines (121 loc) • 3.95 kB
JavaScript
import { getDefaultIndexName } from '../../../utils/get-default-index-name.js';
import { getDatabaseClient } from '../../index.js';
import { DatabaseHelper } from '../types.js';
export class SchemaHelper extends DatabaseHelper {
isOneOfClients(clients) {
return clients.includes(getDatabaseClient(this.knex));
}
async changeNullable(table, column, nullable) {
await this.knex.schema.alterTable(table, (builder) => {
if (nullable) {
builder.setNullable(column);
}
else {
builder.dropNullable(column);
}
});
}
generateIndexName(type, collection, fields) {
return getDefaultIndexName(type, collection, fields);
}
async changeToType(table, column, type, options = {}) {
await this.knex.schema.alterTable(table, (builder) => {
const b = type === 'string' ? builder.string(column, options.length) : builder[type](column);
if (options.nullable === true) {
b.nullable();
}
if (options.nullable === false) {
b.notNullable();
}
if (options.default !== undefined) {
b.defaultTo(options.default);
}
b.alter();
});
}
async changeToTypeByCopy(table, column, type, options) {
const tempName = `${column}__temp`;
await this.knex.schema.alterTable(table, (builder) => {
const col = type === 'string' ? builder.string(tempName, options.length) : builder[type](tempName);
if (options.default !== undefined) {
col.defaultTo(options.default);
}
// Force new temporary column to be nullable (required, as there will already be rows in
// the table)
col.nullable();
});
await this.knex(table).update(tempName, this.knex.ref(column));
await this.knex.schema.alterTable(table, (builder) => {
builder.dropColumn(column);
});
await this.knex.schema.alterTable(table, (builder) => {
builder.renameColumn(tempName, column);
});
// We're altering the temporary column here. That starts nullable, so we only want to set it
// to NOT NULL when applicable
if (options.nullable === false) {
await this.changeNullable(table, column, options.nullable);
}
}
async preColumnChange() {
return false;
}
async postColumnChange() {
return;
}
preRelationChange(_relation) {
return;
}
setNullable(column, field, existing) {
const isNullable = field.schema?.is_nullable ?? existing?.is_nullable ?? true;
if (isNullable) {
column.nullable();
}
else {
column.notNullable();
}
}
processFieldType(field) {
return field.type;
}
constraintName(existingName) {
// most vendors allow for dropping/creating constraints with the same name
// reference issue #14873
return existingName;
}
applyLimit(rootQuery, limit) {
if (limit !== -1) {
rootQuery.limit(limit);
}
}
applyOffset(rootQuery, offset) {
rootQuery.offset(offset);
}
castA2oPrimaryKey() {
return 'CAST(?? AS CHAR(255))';
}
formatUUID(uuid) {
return uuid; // no-op by default
}
/**
* @returns Size of the database in bytes
*/
async getDatabaseSize() {
return null;
}
prepQueryParams(queryParams) {
return queryParams;
}
prepBindings(bindings) {
return bindings;
}
addInnerSortFieldsToGroupBy(_groupByFields, _sortRecords, _hasRelationalSort) {
// no-op by default
}
getColumnNameMaxLength() {
return 64;
}
getTableNameMaxLength() {
return 64;
}
}