MCPcopy Index your code
hub / github.com/simstudioai/sim / restoreTable

Function restoreTable

apps/sim/lib/table/service.ts:613–678  ·  view source on GitHub ↗
(tableId: string, requestId: string)

Source from the content-addressed store, hash-verified

611 * Restores an archived table.
612 */
613export async function restoreTable(tableId: string, requestId: string): Promise<void> {
614 const table = await getTableById(tableId, { includeArchived: true })
615 if (!table) {
616 throw new Error('Table not found')
617 }
618
619 if (!table.archivedAt) {
620 throw new Error('Table is not archived')
621 }
622
623 if (table.workspaceId) {
624 const { getWorkspaceWithOwner } = await import('@/lib/workspaces/permissions/utils')
625 const ws = await getWorkspaceWithOwner(table.workspaceId)
626 if (!ws || ws.archivedAt) {
627 throw new Error('Cannot restore table into an archived workspace')
628 }
629 }
630
631 /**
632 * A concurrent rename/create can claim the chosen name after `generateRestoreName`'s check (MVCC).
633 * Retries pick a new random suffix; 23505 maps to {@link TableConflictError} after exhaustion.
634 */
635 const maxUniqueViolationRetries = 8
636 let attemptedRestoreName = ''
637
638 for (let attempt = 0; attempt < maxUniqueViolationRetries; attempt++) {
639 attemptedRestoreName = ''
640 try {
641 await db.transaction(async (tx) => {
642 await setTableTxTimeouts(tx)
643 await tx.execute(sql`SELECT 1 FROM user_table_definitions WHERE id = ${tableId} FOR UPDATE`)
644
645 attemptedRestoreName = await generateRestoreName(table.name, async (candidate) => {
646 const [match] = await tx
647 .select({ id: userTableDefinitions.id })
648 .from(userTableDefinitions)
649 .where(
650 and(
651 eq(userTableDefinitions.workspaceId, table.workspaceId),
652 eq(userTableDefinitions.name, candidate),
653 isNull(userTableDefinitions.archivedAt)
654 )
655 )
656 .limit(1)
657 return !!match
658 })
659
660 const now = new Date()
661 await tx
662 .update(userTableDefinitions)
663 .set({ archivedAt: null, updatedAt: now, name: attemptedRestoreName })
664 .where(eq(userTableDefinitions.id, tableId))
665 })
666 break
667 } catch (error: unknown) {
668 if (getPostgresErrorCode(error) !== '23505') {
669 throw error
670 }

Callers 1

performRestoreTableFunction · 0.90

Calls 9

setTableTxTimeoutsFunction · 0.90
generateRestoreNameFunction · 0.90
getPostgresErrorCodeFunction · 0.90
getTableByIdFunction · 0.85
getWorkspaceWithOwnerFunction · 0.85
infoMethod · 0.80
executeMethod · 0.65
setMethod · 0.65
eqFunction · 0.50

Tested by

no test coverage detected