{#if datatableTreeLoading && (datatableTree?.length ?? 0) === 0}
Loading...
{/if} {#each treeRoots as root (root.datatable ?? '')} {@const dtOpen = isExpanded(root.datatable)} {#if root.datatable !== undefined} {@const hasMenu = !multiSelectMode && onDatatableAction !== undefined} {/if} {#if dtOpen} {#if root.error}

{root.error}

{/if} {#each root.schemas as sc (sc.schemaKey)} {@const schemaOpen = isExpanded(root.datatable, sc.schemaKey)} {@const indent = root.datatable !== undefined ? 'pl-7' : 'pl-3'} {#if dbSupportsSchemas} {/if} {#if schemaOpen || !dbSupportsSchemas} {@const tableIndent = dbSupportsSchemas ? root.datatable !== undefined ? 'pl-11' : 'pl-7' : root.datatable !== undefined ? 'pl-7' : 'pl-3'} {#each sc.tables as tableKey (tableKey)} {@const entry = { datatable: root.datatable, schema: sc.schemaKey, table: tableKey }} {@const hasMenu = !multiSelectMode} {@const isSelected = root.datatable === currentDatatable && selected.schemaKey === sc.schemaKey && selected.tableKey === tableKey} {/each} {/if} {/each} {#if dbSupportsSchemas && search.trim() === ''} {/if} {/if} {/each}
{#if tableKey && colDefs?.[tableKey]?.length} {@const dbTableOps = dbTableOpsFactory({ colDefs: colDefs[tableKey], tableKey })} {:else if databaseIsEmpty}
Database is empty {#if onImport}
{#if !!$userStore?.is_admin || !!$superadmin} {/if}
{/if}
{/if}
(schemaPermissionsOpen = false)} /> (askingForConfirmation = undefined)} on:confirmed={askingForConfirmation?.onConfirm ?? (() => {})} /> (dbTableEditorState = { open: false })} > (dbTableEditorState = { open: false })} title={dbTableEditorState.alterTableKey ? `Alter ${dbTableEditorState.alterTableKey}` : 'Create a new table'} > {#key dbTableEditorState.alterTableKey} {#if !dbTableEditorState.alterTableKey || dbTableEditorAlterTableData.current} { if (dbTableEditorState.alterTableKey && dbTableEditorAlterTableData.current) { let diff = diffTableEditorValues(dbTableEditorAlterTableData.current, values) // Reverse diff (new → old) so the migration's down undoes the alter. let reverse = diffTableEditorValues(values, dbTableEditorAlterTableData.current) await dbSchemaOps.onAlter({ schema: selected.schemaKey, values: diff, reverse }) } else { await dbSchemaOps.onCreate({ values, schema: selected.schemaKey }) } refresh?.() sendUserToast( dbTableEditorState.alterTableKey ? dbTableEditorState.alterTableKey + ' updated!' : values.name + ' created!' ) dbTableEditorState = { open: false } }} {dbType} computePreview={async ({ values }) => { if (dbTableEditorState.alterTableKey && dbTableEditorAlterTableData.current) { let diff = diffTableEditorValues(dbTableEditorAlterTableData.current, values) let sql = await dbSchemaOps.previewAlterSql({ values: diff, schema: selected.schemaKey }) let alert = !dbSupportsTransactionalDdl(dbType) ? { title: capitalize(dbType) + ' does not support transactional DDL', body: 'Any of these statements failing may leave your database in an intermediate state.' } : undefined return { sql, ...(alert ? { alert } : {}) } } else { let sql = await dbSchemaOps.previewCreateSql({ values, schema: selected.schemaKey }) return { sql } } }} computeBtnProps={({ values }) => { if (dbTableEditorState.alterTableKey && dbTableEditorAlterTableData.current) { let diff = diffTableEditorValues(dbTableEditorAlterTableData.current, values) if (!diff.operations.length) { return { text: 'No changes detected', disabled: true } } return { text: `Alter table (${pluralize(diff.operations.length, 'change')} detected)` } } else { return { text: 'Create table' } } }} /> {:else if dbTableEditorAlterTableData.loading || !colDefs} {:else}

Failed to load table definition.

{dbTableEditorAlterTableData.error}

{/if} {/key}
{ newSchemaDialogOpen = false newSchemaName = '' }} > { newSchemaDialogOpen = false newSchemaName = '' }} title="Create a new schema" >
{ if (e.key === 'Enter' && sanitizedNewSchemaName && !schemaAlreadyExists) { askingForConfirmation = { confirmationText: `Create ${sanitizedNewSchemaName}`, type: 'reload', title: `This will run 'CREATE SCHEMA ${sanitizedNewSchemaName}' on your database. Are you sure?`, open: true, id: 'db-create-schema-confirmation-modal', onConfirm: async () => { askingForConfirmation && (askingForConfirmation.loading = true) try { await dbSchemaOps.onCreateSchema({ schema: sanitizedNewSchemaName }) refresh?.() selected.schemaKey = sanitizedNewSchemaName newSchemaDialogOpen = false newSchemaName = '' } finally { askingForConfirmation = undefined } } } } }} /> {#if schemaAlreadyExists}

Schema "{sanitizedNewSchemaName}" already exists

{:else}

Only letters, numbers, and underscores are allowed.

{/if}
{#snippet actions()} {/snippet}