chore: handles blocks

This commit is contained in:
James
2023-08-02 21:37:06 -04:00
parent 3ccdcc5c29
commit bd464990ea
2 changed files with 130 additions and 6 deletions

View File

@@ -30,19 +30,22 @@ type Args = {
tableName: string
}
type Result = {
arrayBlockRelations: Map<string, string>
}
export const buildTable = ({
adapter,
baseColumns = {},
buildRelationships,
fields,
tableName,
}: Args): void => {
}: Args): Result => {
const formattedTableName = toSnakeCase(tableName);
const columns: Record<string, AnyPgColumnBuilder> = baseColumns;
const indexes: Record<string, (cols: GenericColumns) => IndexBuilder> = {};
let hasLocalizedField = false;
const localesColumns: Record<string, AnyPgColumnBuilder> = {};
const localesIndexes: Record<string, (cols: GenericColumns) => IndexBuilder> = {};
let localesTable: GenericTable;
@@ -50,6 +53,8 @@ export const buildTable = ({
const relationships: Set<string> = new Set();
let relationshipsTable: GenericTable;
const arrayBlockRelations: Map<string, string> = new Map();
const idField = fields.find((field) => fieldAffectsData(field) && field.name === 'id');
if (idField) {
@@ -60,6 +65,7 @@ export const buildTable = ({
({ hasLocalizedField } = traverseFields({
adapter,
arrayBlockRelations,
buildRelationships,
columns,
fields,
@@ -93,6 +99,15 @@ export const buildTable = ({
});
adapter.tables[localeTableName] = localesTable;
const localesTableRelations = relations(localesTable, ({ one }) => ({
_parentID: one(table, {
fields: [localesTable._parentID],
references: [table.id],
}),
}));
adapter.relations[localeTableName] = localesTableRelations;
}
if (buildRelationships) {
@@ -109,15 +124,42 @@ export const buildTable = ({
relationshipColumns[`${relationTo}ID`] = integer(`${formattedRelationTo}_id`).references(() => adapter.tables[formattedRelationTo].id);
});
relationshipsTable = pgTable(`${formattedTableName}_relationships`, relationshipColumns);
const relationshipsTableName = `${formattedTableName}_relationships`;
relationshipsTable = pgTable(relationshipsTableName, relationshipColumns);
adapter.tables[relationshipsTableName] = relationshipsTable;
adapter.tables[`${formattedTableName}_relationships`] = relationshipsTable;
const relationshipsTableRelations = relations(relationshipsTable, ({ one, many }) => {
const result: Record<string, Relation<string>> = {
parent: one(table, {
relationName: '_relationships',
fields: [relationshipsTable.parent],
references: [table.id],
}),
};
relationships.forEach((relationTo) => {
const relatedTableName = toSnakeCase(relationTo);
const idColumnName = `${relationTo}ID`;
result[idColumnName] = one(adapter.tables[relatedTableName], {
fields: [relationshipsTable[idColumnName]],
references: [adapter.tables[relatedTableName].id],
});
});
return result;
});
adapter.relations[relationshipsTableName] = relationshipsTableRelations;
}
}
const tableRelations = relations(table, ({ many }) => {
const result: Record<string, Relation<string>> = {};
arrayBlockRelations.forEach((val, key) => {
result[key] = many(adapter.tables[val]);
});
if (hasLocalizedField) {
result._locales = many(localesTable);
}
@@ -132,4 +174,6 @@ export const buildTable = ({
});
adapter.relations[`${formattedTableName}`] = tableRelations;
return { arrayBlockRelations };
};

View File

@@ -3,12 +3,14 @@ import { AnyPgColumnBuilder, integer, pgEnum, pgTable, serial, uniqueIndex, text
import { Field } from 'payload/types';
import toSnakeCase from 'to-snake-case';
import { fieldAffectsData } from 'payload/dist/fields/config/types';
import { Relation, relations } from 'drizzle-orm';
import { GenericColumns, PostgresAdapter } from '../types';
import { createIndex } from './createIndex';
import { buildTable } from './build';
type Args = {
adapter: PostgresAdapter
arrayBlockRelations: Map<string, string>
buildRelationships: boolean
columns: Record<string, AnyPgColumnBuilder>
columnPrefix?: string
@@ -23,6 +25,7 @@ type Args = {
export const traverseFields = ({
adapter,
arrayBlockRelations,
buildRelationships,
columnPrefix,
columns,
@@ -82,11 +85,86 @@ export const traverseFields = ({
baseColumns._locale = adapter.enums._locales('_locale').notNull();
}
buildTable({
const arrayTableName = `${tableName}_${toSnakeCase(field.name)}`;
const { arrayBlockRelations: subArrayBlockRelations } = buildTable({
adapter,
baseColumns,
fields: field.fields,
tableName: `${tableName}_${toSnakeCase(field.name)}`,
tableName: arrayTableName,
});
arrayBlockRelations.set(`${fieldPrefix || ''}${field.name}`, arrayTableName);
const arrayTableRelations = relations(adapter.tables[arrayTableName], ({ many, one }) => {
const result: Record<string, Relation<string>> = {
_parentID: one(adapter.tables[tableName], {
fields: [adapter.tables[arrayTableName]._parentID],
references: [adapter.tables[tableName].id],
}),
};
if (field.localized) {
result._locales = many(adapter.tables[`${arrayTableName}_locales`]);
}
subArrayBlockRelations.forEach((val, key) => {
result[key] = many(adapter.tables[val]);
});
return result;
});
adapter.relations[arrayTableName] = arrayTableRelations;
break;
}
case 'blocks': {
field.blocks.forEach((block) => {
const baseColumns: Record<string, AnyPgColumnBuilder> = {
_order: integer('_order').notNull(),
_path: text('_path').notNull(),
_parentID: integer('_parent_id').references(() => adapter.tables[tableName].id).notNull(),
};
if (field.localized && adapter.payload.config.localization) {
baseColumns._locale = adapter.enums._locales('_locale').notNull();
}
const blockTableName = `${tableName}_${toSnakeCase(block.slug)}`;
if (!adapter.tables[blockTableName]) {
const { arrayBlockRelations: subArrayBlockRelations } = buildTable({
adapter,
baseColumns,
fields: block.fields,
tableName: blockTableName,
});
const blockTableRelations = relations(adapter.tables[blockTableName], ({ many, one }) => {
const result: Record<string, Relation<string>> = {
_parentID: one(adapter.tables[tableName], {
fields: [adapter.tables[blockTableName]._parentID],
references: [adapter.tables[tableName].id],
}),
};
if (field.localized) {
result._locales = many(adapter.tables[`${blockTableName}_locales`]);
}
subArrayBlockRelations.forEach((val, key) => {
result[key] = many(adapter.tables[val]);
});
return result;
});
adapter.relations[blockTableName] = blockTableRelations;
}
arrayBlockRelations.set(`_${fieldPrefix || ''}${field.name}`, blockTableName);
});
break;
@@ -96,6 +174,7 @@ export const traverseFields = ({
// Todo: determine what should happen if groups are set to localized
const { hasLocalizedField: groupHasLocalizedField } = traverseFields({
adapter,
arrayBlockRelations,
buildRelationships,
columnPrefix: `${columnName}_`,
columns,
@@ -116,6 +195,7 @@ export const traverseFields = ({
case 'row':
({ hasLocalizedField } = traverseFields({
adapter,
arrayBlockRelations,
buildRelationships,
columns,
fields: field.fields,