diff --git a/packages/db-postgres/src/schema/build.ts b/packages/db-postgres/src/schema/build.ts index ec1b9f8ce1..f1158a56ff 100644 --- a/packages/db-postgres/src/schema/build.ts +++ b/packages/db-postgres/src/schema/build.ts @@ -21,6 +21,7 @@ import { Relation, relations } from 'drizzle-orm'; import { fieldAffectsData } from 'payload/dist/fields/config/types'; import { GenericColumns, GenericTable, PostgresAdapter } from '../types'; import { traverseFields } from './traverseFields'; +import { parentIDColumnMap } from './parentIDColumnMap'; type Args = { adapter: PostgresAdapter @@ -56,9 +57,18 @@ export const buildTable = ({ const arrayBlockRelations: Map = new Map(); const idField = fields.find((field) => fieldAffectsData(field) && field.name === 'id'); + let idColType = 'integer'; if (idField) { - columns.id = idField.type === 'number' ? integer('id').primaryKey() : text('id').primaryKey(); + if (idField.type === 'number') { + idColType = 'numeric'; + columns.id = numeric('id').primaryKey(); + } + + if (idField.type === 'text') { + idColType = 'varchar'; + columns.id = varchar('id').primaryKey(); + } } else { columns.id = serial('id').primaryKey(); } @@ -89,7 +99,7 @@ export const buildTable = ({ const localeTableName = `${formattedTableName}_locales`; localesColumns.id = integer('id').primaryKey(); localesColumns._locale = adapter.enums._locales('_locale').notNull(); - localesColumns._parentID = integer('_parent_id').references(() => table.id).notNull(); + localesColumns._parentID = parentIDColumnMap[idColType]('_parent_id').references(() => table.id).notNull(); localesTable = pgTable(localeTableName, localesColumns, (cols) => { return Object.entries(localesIndexes).reduce((acc, [colName, func]) => { @@ -114,7 +124,7 @@ export const buildTable = ({ if (relationships.size) { const relationshipColumns: Record = { id: serial('id').primaryKey(), - parent: integer('parent_id').references(() => table.id).notNull(), + parent: parentIDColumnMap[idColType]('parent_id').references(() => table.id).notNull(), path: varchar('path').notNull(), order: integer('order'), }; diff --git a/packages/db-postgres/src/schema/parentIDColumnMap.ts b/packages/db-postgres/src/schema/parentIDColumnMap.ts new file mode 100644 index 0000000000..e6e3965b9a --- /dev/null +++ b/packages/db-postgres/src/schema/parentIDColumnMap.ts @@ -0,0 +1,7 @@ +import { integer, numeric, varchar } from 'drizzle-orm/pg-core'; + +export const parentIDColumnMap = { + integer, + varchar, + numeric, +}; diff --git a/packages/db-postgres/src/schema/traverseFields.ts b/packages/db-postgres/src/schema/traverseFields.ts index bb0aac2625..b0f73096d2 100644 --- a/packages/db-postgres/src/schema/traverseFields.ts +++ b/packages/db-postgres/src/schema/traverseFields.ts @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign */ -import { AnyPgColumnBuilder, integer, pgEnum, pgTable, serial, uniqueIndex, text, varchar, PgColumn, PgTableExtraConfig, index, numeric, PgColumnHKT, IndexBuilder } from 'drizzle-orm/pg-core'; +import { AnyPgColumnBuilder, integer, pgEnum, pgTable, serial, uniqueIndex, text, varchar, PgColumn, PgTableExtraConfig, index, numeric, PgColumnHKT, IndexBuilder, PgNumericBuilder, PgVarcharBuilder } from 'drizzle-orm/pg-core'; import { Field } from 'payload/types'; import toSnakeCase from 'to-snake-case'; import { fieldAffectsData } from 'payload/dist/fields/config/types'; @@ -7,6 +7,7 @@ import { Relation, relations } from 'drizzle-orm'; import { GenericColumns, PostgresAdapter } from '../types'; import { createIndex } from './createIndex'; import { buildTable } from './build'; +import { parentIDColumnMap } from './parentIDColumnMap'; type Args = { adapter: PostgresAdapter @@ -39,7 +40,12 @@ export const traverseFields = ({ }: Args): { hasLocalizedField: boolean } => { let hasLocalizedField = false; + let parentIDColType = 'integer'; + if (columns.id instanceof PgNumericBuilder) parentIDColType = 'numeric'; + if (columns.id instanceof PgVarcharBuilder) parentIDColType = 'varchar'; + fields.forEach((field) => { + if ('name' in field && field.name === 'id') return; let columnName: string; let targetTable = columns; @@ -78,7 +84,7 @@ export const traverseFields = ({ case 'array': { const baseColumns: Record = { _order: integer('_order').notNull(), - _parentID: integer('_parent_id').references(() => adapter.tables[tableName].id).notNull(), + _parentID: parentIDColumnMap[parentIDColType]('_parent_id').references(() => adapter.tables[tableName].id).notNull(), }; if (field.localized && adapter.payload.config.localization) { @@ -125,7 +131,7 @@ export const traverseFields = ({ const baseColumns: Record = { _order: integer('_order').notNull(), _path: text('_path').notNull(), - _parentID: integer('_parent_id').references(() => adapter.tables[tableName].id).notNull(), + _parentID: parentIDColumnMap[parentIDColType]('_parent_id').references(() => adapter.tables[tableName].id).notNull(), }; if (field.localized && adapter.payload.config.localization) { @@ -183,7 +189,7 @@ export const traverseFields = ({ indexes, localesColumns, localesIndexes, - tableName: `${tableName}_${toSnakeCase(field.name)}`, + tableName, relationships, }); @@ -192,6 +198,43 @@ export const traverseFields = ({ break; } + case 'tabs': { + field.tabs.forEach((tab) => { + if ('name' in tab) { + const { hasLocalizedField: tabHasLocalizedField } = traverseFields({ + adapter, + arrayBlockRelations, + buildRelationships, + columnPrefix: `${columnName}_`, + columns, + fieldPrefix: `${fieldPrefix || ''}${tab.name}_`, + fields: tab.fields, + indexes, + localesColumns, + localesIndexes, + tableName, + relationships, + }); + + if (tabHasLocalizedField) hasLocalizedField = true; + } else { + ({ hasLocalizedField } = traverseFields({ + adapter, + arrayBlockRelations, + buildRelationships, + columns, + fields: tab.fields, + indexes, + localesColumns, + localesIndexes, + tableName, + relationships, + })); + } + }); + break; + } + case 'row': ({ hasLocalizedField } = traverseFields({ adapter,