98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
/* eslint-disable no-param-reassign */
|
|
import type { ArrayRowToInsert } from '../transform/write/types.js'
|
|
import type { DrizzleDB, PostgresAdapter } from '../types.js'
|
|
|
|
type Args = {
|
|
adapter: PostgresAdapter
|
|
arrays: {
|
|
[tableName: string]: ArrayRowToInsert[]
|
|
}[]
|
|
db: DrizzleDB
|
|
parentRows: Record<string, unknown>[]
|
|
}
|
|
|
|
type RowsByTable = {
|
|
[tableName: string]: {
|
|
arrays: {
|
|
[tableName: string]: ArrayRowToInsert[]
|
|
}[]
|
|
locales: Record<string, unknown>[]
|
|
rows: Record<string, unknown>[]
|
|
}
|
|
}
|
|
|
|
export const insertArrays = async ({ adapter, arrays, db, parentRows }: Args): Promise<void> => {
|
|
// Maintain a map of flattened rows by table
|
|
const rowsByTable: RowsByTable = {}
|
|
|
|
arrays.forEach((arraysByTable, parentRowIndex) => {
|
|
Object.entries(arraysByTable).forEach(([tableName, arrayRows]) => {
|
|
// If the table doesn't exist in map, initialize it
|
|
if (!rowsByTable[tableName]) {
|
|
rowsByTable[tableName] = {
|
|
arrays: [],
|
|
locales: [],
|
|
rows: [],
|
|
}
|
|
}
|
|
|
|
const parentID = parentRows[parentRowIndex].id
|
|
|
|
// Add any sub arrays that need to be created
|
|
// We will call this recursively below
|
|
arrayRows.forEach((arrayRow, i) => {
|
|
if (Object.keys(arrayRow.arrays).length > 0) {
|
|
rowsByTable[tableName].arrays.push(arrayRow.arrays)
|
|
}
|
|
|
|
// Set up parent IDs for both row and locale row
|
|
arrayRow.row._parentID = parentID
|
|
rowsByTable[tableName].rows.push(arrayRow.row)
|
|
|
|
Object.entries(arrayRow.locales).forEach(([arrayRowLocale, arrayRowLocaleData]) => {
|
|
arrayRowLocaleData._parentID = arrayRow.row.id
|
|
arrayRowLocaleData._locale = arrayRowLocale
|
|
rowsByTable[tableName].locales.push(arrayRowLocaleData)
|
|
if (!arrayRow.row.id) {
|
|
arrayRowLocaleData._getParentID = (rows) => rows[i].id
|
|
}
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
// Insert all corresponding arrays
|
|
// (one insert per array table)
|
|
for (const [tableName, row] of Object.entries(rowsByTable)) {
|
|
// the nested arrays need the ID for the parentID foreign key
|
|
let insertedRows: Args['parentRows']
|
|
if (row.rows.length > 0) {
|
|
insertedRows = await db.insert(adapter.tables[tableName]).values(row.rows).returning()
|
|
}
|
|
|
|
// Insert locale rows
|
|
if (adapter.tables[`${tableName}_locales`] && row.locales.length > 0) {
|
|
if (!row.locales[0]._parentID) {
|
|
row.locales = row.locales.map((localeRow, i) => {
|
|
if (typeof localeRow._getParentID === 'function') {
|
|
localeRow._parentID = localeRow._getParentID(insertedRows)
|
|
delete localeRow._getParentID
|
|
}
|
|
return localeRow
|
|
})
|
|
}
|
|
await db.insert(adapter.tables[`${tableName}_locales`]).values(row.locales).returning()
|
|
}
|
|
|
|
// If there are sub arrays, call this function recursively
|
|
if (row.arrays.length > 0) {
|
|
await insertArrays({
|
|
adapter,
|
|
arrays: row.arrays,
|
|
db,
|
|
parentRows: insertedRows,
|
|
})
|
|
}
|
|
}
|
|
}
|