mirror of
https://github.com/strapi/strapi.git
synced 2025-11-08 06:07:41 +00:00
chore(database): use naming functions for identifiers in metadata relations
This commit is contained in:
parent
c29dcf0999
commit
3cea9ffa5c
@ -1,9 +1,8 @@
|
|||||||
import _ from 'lodash/fp';
|
import _ from 'lodash/fp';
|
||||||
|
import * as identifiers from '../utils/identifiers';
|
||||||
import * as types from '../utils/types';
|
import * as types from '../utils/types';
|
||||||
import {
|
import {
|
||||||
createRelation,
|
createRelation,
|
||||||
getJoinTableName,
|
|
||||||
isPolymorphic,
|
isPolymorphic,
|
||||||
isBidirectional,
|
isBidirectional,
|
||||||
isAnyToOne,
|
isAnyToOne,
|
||||||
@ -17,7 +16,6 @@ import type { Attribute, Model } from '../types';
|
|||||||
|
|
||||||
export type { Metadata, Meta };
|
export type { Metadata, Meta };
|
||||||
export {
|
export {
|
||||||
getJoinTableName,
|
|
||||||
isPolymorphic,
|
isPolymorphic,
|
||||||
isBidirectional,
|
isBidirectional,
|
||||||
isAnyToOne,
|
isAnyToOne,
|
||||||
@ -87,6 +85,6 @@ export const createMetadata = (models: Model[] = []): Metadata => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createAttribute = (attributeName: string, attribute: Attribute) => {
|
const createAttribute = (attributeName: string, attribute: Attribute) => {
|
||||||
const columnName = _.snakeCase(attributeName);
|
const columnName = identifiers.getColumnName(attributeName);
|
||||||
Object.assign(attribute, { columnName });
|
Object.assign(attribute, { columnName });
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import _ from 'lodash/fp';
|
import _ from 'lodash/fp';
|
||||||
|
|
||||||
|
import * as identifiers from '../utils/identifiers';
|
||||||
import type { Meta, Metadata } from './metadata';
|
import type { Meta, Metadata } from './metadata';
|
||||||
import type { RelationalAttribute, Relation, MorphJoinTable } from '../types';
|
import type { RelationalAttribute, Relation, MorphJoinTable } from '../types';
|
||||||
|
|
||||||
@ -15,6 +16,10 @@ interface JoinTableOptions {
|
|||||||
meta: Meta;
|
meta: Meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ID = identifiers.ID_COLUMN;
|
||||||
|
const ORDER = identifiers.ORDER_COLUMN;
|
||||||
|
const FIELD = identifiers.FIELD_COLUMN;
|
||||||
|
|
||||||
const hasInversedBy = (
|
const hasInversedBy = (
|
||||||
attr: RelationalAttribute
|
attr: RelationalAttribute
|
||||||
): attr is RelationalAttribute & { inversedBy: boolean } => 'inversedBy' in attr;
|
): attr is RelationalAttribute & { inversedBy: boolean } => 'inversedBy' in attr;
|
||||||
@ -57,9 +62,6 @@ const isOwner = (
|
|||||||
const shouldUseJoinTable = (attribute: RelationalAttribute) =>
|
const shouldUseJoinTable = (attribute: RelationalAttribute) =>
|
||||||
!('useJoinTable' in attribute) || attribute.useJoinTable !== false;
|
!('useJoinTable' in attribute) || attribute.useJoinTable !== false;
|
||||||
|
|
||||||
export const getJoinTableName = (tableName: string, attributeName: string) =>
|
|
||||||
_.snakeCase(`${tableName}_${attributeName}_links`);
|
|
||||||
|
|
||||||
export const hasOrderColumn = (attribute: RelationalAttribute) => isAnyToMany(attribute);
|
export const hasOrderColumn = (attribute: RelationalAttribute) => isAnyToMany(attribute);
|
||||||
export const hasInverseOrderColumn = (attribute: RelationalAttribute) =>
|
export const hasInverseOrderColumn = (attribute: RelationalAttribute) =>
|
||||||
isBidirectional(attribute) && isManyToAny(attribute);
|
isBidirectional(attribute) && isManyToAny(attribute);
|
||||||
@ -209,8 +211,8 @@ const createManyToMany = (
|
|||||||
* set info in the traget
|
* set info in the traget
|
||||||
*/
|
*/
|
||||||
const createMorphToOne = (attributeName: string, attribute: Relation.MorphToOne) => {
|
const createMorphToOne = (attributeName: string, attribute: Relation.MorphToOne) => {
|
||||||
const idColumnName = 'target_id';
|
const idColumnName = identifiers.getJoinColumnAttributeIdName('target');
|
||||||
const typeColumnName = 'target_type';
|
const typeColumnName = identifiers.getMorphColumnTypeName('target');
|
||||||
|
|
||||||
if ('morphColumn' in attribute && attribute.morphColumn) {
|
if ('morphColumn' in attribute && attribute.morphColumn) {
|
||||||
return;
|
return;
|
||||||
@ -225,7 +227,7 @@ const createMorphToOne = (attributeName: string, attribute: Relation.MorphToOne)
|
|||||||
},
|
},
|
||||||
idColumn: {
|
idColumn: {
|
||||||
name: idColumnName,
|
name: idColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -246,19 +248,19 @@ const createMorphToMany = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const joinTableName = _.snakeCase(`${meta.tableName}_${attributeName}_morphs`);
|
const joinTableName = identifiers.getMorphTableName(meta.tableName, attributeName);
|
||||||
|
const joinColumnName = identifiers.getMorphColumnJoinTableIdName(meta.singularName);
|
||||||
|
const idColumnName = identifiers.getMorphColumnAttributeIdName(attributeName);
|
||||||
|
const typeColumnName = identifiers.getMorphColumnTypeName(attributeName);
|
||||||
|
|
||||||
const joinColumnName = _.snakeCase(`${meta.singularName}_id`);
|
const fkIndexName = identifiers.getFkIndexName(joinTableName);
|
||||||
const morphColumnName = _.snakeCase(`${attributeName}`);
|
|
||||||
const idColumnName = `${morphColumnName}_id`;
|
|
||||||
const typeColumnName = `${morphColumnName}_type`;
|
|
||||||
|
|
||||||
metadata.add({
|
metadata.add({
|
||||||
singularName: joinTableName,
|
singularName: joinTableName,
|
||||||
uid: joinTableName,
|
uid: joinTableName,
|
||||||
tableName: joinTableName,
|
tableName: joinTableName,
|
||||||
attributes: {
|
attributes: {
|
||||||
id: {
|
[ID]: {
|
||||||
type: 'increments',
|
type: 'increments',
|
||||||
},
|
},
|
||||||
[joinColumnName]: {
|
[joinColumnName]: {
|
||||||
@ -276,10 +278,10 @@ const createMorphToMany = (
|
|||||||
[typeColumnName]: {
|
[typeColumnName]: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
field: {
|
[FIELD]: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
order: {
|
[ORDER]: {
|
||||||
type: 'float',
|
type: 'float',
|
||||||
column: {
|
column: {
|
||||||
unsigned: true,
|
unsigned: true,
|
||||||
@ -288,12 +290,12 @@ const createMorphToMany = (
|
|||||||
},
|
},
|
||||||
indexes: [
|
indexes: [
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_fk`,
|
name: fkIndexName,
|
||||||
columns: [joinColumnName],
|
columns: [joinColumnName],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_order_index`,
|
name: `${joinTableName}_order_index`,
|
||||||
columns: ['order'],
|
columns: [ORDER],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_id_column_index`,
|
name: `${joinTableName}_id_column_index`,
|
||||||
@ -302,10 +304,10 @@ const createMorphToMany = (
|
|||||||
],
|
],
|
||||||
foreignKeys: [
|
foreignKeys: [
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_fk`,
|
name: fkIndexName,
|
||||||
columns: [joinColumnName],
|
columns: [joinColumnName],
|
||||||
referencedColumns: ['id'],
|
referencedColumns: [ID],
|
||||||
referencedTable: meta.tableName,
|
referencedTable: identifiers.getTableName(meta.tableName),
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -317,7 +319,7 @@ const createMorphToMany = (
|
|||||||
name: joinTableName,
|
name: joinTableName,
|
||||||
joinColumn: {
|
joinColumn: {
|
||||||
name: joinColumnName,
|
name: joinColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
},
|
},
|
||||||
morphColumn: {
|
morphColumn: {
|
||||||
typeColumn: {
|
typeColumn: {
|
||||||
@ -325,7 +327,7 @@ const createMorphToMany = (
|
|||||||
},
|
},
|
||||||
idColumn: {
|
idColumn: {
|
||||||
name: idColumnName,
|
name: idColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
@ -390,7 +392,7 @@ const createJoinColum = (metadata: Metadata, { attribute, attributeName }: JoinC
|
|||||||
const joinColumnName = _.snakeCase(`${attributeName}_id`);
|
const joinColumnName = _.snakeCase(`${attributeName}_id`);
|
||||||
const joinColumn = {
|
const joinColumn = {
|
||||||
name: joinColumnName,
|
name: joinColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
referencedTable: targetMeta.tableName,
|
referencedTable: targetMeta.tableName,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -430,30 +432,34 @@ const createJoinTable = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const joinTableName = getJoinTableName(meta.tableName, attributeName);
|
const joinTableName = identifiers.getJoinTableName(meta.tableName, attributeName);
|
||||||
|
|
||||||
const joinColumnName = _.snakeCase(`${meta.singularName}_id`);
|
const joinColumnName = identifiers.getJoinColumnIdName(meta.singularName);
|
||||||
let inverseJoinColumnName = _.snakeCase(`${targetMeta.singularName}_id`);
|
let inverseJoinColumnName = identifiers.getJoinColumnIdName(targetMeta.singularName);
|
||||||
|
|
||||||
// if relation is self referencing
|
// if relation is self referencing
|
||||||
if (joinColumnName === inverseJoinColumnName) {
|
if (joinColumnName === inverseJoinColumnName) {
|
||||||
inverseJoinColumnName = `inv_${inverseJoinColumnName}`;
|
inverseJoinColumnName = identifiers.getInverseJoinColumnIdName(targetMeta.singularName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const orderColumnName = _.snakeCase(`${targetMeta.singularName}_order`);
|
const orderColumnName = identifiers.getOrderColumnName(targetMeta.singularName);
|
||||||
let inverseOrderColumnName = _.snakeCase(`${meta.singularName}_order`);
|
// TODO: should this plus the conditional below be rolled into one method?
|
||||||
|
let inverseOrderColumnName = identifiers.getOrderColumnName(meta.singularName);
|
||||||
|
|
||||||
// if relation is self referencing
|
// if relation is self referencing
|
||||||
if (attribute.relation === 'manyToMany' && orderColumnName === inverseOrderColumnName) {
|
if (attribute.relation === 'manyToMany' && orderColumnName === inverseOrderColumnName) {
|
||||||
inverseOrderColumnName = `inv_${inverseOrderColumnName}`;
|
inverseOrderColumnName = identifiers.getInverseOrderColumnName(meta.singularName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fkIndexName = identifiers.getFkIndexName(joinTableName); // TODO: joinTableName is multipart, can we re-use those parts instead of shortening the combined string?
|
||||||
|
const invFkIndexName = identifiers.getInverseFkIndexName(joinTableName);
|
||||||
|
|
||||||
const metadataSchema: Meta = {
|
const metadataSchema: Meta = {
|
||||||
singularName: joinTableName,
|
singularName: joinTableName,
|
||||||
uid: joinTableName,
|
uid: joinTableName,
|
||||||
tableName: joinTableName,
|
tableName: joinTableName,
|
||||||
attributes: {
|
attributes: {
|
||||||
id: {
|
[ID]: {
|
||||||
type: 'increments',
|
type: 'increments',
|
||||||
},
|
},
|
||||||
[joinColumnName]: {
|
[joinColumnName]: {
|
||||||
@ -472,32 +478,32 @@ const createJoinTable = (
|
|||||||
},
|
},
|
||||||
indexes: [
|
indexes: [
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_fk`,
|
name: fkIndexName,
|
||||||
columns: [joinColumnName],
|
columns: [joinColumnName],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_inv_fk`,
|
name: invFkIndexName,
|
||||||
columns: [inverseJoinColumnName],
|
columns: [inverseJoinColumnName],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_unique`,
|
name: identifiers.getUniqueIndexName(joinTableName),
|
||||||
columns: [joinColumnName, inverseJoinColumnName],
|
columns: [joinColumnName, inverseJoinColumnName],
|
||||||
type: 'unique',
|
type: 'unique',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
foreignKeys: [
|
foreignKeys: [
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_fk`,
|
name: fkIndexName,
|
||||||
columns: [joinColumnName],
|
columns: [joinColumnName],
|
||||||
referencedColumns: ['id'],
|
referencedColumns: [ID],
|
||||||
referencedTable: meta.tableName,
|
referencedTable: meta.tableName, // TODO: does this need to be wrapped or do we trust meta.tableName to be the right shortened version?
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${joinTableName}_inv_fk`,
|
name: invFkIndexName,
|
||||||
columns: [inverseJoinColumnName],
|
columns: [inverseJoinColumnName],
|
||||||
referencedColumns: ['id'],
|
referencedColumns: [ID],
|
||||||
referencedTable: targetMeta.tableName,
|
referencedTable: targetMeta.tableName, // TODO: does this need to be wrapped or do we trust meta.tableName to be the right shortened version?
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -509,11 +515,11 @@ const createJoinTable = (
|
|||||||
name: joinTableName,
|
name: joinTableName,
|
||||||
joinColumn: {
|
joinColumn: {
|
||||||
name: joinColumnName,
|
name: joinColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
},
|
},
|
||||||
inverseJoinColumn: {
|
inverseJoinColumn: {
|
||||||
name: inverseJoinColumnName,
|
name: inverseJoinColumnName,
|
||||||
referencedColumn: 'id',
|
referencedColumn: ID,
|
||||||
},
|
},
|
||||||
pivotColumns: [joinColumnName, inverseJoinColumnName],
|
pivotColumns: [joinColumnName, inverseJoinColumnName],
|
||||||
} as any;
|
} as any;
|
||||||
@ -528,7 +534,7 @@ const createJoinTable = (
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
metadataSchema.indexes.push({
|
metadataSchema.indexes.push({
|
||||||
name: `${joinTableName}_order_fk`,
|
name: identifiers.getOrderFkIndexName(joinTableName), // TODO: should we send joinTableName as parts?
|
||||||
columns: [orderColumnName],
|
columns: [orderColumnName],
|
||||||
});
|
});
|
||||||
joinTable.orderColumnName = orderColumnName;
|
joinTable.orderColumnName = orderColumnName;
|
||||||
@ -546,7 +552,7 @@ const createJoinTable = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
metadataSchema.indexes.push({
|
metadataSchema.indexes.push({
|
||||||
name: `${joinTableName}_order_inv_fk`,
|
name: identifiers.getOrderInverseFkIndexName(joinTableName),
|
||||||
columns: [inverseOrderColumnName],
|
columns: [inverseOrderColumnName],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export const getNameFromTokens = (tokens: NameToken[], max: number = MAX_DB_IDEN
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Generic name handler used by all helper functions
|
// Generic name handler used by all helper functions
|
||||||
export const getName = (names: NameInput, options: NameOptions) => {
|
export const getName = (names: NameInput, options: NameOptions = {}) => {
|
||||||
const tokens = _.castArray(names).map((name) => {
|
const tokens = _.castArray(names).map((name) => {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
@ -61,7 +61,6 @@ export const getName = (names: NameInput, options: NameOptions) => {
|
|||||||
* TABLES
|
* TABLES
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Get a base table name for a model
|
|
||||||
export const getTableName = (name: string, options?: NameOptions) => {
|
export const getTableName = (name: string, options?: NameOptions) => {
|
||||||
const tokens = [
|
const tokens = [
|
||||||
{
|
{
|
||||||
@ -93,7 +92,10 @@ export const getMorphTableName = (collectionName: string, attributeName: string)
|
|||||||
* COLUMNS
|
* COLUMNS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Regular relation join tables
|
export const getColumnName = (attributeName: string) => {
|
||||||
|
return getName(attributeName);
|
||||||
|
};
|
||||||
|
|
||||||
export const getJoinColumnEntityIdName = () => {
|
export const getJoinColumnEntityIdName = () => {
|
||||||
return getName(ENTITY, { suffix: 'id' });
|
return getName(ENTITY, { suffix: 'id' });
|
||||||
};
|
};
|
||||||
@ -102,7 +104,25 @@ export const getJoinColumnAttributeIdName = (attributeName: string) => {
|
|||||||
return getName(attributeName, { suffix: 'id' });
|
return getName(attributeName, { suffix: 'id' });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Morph Join Tables
|
export const getJoinColumnIdName = (singularName: string) => {
|
||||||
|
return getName(singularName, { suffix: 'id' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInverseJoinColumnIdName = (singularName: string) => {
|
||||||
|
return getName(singularName, { suffix: 'id', prefix: 'inv' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOrderColumnName = (singularName: string) => {
|
||||||
|
return getName(singularName, { suffix: 'order' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInverseOrderColumnName = (singularName: string) => {
|
||||||
|
return getName(singularName, { suffix: 'order', prefix: 'inv' });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Morph Join Tables
|
||||||
|
*/
|
||||||
export const getMorphColumnJoinTableIdName = (singularName: string) => {
|
export const getMorphColumnJoinTableIdName = (singularName: string) => {
|
||||||
return getName(singularName, { suffix: 'id' });
|
return getName(singularName, { suffix: 'id' });
|
||||||
};
|
};
|
||||||
@ -127,6 +147,18 @@ export const getFkIndexName = (names: NameInput) => {
|
|||||||
return getName(names, { suffix: 'fk' });
|
return getName(names, { suffix: 'fk' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getInverseFkIndexName = (names: NameInput) => {
|
||||||
|
return getName(names, { suffix: 'inv_fk' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOrderFkIndexName = (names: NameInput) => {
|
||||||
|
return getName(names, { suffix: 'order_fk' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOrderInverseFkIndexName = (names: NameInput) => {
|
||||||
|
return getName(names, { suffix: 'order_inv_fk' });
|
||||||
|
};
|
||||||
|
|
||||||
export const getUniqueIndexName = (names: NameInput) => {
|
export const getUniqueIndexName = (names: NameInput) => {
|
||||||
return getName(names, { suffix: 'unique' });
|
return getName(names, { suffix: 'unique' });
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { getJoinTableName } from '../../metadata';
|
|
||||||
|
|
||||||
import type { Database } from '../..';
|
import type { Database } from '../..';
|
||||||
import type { Relation } from '../../types';
|
import type { Relation } from '../../types';
|
||||||
|
import { getJoinTableName } from '../../utils/identifiers';
|
||||||
|
|
||||||
type Link = {
|
type Link = {
|
||||||
relation: Relation.Bidirectional & { inversedBy: string };
|
relation: Relation.Bidirectional & { inversedBy: string };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user