diff --git a/mathesar/urls.py b/mathesar/urls.py index a0b438376d..8f80565ad0 100644 --- a/mathesar/urls.py +++ b/mathesar/urls.py @@ -61,7 +61,7 @@ path('i18n/', include('django.conf.urls.i18n')), re_path( r'^db/(?P\w+)/(?P\w+)/', - views.schema_home, + views.schemas, name='schema_home' ), ] diff --git a/mathesar/views.py b/mathesar/views.py index e88b596881..4199ee79ee 100644 --- a/mathesar/views.py +++ b/mathesar/views.py @@ -7,6 +7,7 @@ from rest_framework.decorators import api_view from rest_framework.response import Response +from mathesar.rpc.schemas import list_ as schemas_list from mathesar.api.db.permissions.database import DatabaseAccessPolicy from mathesar.api.db.permissions.query import QueryAccessPolicy from mathesar.api.db.permissions.schema import SchemaAccessPolicy @@ -26,14 +27,10 @@ def get_schema_list(request, database): - qs = Schema.objects.filter(database=database) - permission_restricted_qs = SchemaAccessPolicy.scope_queryset(request, qs) - schema_serializer = SchemaSerializer( - permission_restricted_qs, - many=True, - context={'request': request} - ) - return schema_serializer.data + if database is not None: + return schemas_list(request=request, database_id=database.id) + else: + return [] def _get_permissible_db_queryset(request): @@ -180,19 +177,6 @@ def get_current_database(request, connection_id): return current_database -def get_current_schema(request, schema_id, database): - # if there's a schema ID passed in, try to retrieve the schema, or return a 404 error. - if schema_id is not None: - permitted_schemas = SchemaAccessPolicy.scope_queryset(request, Schema.objects.all()) - return get_object_or_404(permitted_schemas, id=schema_id) - else: - try: - # Try to get the first schema in the DB - return Schema.objects.filter(database=database).order_by('id').first() - except Schema.DoesNotExist: - return None - - def render_schema(request, database, schema): # if there's no schema available, redirect to the schemas page. if not schema: @@ -300,16 +284,7 @@ def admin_home(request, **kwargs): @login_required -def schema_home(request, connection_id, schema_id, **kwargs): - database = get_current_database(request, connection_id) - schema = get_current_schema(request, schema_id, database) - return render(request, 'mathesar/index.html', { - 'common_data': get_common_data(request, database, schema) - }) - - -@login_required -def schemas(request, connection_id): +def schemas(request, connection_id, **kwargs): database = get_current_database(request, connection_id) return render(request, 'mathesar/index.html', { 'common_data': get_common_data(request, database, None) diff --git a/mathesar_ui/src/AppTypes.ts b/mathesar_ui/src/AppTypes.ts index 168d51b58d..a779ca063e 100644 --- a/mathesar_ui/src/AppTypes.ts +++ b/mathesar_ui/src/AppTypes.ts @@ -1,5 +1,3 @@ -import type { TreeItem } from '@mathesar-component-library/types'; - /** @deprecated in favor of Connection */ export interface Database { id: number; @@ -16,16 +14,6 @@ export interface DBObjectEntry { description: string | null; } -export interface SchemaEntry extends DBObjectEntry { - has_dependencies: boolean; - num_tables: number; - num_queries: number; -} - -export interface SchemaResponse extends SchemaEntry, TreeItem { - tables: DBObjectEntry[]; -} - export type DbType = string; export interface FilterConfiguration { diff --git a/mathesar_ui/src/api/rest/schemas.ts b/mathesar_ui/src/api/rest/schemas.ts deleted file mode 100644 index 9940035c0b..0000000000 --- a/mathesar_ui/src/api/rest/schemas.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { SchemaEntry, SchemaResponse } from '@mathesar/AppTypes'; - -import type { Connection } from './connections'; -import { - type PaginatedResponse, - deleteAPI, - getAPI, - patchAPI, - postAPI, -} from './utils/requestUtils'; - -function list(connectionId: Connection['id']) { - return getAPI>( - `/api/db/v0/schemas/?connection_id=${connectionId}&limit=500`, - ); -} - -function add(props: { - name: SchemaEntry['name']; - description: SchemaEntry['description']; - connectionId: Connection['id']; -}) { - return postAPI('/api/db/v0/schemas/', { - name: props.name, - description: props.description, - connection_id: props.connectionId, - }); -} - -function update(schema: { - id: SchemaEntry['id']; - name?: SchemaEntry['name']; - description?: SchemaEntry['description']; -}) { - return patchAPI(`/api/db/v0/schemas/${schema.id}/`, { - name: schema.name, - description: schema.description, - }); -} - -function deleteSchema(schemaId: SchemaEntry['id']) { - return deleteAPI(`/api/db/v0/schemas/${schemaId}/`); -} - -export default { - list, - add, - update, - delete: deleteSchema, -}; diff --git a/mathesar_ui/src/api/rest/types/queries.ts b/mathesar_ui/src/api/rest/types/queries.ts index 713f32c96a..6517eef56a 100644 --- a/mathesar_ui/src/api/rest/types/queries.ts +++ b/mathesar_ui/src/api/rest/types/queries.ts @@ -1,7 +1,7 @@ import type { Column } from '@mathesar/api/rest/types/tables/columns'; import type { JpPath } from '@mathesar/api/rest/types/tables/joinable_tables'; import type { PaginatedResponse } from '@mathesar/api/rest/utils/requestUtils'; -import type { SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; export type QueryColumnAlias = string; @@ -182,7 +182,7 @@ export interface QueryResultsResponse { export interface QueryRunResponse extends QueryResultsResponse { query: { - schema: SchemaEntry['id']; + schema: Schema['oid']; base_table: QueryInstance['base_table']; initial_columns: QueryInstanceInitialColumn[]; transformations?: QueryInstanceTransformation[]; diff --git a/mathesar_ui/src/api/rest/users.ts b/mathesar_ui/src/api/rest/users.ts index 1020ccc448..477d881d68 100644 --- a/mathesar_ui/src/api/rest/users.ts +++ b/mathesar_ui/src/api/rest/users.ts @@ -1,4 +1,5 @@ -import type { Database, SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; +import type { Database } from '@mathesar/AppTypes'; import type { Language } from '@mathesar/i18n/languages/utils'; import { @@ -27,7 +28,7 @@ export interface DatabaseRole { export interface SchemaRole { id: number; - schema: SchemaEntry['id']; + schema: Schema['oid']; role: UserRole; } @@ -92,7 +93,7 @@ function deleteDatabaseRole(roleId: DatabaseRole['id']) { function addSchemaRole( userId: User['id'], - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], role: UserRole, ) { return postAPI('/api/ui/v0/schema_roles/', { diff --git a/mathesar_ui/src/api/rpc/index.ts b/mathesar_ui/src/api/rpc/index.ts index 0ed7c027c2..e9a3b3c531 100644 --- a/mathesar_ui/src/api/rpc/index.ts +++ b/mathesar_ui/src/api/rpc/index.ts @@ -3,6 +3,7 @@ import Cookies from 'js-cookie'; import { buildRpcApi } from '@mathesar/packages/json-rpc-client-builder'; import { connections } from './connections'; +import { schemas } from './schemas'; /** Mathesar's JSON-RPC API */ export const api = buildRpcApi({ @@ -10,5 +11,6 @@ export const api = buildRpcApi({ getHeaders: () => ({ 'X-CSRFToken': Cookies.get('csrftoken') }), methodTree: { connections, + schemas, }, }); diff --git a/mathesar_ui/src/api/rpc/schemas.ts b/mathesar_ui/src/api/rpc/schemas.ts new file mode 100644 index 0000000000..486a7d4728 --- /dev/null +++ b/mathesar_ui/src/api/rpc/schemas.ts @@ -0,0 +1,47 @@ +import { rpcMethodTypeContainer } from '@mathesar/packages/json-rpc-client-builder'; + +export interface Schema { + oid: number; + name: string; + description: string; + table_count: number; +} + +export const schemas = { + list: rpcMethodTypeContainer< + { + database_id: number; + }, + Schema[] + >(), + + /** Returns the OID of the newly-created schema */ + add: rpcMethodTypeContainer< + { + database_id: number; + name: string; + description?: string; + }, + number + >(), + + patch: rpcMethodTypeContainer< + { + database_id: number; + schema_oid: number; + patch: { + name?: string; + description?: string; + }; + }, + void + >(), + + delete: rpcMethodTypeContainer< + { + database_id: number; + schema_oid: number; + }, + void + >(), +}; diff --git a/mathesar_ui/src/components/AppHeader.svelte b/mathesar_ui/src/components/AppHeader.svelte index 0fa38e1483..3bc094ebca 100644 --- a/mathesar_ui/src/components/AppHeader.svelte +++ b/mathesar_ui/src/components/AppHeader.svelte @@ -62,7 +62,7 @@ isCreatingNewEmptyTable = true; const tableInfo = await createTable(database, schema, {}); isCreatingNewEmptyTable = false; - router.goto(getTablePageUrl(database.id, schema.id, tableInfo.id), false); + router.goto(getTablePageUrl(database.id, schema.oid, tableInfo.id), false); } @@ -90,14 +90,14 @@ {$_('new_table_from_data_import')} {/if} {$_('open_data_explorer')} diff --git a/mathesar_ui/src/components/SchemaName.svelte b/mathesar_ui/src/components/SchemaName.svelte index e6fa7cf638..d3a0199027 100644 --- a/mathesar_ui/src/components/SchemaName.svelte +++ b/mathesar_ui/src/components/SchemaName.svelte @@ -1,10 +1,10 @@ diff --git a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte index 734923fb38..477ec9ee99 100644 --- a/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte +++ b/mathesar_ui/src/pages/database/AddEditSchemaModal.svelte @@ -2,7 +2,8 @@
-

- {$_('count_tables', { values: { count: schema.num_tables } })} -

- -

- {$_('count_explorations', { values: { count: schema.num_queries } })} +

+ {$_('count_tables', { values: { count: schema.table_count } })}

diff --git a/mathesar_ui/src/pages/database/SchemaRow.svelte b/mathesar_ui/src/pages/database/SchemaRow.svelte index 6eb6c24f72..534cec6534 100644 --- a/mathesar_ui/src/pages/database/SchemaRow.svelte +++ b/mathesar_ui/src/pages/database/SchemaRow.svelte @@ -2,7 +2,8 @@ import { createEventDispatcher } from 'svelte'; import { _ } from 'svelte-i18n'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import DropdownMenu from '@mathesar/component-library/dropdown-menu/DropdownMenu.svelte'; import MenuDivider from '@mathesar/component-library/menu/MenuDivider.svelte'; import InfoBox from '@mathesar/components/message-boxes/InfoBox.svelte'; @@ -21,13 +22,13 @@ const dispatch = createEventDispatcher(); export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let canExecuteDDL = true; let isHovered = false; let isFocused = false; - $: href = getSchemaPageUrl(database.id, schema.id); + $: href = getSchemaPageUrl(database.id, schema.oid); $: isDefault = schema.name === 'public'; $: isLocked = schema.name === 'public'; diff --git a/mathesar_ui/src/pages/exploration/ExplorationPage.svelte b/mathesar_ui/src/pages/exploration/ExplorationPage.svelte index c5372c4f36..be676788a6 100644 --- a/mathesar_ui/src/pages/exploration/ExplorationPage.svelte +++ b/mathesar_ui/src/pages/exploration/ExplorationPage.svelte @@ -3,7 +3,8 @@ import { router } from 'tinro'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import LayoutWithHeader from '@mathesar/layouts/LayoutWithHeader.svelte'; import { getSchemaPageUrl } from '@mathesar/routes/urls'; import { currentDbAbstractTypes } from '@mathesar/stores/abstract-types'; @@ -22,7 +23,7 @@ const userProfile = getUserProfileStoreFromContext(); export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let query: QueryInstance; export let shareConsumer: ShareConsumer | undefined = undefined; @@ -51,7 +52,7 @@ $: createQueryRunner(query, $currentDbAbstractTypes.data); function gotoSchemaPage() { - router.goto(getSchemaPageUrl(database.id, schema.id)); + router.goto(getSchemaPageUrl(database.id, schema.oid)); } diff --git a/mathesar_ui/src/pages/exploration/Header.svelte b/mathesar_ui/src/pages/exploration/Header.svelte index 5a96c39484..d3ec06a273 100644 --- a/mathesar_ui/src/pages/exploration/Header.svelte +++ b/mathesar_ui/src/pages/exploration/Header.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import EntityPageHeader from '@mathesar/components/EntityPageHeader.svelte'; import { iconExploration, iconInspector } from '@mathesar/icons'; import { getExplorationEditorPageUrl } from '@mathesar/routes/urls'; @@ -11,7 +12,7 @@ import ShareExplorationDropdown from './ShareExplorationDropdown.svelte'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let query: QueryInstance; export let isInspectorOpen = true; export let canEditMetadata: boolean; @@ -30,7 +31,7 @@ {#if canEditMetadata} {$_('edit_in_data_explorer')} diff --git a/mathesar_ui/src/pages/import/preview/ImportPreviewContent.svelte b/mathesar_ui/src/pages/import/preview/ImportPreviewContent.svelte index b6359e8e2c..838161b297 100644 --- a/mathesar_ui/src/pages/import/preview/ImportPreviewContent.svelte +++ b/mathesar_ui/src/pages/import/preview/ImportPreviewContent.svelte @@ -6,7 +6,8 @@ import type { DataFile } from '@mathesar/api/rest/types/dataFiles'; import type { TableEntry } from '@mathesar/api/rest/types/tables'; import type { Column } from '@mathesar/api/rest/types/tables/columns'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import { Field, FieldLayout, @@ -60,7 +61,7 @@ const cancelationRequest = makeDeleteTableRequest(); export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let table: TableEntry; export let dataFile: DataFile; export let useColumnTypeInference = false; @@ -108,7 +109,7 @@ }) { const tableId = props.table?.id ?? table.id; router.goto( - getImportPreviewPageUrl(database.id, schema.id, tableId, { + getImportPreviewPageUrl(database.id, schema.oid, tableId, { useColumnTypeInference: props.useColumnTypeInference ?? useColumnTypeInference, }), @@ -146,7 +147,7 @@ async function cancel() { const response = await cancelationRequest.run({ database, schema, table }); if (response.isOk) { - router.goto(getSchemaPageUrl(database.id, schema.id), true); + router.goto(getSchemaPageUrl(database.id, schema.oid), true); } else { toast.fromError(response.error); } @@ -159,7 +160,7 @@ import_verified: true, columns: finalizeColumns(columns, columnPropertiesMap), }); - router.goto(getTablePageUrl(database.id, schema.id, table.id), true); + router.goto(getTablePageUrl(database.id, schema.oid, table.id), true); } catch (err) { toast.fromError(err); } diff --git a/mathesar_ui/src/pages/import/preview/ImportPreviewPage.svelte b/mathesar_ui/src/pages/import/preview/ImportPreviewPage.svelte index d67efa353b..775b6d0712 100644 --- a/mathesar_ui/src/pages/import/preview/ImportPreviewPage.svelte +++ b/mathesar_ui/src/pages/import/preview/ImportPreviewPage.svelte @@ -3,7 +3,8 @@ import { router } from 'tinro'; import { dataFilesApi } from '@mathesar/api/rest/dataFiles'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import ErrorBox from '@mathesar/components/message-boxes/ErrorBox.svelte'; import { makeSimplePageTitle } from '@mathesar/pages/pageTitleUtils'; import { getTablePageUrl } from '@mathesar/routes/urls'; @@ -19,12 +20,12 @@ const dataFileFetch = new AsyncStore(dataFilesApi.get); export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let tableId: number; export let useColumnTypeInference = false; function redirectToTablePage() { - router.goto(getTablePageUrl(database.id, schema.id, tableId)); + router.goto(getTablePageUrl(database.id, schema.oid, tableId)); } $: void (async () => { diff --git a/mathesar_ui/src/pages/import/preview/importPreviewPageUtils.ts b/mathesar_ui/src/pages/import/preview/importPreviewPageUtils.ts index 262ae59480..6d7474ca8c 100644 --- a/mathesar_ui/src/pages/import/preview/importPreviewPageUtils.ts +++ b/mathesar_ui/src/pages/import/preview/importPreviewPageUtils.ts @@ -5,7 +5,8 @@ import type { TableEntry, } from '@mathesar/api/rest/types/tables'; import type { Column } from '@mathesar/api/rest/types/tables/columns'; -import type { Database, SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; +import type { Database } from '@mathesar/AppTypes'; import { getCellCap } from '@mathesar/components/cell-fabric/utils'; import { getAbstractTypeForDbType } from '@mathesar/stores/abstract-types'; import type { @@ -51,7 +52,7 @@ export function processColumns( export function makeHeaderUpdateRequest() { interface Props { database: Database; - schema: SchemaEntry; + schema: Schema; table: Pick; dataFile: Pick; firstRowIsHeader: boolean; @@ -73,7 +74,7 @@ export function makeHeaderUpdateRequest() { export function makeDeleteTableRequest() { interface Props { database: Database; - schema: SchemaEntry; + schema: Schema; table: Pick; } return new AsyncStore((props: Props) => diff --git a/mathesar_ui/src/pages/import/upload/ImportUploadPage.svelte b/mathesar_ui/src/pages/import/upload/ImportUploadPage.svelte index 35704c6d47..64c670d4d1 100644 --- a/mathesar_ui/src/pages/import/upload/ImportUploadPage.svelte +++ b/mathesar_ui/src/pages/import/upload/ImportUploadPage.svelte @@ -4,7 +4,8 @@ import { dataFilesApi } from '@mathesar/api/rest/dataFiles'; import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import Spinner from '@mathesar/component-library/spinner/Spinner.svelte'; import DocsLink from '@mathesar/components/DocsLink.svelte'; import { @@ -37,7 +38,7 @@ import DataFileInput from './DataFileInput.svelte'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; interface UploadMethod { key: 'file' | 'url' | 'clipboard'; @@ -117,7 +118,7 @@ }); const previewPage = getImportPreviewPageUrl( database.id, - schema.id, + schema.oid, table.id, { useColumnTypeInference: $useColumnTypeInference }, ); diff --git a/mathesar_ui/src/pages/schema/CreateEmptyTableButton.svelte b/mathesar_ui/src/pages/schema/CreateEmptyTableButton.svelte index 1d95dcea92..6e288c5312 100644 --- a/mathesar_ui/src/pages/schema/CreateEmptyTableButton.svelte +++ b/mathesar_ui/src/pages/schema/CreateEmptyTableButton.svelte @@ -1,13 +1,14 @@ diff --git a/mathesar_ui/src/pages/schema/CreateNewExplorationTutorial.svelte b/mathesar_ui/src/pages/schema/CreateNewExplorationTutorial.svelte index 9592e2677a..ea2eebf2f6 100644 --- a/mathesar_ui/src/pages/schema/CreateNewExplorationTutorial.svelte +++ b/mathesar_ui/src/pages/schema/CreateNewExplorationTutorial.svelte @@ -1,12 +1,13 @@ @@ -18,7 +19,7 @@ {$_('open_data_explorer')} diff --git a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte index 2bb296e493..9a22b3733e 100644 --- a/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte +++ b/mathesar_ui/src/pages/schema/CreateNewTableButton.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import { router } from 'tinro'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import Icon from '@mathesar/component-library/icon/Icon.svelte'; import LinkMenuItem from '@mathesar/component-library/menu/LinkMenuItem.svelte'; import { iconAddNew } from '@mathesar/icons'; @@ -15,7 +16,7 @@ } from '@mathesar-component-library'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; let isCreatingNewTable = false; @@ -23,7 +24,7 @@ isCreatingNewTable = true; const tableInfo = await createTable(database, schema, {}); isCreatingNewTable = false; - router.goto(getTablePageUrl(database.id, schema.id, tableInfo.id), false); + router.goto(getTablePageUrl(database.id, schema.oid, tableInfo.id), false); } @@ -44,7 +45,7 @@ {$_('from_scratch')} - + {$_('from_data_import')} diff --git a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte index 230dcfd739..241bb17bb9 100644 --- a/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte +++ b/mathesar_ui/src/pages/schema/CreateNewTableTutorial.svelte @@ -1,14 +1,15 @@ @@ -22,7 +23,7 @@ {$_('from_scratch')} - + {$_('import_from_file')} diff --git a/mathesar_ui/src/pages/schema/ExplorationItem.svelte b/mathesar_ui/src/pages/schema/ExplorationItem.svelte index ade361c335..dc2a346478 100644 --- a/mathesar_ui/src/pages/schema/ExplorationItem.svelte +++ b/mathesar_ui/src/pages/schema/ExplorationItem.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import TableName from '@mathesar/components/TableName.svelte'; import { iconExploration } from '@mathesar/icons'; import { getExplorationPageUrl } from '@mathesar/routes/urls'; @@ -11,14 +12,14 @@ export let exploration: QueryInstance; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; $: baseTable = $tablesStore.data.get(exploration.base_table);
diff --git a/mathesar_ui/src/pages/schema/ExplorationsList.svelte b/mathesar_ui/src/pages/schema/ExplorationsList.svelte index 6dd223f709..8fa27682a5 100644 --- a/mathesar_ui/src/pages/schema/ExplorationsList.svelte +++ b/mathesar_ui/src/pages/schema/ExplorationsList.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import { iconExploration } from '@mathesar/icons'; import EmptyEntity from './EmptyEntity.svelte'; @@ -10,7 +11,7 @@ export let explorations: QueryInstance[]; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let bordered = true; diff --git a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte index cb22a2a557..b4dc77cf9c 100644 --- a/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte +++ b/mathesar_ui/src/pages/schema/SchemaAccessControlModal.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import type { UserRole } from '@mathesar/api/rest/users'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import Identifier from '@mathesar/components/Identifier.svelte'; import ErrorBox from '@mathesar/components/message-boxes/ErrorBox.svelte'; import { RichText } from '@mathesar/components/rich-text'; @@ -19,7 +20,7 @@ export let controller: ModalController; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; const usersStore = setUsersStoreInContext(); const { requestStatus } = usersStore; diff --git a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte index 4cfee93bce..bf947784f2 100644 --- a/mathesar_ui/src/pages/schema/SchemaExplorations.svelte +++ b/mathesar_ui/src/pages/schema/SchemaExplorations.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import EntityContainerWithFilterBar from '@mathesar/components/EntityContainerWithFilterBar.svelte'; import { RichText } from '@mathesar/components/rich-text'; import { getDataExplorerPageUrl } from '@mathesar/routes/urls'; @@ -12,7 +13,7 @@ import ExplorationsList from './ExplorationsList.svelte'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let explorationsMap: Map; export let hasTablesToExplore: boolean; export let canEditMetadata: boolean; @@ -47,7 +48,7 @@ on:clear={clearQuery} > - + {$_('open_data_explorer')} diff --git a/mathesar_ui/src/pages/schema/SchemaOverview.svelte b/mathesar_ui/src/pages/schema/SchemaOverview.svelte index 4385fc2de7..ad9d8cd6ca 100644 --- a/mathesar_ui/src/pages/schema/SchemaOverview.svelte +++ b/mathesar_ui/src/pages/schema/SchemaOverview.svelte @@ -4,7 +4,8 @@ import type { QueryInstance } from '@mathesar/api/rest/types/queries'; import type { TableEntry } from '@mathesar/api/rest/types/tables'; import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import SpinnerButton from '@mathesar/component-library/spinner-button/SpinnerButton.svelte'; import ErrorBox from '@mathesar/components/message-boxes/ErrorBox.svelte'; import { iconRefresh } from '@mathesar/icons'; @@ -31,7 +32,7 @@ export let canEditMetadata: boolean; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; $: hasTables = tablesMap.size > 0; $: hasExplorations = explorationsMap.size > 0; @@ -53,14 +54,14 @@ {#if tablesRequestStatus.state === 'processing'} - + {:else if tablesRequestStatus.state === 'failure'}

{tablesRequestStatus.errors[0]}

{ - await refetchTablesForSchema(schema.id); + await refetchTablesForSchema(schema.oid); }} label={$_('retry')} icon={iconRefresh} @@ -94,7 +95,7 @@
{ - await refetchQueriesForSchema(schema.id); + await refetchQueriesForSchema(schema.oid); }} label={$_('retry')} icon={iconRefresh} @@ -125,7 +126,7 @@ {$_('what_is_an_exploration_mini')}
- + {$_('open_data_explorer')}
diff --git a/mathesar_ui/src/pages/schema/SchemaPage.svelte b/mathesar_ui/src/pages/schema/SchemaPage.svelte index fab522012b..e7bc1d4149 100644 --- a/mathesar_ui/src/pages/schema/SchemaPage.svelte +++ b/mathesar_ui/src/pages/schema/SchemaPage.svelte @@ -1,7 +1,8 @@ diff --git a/mathesar_ui/src/routes/DataExplorerRoute.svelte b/mathesar_ui/src/routes/DataExplorerRoute.svelte index 0bbd7b7f67..6e792991fd 100644 --- a/mathesar_ui/src/routes/DataExplorerRoute.svelte +++ b/mathesar_ui/src/routes/DataExplorerRoute.svelte @@ -4,7 +4,8 @@ import { router } from 'tinro'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import type { CancellablePromise } from '@mathesar/component-library'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import { iconEdit, iconExploration } from '@mathesar/icons'; @@ -24,7 +25,7 @@ } from '@mathesar/systems/data-explorer'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let queryId: number | undefined; let is404 = false; @@ -42,7 +43,7 @@ try { const url = getExplorationEditorPageUrl( database.id, - schema.id, + schema.oid, instance.id, ); router.goto(url, true); @@ -134,7 +135,7 @@ import { _ } from 'svelte-i18n'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import ErrorPage from '@mathesar/pages/ErrorPage.svelte'; import ExplorationPage from '@mathesar/pages/exploration/ExplorationPage.svelte'; import { queries } from '@mathesar/stores/queries'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let queryId: number; $: query = $queries.data.get(queryId); diff --git a/mathesar_ui/src/routes/ImportRoute.svelte b/mathesar_ui/src/routes/ImportRoute.svelte index 3690eaa72e..7d92797891 100644 --- a/mathesar_ui/src/routes/ImportRoute.svelte +++ b/mathesar_ui/src/routes/ImportRoute.svelte @@ -2,7 +2,8 @@ import { _ } from 'svelte-i18n'; import { Route } from 'tinro'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import { iconImportData } from '@mathesar/icons'; import ImportPreviewPage from '@mathesar/pages/import/preview/ImportPreviewPage.svelte'; @@ -11,13 +12,13 @@ import { getImportPageUrl, getImportPreviewPageQueryParams } from './urls'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; import type { TableEntry } from '@mathesar/api/rest/types/tables'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import RecordPage from '@mathesar/pages/record/RecordPage.svelte'; import RecordStore from '@mathesar/pages/record/RecordStore'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let table: TableEntry; export let recordPk: string; diff --git a/mathesar_ui/src/routes/TableRoute.svelte b/mathesar_ui/src/routes/TableRoute.svelte index 21359c159b..f75cc14cb3 100644 --- a/mathesar_ui/src/routes/TableRoute.svelte +++ b/mathesar_ui/src/routes/TableRoute.svelte @@ -3,7 +3,8 @@ import { _ } from 'svelte-i18n'; import { Route } from 'tinro'; - import type { Database, SchemaEntry } from '@mathesar/AppTypes'; + import type { Schema } from '@mathesar/api/rpc/schemas'; + import type { Database } from '@mathesar/AppTypes'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import ErrorPage from '@mathesar/pages/ErrorPage.svelte'; import TablePage from '@mathesar/pages/table/TablePage.svelte'; @@ -12,7 +13,7 @@ import RecordPageRoute from './RecordPageRoute.svelte'; export let database: Database; - export let schema: SchemaEntry; + export let schema: Schema; export let tableId: number; $: $currentTableId = tableId; diff --git a/mathesar_ui/src/stores/queries.ts b/mathesar_ui/src/stores/queries.ts index 1aa0ed73d5..5dc21f936c 100644 --- a/mathesar_ui/src/stores/queries.ts +++ b/mathesar_ui/src/stores/queries.ts @@ -53,32 +53,32 @@ import { postAPI, putAPI, } from '@mathesar/api/rest/utils/requestUtils'; -import type { SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; import CacheManager from '@mathesar/utils/CacheManager'; import { preloadCommonData } from '@mathesar/utils/preloadData'; import { SHARED_LINK_UUID_QUERY_PARAM } from '@mathesar/utils/shares'; import { CancellablePromise } from '@mathesar-component-library'; -import { addCountToSchemaNumExplorations, currentSchemaId } from './schemas'; +import { currentSchemaId } from './schemas'; const commonData = preloadCommonData(); export type UnsavedQueryInstance = Partial; export interface QueriesStoreSubstance { - schemaId: SchemaEntry['id']; + schemaId: Schema['oid']; requestStatus: RequestStatus; data: Map; } // Cache the query list of the last 3 opened schemas const schemasCacheManager = new CacheManager< - SchemaEntry['id'], + Schema['oid'], Writable >(3); const requestMap: Map< - SchemaEntry['id'], + Schema['oid'], CancellablePromise> > = new Map(); @@ -87,7 +87,7 @@ function sortedQueryEntries(queryEntries: QueryInstance[]): QueryInstance[] { } function setSchemaQueriesStore( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], queryEntries?: QueryInstance[], ): Writable { const queries: QueriesStoreSubstance['data'] = new Map(); @@ -120,7 +120,7 @@ function findSchemaStoreForQuery(id: QueryInstance['id']) { } export async function refetchQueriesForSchema( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ): Promise { const store = schemasCacheManager.get(schemaId); if (!store) { @@ -164,7 +164,7 @@ export async function refetchQueriesForSchema( let preload = true; export function getQueriesStoreForSchema( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ): Writable { let store = schemasCacheManager.get(schemaId); if (!store) { @@ -212,7 +212,6 @@ export function createQuery( ): CancellablePromise { const promise = postAPI('/api/db/v0/queries/', newQuery); void promise.then((instance) => { - addCountToSchemaNumExplorations(instance.schema, 1); void refetchQueriesForSchema(instance.schema); return instance; }); @@ -306,7 +305,6 @@ export function deleteQuery(queryId: number): CancellablePromise { storeData.data.delete(queryId); return { ...storeData, data: new Map(storeData.data) }; }); - addCountToSchemaNumExplorations(get(store).schemaId, -1); } return undefined; }); diff --git a/mathesar_ui/src/stores/schemas.ts b/mathesar_ui/src/stores/schemas.ts index 774cd840f1..2a5d31374a 100644 --- a/mathesar_ui/src/stores/schemas.ts +++ b/mathesar_ui/src/stores/schemas.ts @@ -2,12 +2,9 @@ import type { Readable, Unsubscriber, Writable } from 'svelte/store'; import { derived, get, writable } from 'svelte/store'; import type { Connection } from '@mathesar/api/rest/connections'; -import schemasApi from '@mathesar/api/rest/schemas'; -import type { - PaginatedResponse, - RequestStatus, -} from '@mathesar/api/rest/utils/requestUtils'; -import type { SchemaEntry, SchemaResponse } from '@mathesar/AppTypes'; +import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; +import { api } from '@mathesar/api/rpc'; +import type { Schema } from '@mathesar/api/rpc/schemas'; import { preloadCommonData } from '@mathesar/utils/preloadData'; import type { CancellablePromise } from '@mathesar-component-library'; @@ -15,12 +12,13 @@ import { connectionsStore } from './databases'; const commonData = preloadCommonData(); -export const currentSchemaId: Writable = - writable(commonData.current_schema ?? undefined); +export const currentSchemaId: Writable = writable( + commonData.current_schema ?? undefined, +); export interface DBSchemaStoreData { requestStatus: RequestStatus; - data: Map; + data: Map; } const dbSchemaStoreMap: Map< @@ -29,22 +27,16 @@ const dbSchemaStoreMap: Map< > = new Map(); const dbSchemasRequestMap: Map< Connection['id'], - CancellablePromise | undefined> + CancellablePromise > = new Map(); -function findStoreBySchemaId(id: SchemaEntry['id']) { - return [...dbSchemaStoreMap.values()].find((entry) => - get(entry).data.has(id), - ); -} - function setDBSchemaStore( connectionId: Connection['id'], - schemas: SchemaResponse[], + schemas: Schema[], ): Writable { const schemaMap: DBSchemaStoreData['data'] = new Map(); schemas.forEach((schema) => { - schemaMap.set(schema.id, schema); + schemaMap.set(schema.oid, schema); }); const storeValue: DBSchemaStoreData = { requestStatus: { state: 'success' }, @@ -63,12 +55,12 @@ function setDBSchemaStore( function updateSchemaInDBSchemaStore( connectionId: Connection['id'], - schema: SchemaResponse, + schema: Schema, ) { const store = dbSchemaStoreMap.get(connectionId); if (store) { store.update((value) => { - value.data?.set(schema.id, schema); + value.data?.set(schema.oid, schema); return { ...value, data: new Map(value.data), @@ -79,7 +71,7 @@ function updateSchemaInDBSchemaStore( function removeSchemaInDBSchemaStore( connectionId: Connection['id'], - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ) { const store = dbSchemaStoreMap.get(connectionId); if (store) { @@ -95,36 +87,16 @@ function removeSchemaInDBSchemaStore( export function addCountToSchemaNumTables( connection: Connection, - schema: SchemaEntry, + schema: Schema, count: number, ) { const store = dbSchemaStoreMap.get(connection.id); if (store) { store.update((value) => { - const schemaToModify = value.data.get(schema.id); - if (schemaToModify) { - schemaToModify.num_tables += count; - value.data.set(schema.id, schemaToModify); - } - return { - ...value, - data: new Map(value.data), - }; - }); - } -} - -export function addCountToSchemaNumExplorations( - schemaId: SchemaEntry['id'], - count: number, -) { - const store = findStoreBySchemaId(schemaId); - if (store) { - store.update((value) => { - const schemaToModify = value.data.get(schemaId); + const schemaToModify = value.data.get(schema.oid); if (schemaToModify) { - schemaToModify.num_queries += count; - value.data.set(schemaId, schemaToModify); + schemaToModify.table_count += count; + value.data.set(schema.oid, schemaToModify); } return { ...value, @@ -153,10 +125,9 @@ async function refetchSchemasForDB( dbSchemasRequestMap.get(connectionId)?.cancel(); - const schemaRequest = schemasApi.list(connectionId); + const schemaRequest = api.schemas.list({ database_id: connectionId }).run(); dbSchemasRequestMap.set(connectionId, schemaRequest); - const response = await schemaRequest; - const schemas = response?.results || []; + const schemas = await schemaRequest; const dbSchemasStore = setDBSchemaStore(connectionId, schemas); @@ -201,8 +172,8 @@ function getSchemasStoreForDB( export function getSchemaInfo( connectionId: Connection['id'], - schemaId: SchemaEntry['id'], -): SchemaEntry | undefined { + schemaId: Schema['oid'], +): Schema | undefined { const store = dbSchemaStoreMap.get(connectionId); if (!store) { return undefined; @@ -212,32 +183,51 @@ export function getSchemaInfo( export async function createSchema( connectionId: Connection['id'], - schemaName: SchemaEntry['name'], - description: SchemaEntry['description'], -): Promise { - const response = await schemasApi.add({ - name: schemaName, + name: Schema['name'], + description: Schema['description'], +): Promise { + const schemaOid = await api.schemas + .add({ + database_id: connectionId, + name, + description, + }) + .run(); + updateSchemaInDBSchemaStore(connectionId, { + oid: schemaOid, + name, description, - connectionId, + table_count: 0, }); - updateSchemaInDBSchemaStore(connectionId, response); - return response; } export async function updateSchema( connectionId: Connection['id'], - schema: SchemaEntry, -): Promise { - const response = await schemasApi.update(schema); - updateSchemaInDBSchemaStore(connectionId, response); - return response; + schema: Schema, +): Promise { + await api.schemas + .patch({ + database_id: connectionId, + schema_oid: schema.oid, + patch: { + name: schema.name, + description: schema.description, + }, + }) + .run(); + updateSchemaInDBSchemaStore(connectionId, schema); } export async function deleteSchema( connectionId: Connection['id'], - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ): Promise { - await schemasApi.delete(schemaId); + await api.schemas + .delete({ + database_id: connectionId, + schema_oid: schemaId, + }) + .run(); removeSchemaInDBSchemaStore(connectionId, schemaId); } @@ -264,7 +254,7 @@ export const schemas: Readable = derived( }, ); -export const currentSchema: Readable = derived( +export const currentSchema: Readable = derived( [currentSchemaId, schemas], ([$currentSchemaId, $schemas]) => $currentSchemaId ? $schemas.data.get($currentSchemaId) : undefined, diff --git a/mathesar_ui/src/stores/storeBasedUrls.ts b/mathesar_ui/src/stores/storeBasedUrls.ts index 2ac9ba02a5..7c858b6bd2 100644 --- a/mathesar_ui/src/stores/storeBasedUrls.ts +++ b/mathesar_ui/src/stores/storeBasedUrls.ts @@ -31,7 +31,7 @@ export const storeToGetRecordPageUrl = derived( recordId: unknown; }): string | undefined { const d = connectionId ?? connection?.id; - const s = schemaId ?? schema?.id; + const s = schemaId ?? schema?.oid; const t = tableId ?? table?.id; const r = recordId ?? undefined; if ( @@ -61,7 +61,7 @@ export const storeToGetTablePageUrl = derived( tableId?: number; }): string | undefined { const d = connectionId ?? connection?.id; - const s = schemaId ?? schema?.id; + const s = schemaId ?? schema?.oid; const t = tableId ?? table?.id; if (d === undefined || s === undefined || t === undefined) { return undefined; diff --git a/mathesar_ui/src/stores/tables.ts b/mathesar_ui/src/stores/tables.ts index 047d37d183..219cc4407c 100644 --- a/mathesar_ui/src/stores/tables.ts +++ b/mathesar_ui/src/stores/tables.ts @@ -35,7 +35,8 @@ import { patchAPI, postAPI, } from '@mathesar/api/rest/utils/requestUtils'; -import type { DBObjectEntry, Database, SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; +import type { DBObjectEntry, Database } from '@mathesar/AppTypes'; import { invalidIf } from '@mathesar/components/form'; import type { AtLeastOne } from '@mathesar/typeUtils'; import { preloadCommonData } from '@mathesar/utils/preloadData'; @@ -55,11 +56,11 @@ export interface DBTablesStoreData { } const schemaTablesStoreMap: Map< - SchemaEntry['id'], + Schema['oid'], Writable > = new Map(); const schemaTablesRequestMap: Map< - SchemaEntry['id'], + Schema['oid'], CancellablePromise> > = new Map(); @@ -68,7 +69,7 @@ function sortedTableEntries(tableEntries: TableEntry[]): TableEntry[] { } function setSchemaTablesStore( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], tableEntries?: TableEntry[], ): Writable { const tables: DBTablesStoreData['data'] = new Map(); @@ -93,14 +94,12 @@ function setSchemaTablesStore( return store; } -export function removeTablesInSchemaTablesStore( - schemaId: SchemaEntry['id'], -): void { +export function removeTablesInSchemaTablesStore(schemaId: Schema['oid']): void { schemaTablesStoreMap.delete(schemaId); } export async function refetchTablesForSchema( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ): Promise { const store = schemaTablesStoreMap.get(schemaId); if (!store) { @@ -143,7 +142,7 @@ export async function refetchTablesForSchema( let preload = true; export function getTablesStoreForSchema( - schemaId: SchemaEntry['id'], + schemaId: Schema['oid'], ): Writable { let store = schemaTablesStoreMap.get(schemaId); if (!store) { @@ -195,7 +194,7 @@ function findAndUpdateTableStore(id: TableEntry['id'], tableEntry: TableEntry) { export function deleteTable( database: Database, - schema: SchemaEntry, + schema: Schema, tableId: TableEntry['id'], ): CancellablePromise { const promise = deleteAPI(`/api/db/v0/tables/${tableId}/`); @@ -203,7 +202,7 @@ export function deleteTable( (resolve, reject) => { void promise.then((value) => { addCountToSchemaNumTables(database, schema, -1); - schemaTablesStoreMap.get(schema.id)?.update((tableStoreData) => { + schemaTablesStoreMap.get(schema.oid)?.update((tableStoreData) => { tableStoreData.data.delete(tableId); return { ...tableStoreData, @@ -242,14 +241,14 @@ export function updateTableMetaData( export function createTable( database: Database, - schema: SchemaEntry, + schema: Schema, tableArgs: { name?: string; dataFiles?: [number, ...number[]]; }, ): CancellablePromise { const promise = postAPI('/api/db/v0/tables/', { - schema: schema.id, + schema: schema.oid, name: tableArgs.name, data_files: tableArgs.dataFiles, }); @@ -257,7 +256,7 @@ export function createTable( (resolve, reject) => { void promise.then((value) => { addCountToSchemaNumTables(database, schema, 1); - schemaTablesStoreMap.get(schema.id)?.update((existing) => { + schemaTablesStoreMap.get(schema.oid)?.update((existing) => { const tableEntryMap: DBTablesStoreData['data'] = new Map(); sortedTableEntries([...existing.data.values(), value]).forEach( (entry) => { diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts index 8609761322..90e4c07a82 100644 --- a/mathesar_ui/src/stores/users.ts +++ b/mathesar_ui/src/stores/users.ts @@ -11,7 +11,8 @@ import userApi, { type UserRole, } from '@mathesar/api/rest/users'; import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; -import type { Database, SchemaEntry } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; +import type { Database } from '@mathesar/AppTypes'; import { getErrorMessage } from '@mathesar/utils/errors'; import { type AccessOperation, @@ -54,7 +55,7 @@ export class UserModel { hasPermission( dbObject: { database?: Pick; - schema?: Pick; + schema?: Pick; }, operation: AccessOperation, ): boolean { @@ -69,7 +70,7 @@ export class UserModel { } const roles: UserRole[] = []; if (schema) { - const userSchemaRole = this.schemaRoles.get(schema.id); + const userSchemaRole = this.schemaRoles.get(schema.oid); if (userSchemaRole) { roles.push(userSchemaRole.role); } @@ -87,8 +88,8 @@ export class UserModel { return this.databaseRoles.get(database.id); } - getRoleForSchema(schema: Pick) { - return this.schemaRoles.get(schema.id); + getRoleForSchema(schema: Pick) { + return this.schemaRoles.get(schema.oid); } hasDirectDbAccess(database: Pick) { @@ -99,14 +100,11 @@ export class UserModel { return this.hasDirectDbAccess(database) || this.isSuperUser; } - hasDirectSchemaAccess(schema: Pick) { - return this.schemaRoles.has(schema.id); + hasDirectSchemaAccess(schema: Pick) { + return this.schemaRoles.has(schema.oid); } - hasSchemaAccess( - database: Pick, - schema: Pick, - ) { + hasSchemaAccess(database: Pick, schema: Pick) { return this.hasDbAccess(database) || this.hasDirectSchemaAccess(schema); } @@ -298,10 +296,10 @@ class WritableUsersStore { async addSchemaRoleForUser( userId: number, - schema: Pick, + schema: Pick, role: UserRole, ) { - const schemaRole = await userApi.addSchemaRole(userId, schema.id, role); + const schemaRole = await userApi.addSchemaRole(userId, schema.oid, role); this.users.update((users) => users.map((user) => { if (user.id === userId) { @@ -313,10 +311,7 @@ class WritableUsersStore { void this.fetchUsersSilently(); } - async removeSchemaAccessForUser( - userId: number, - schema: Pick, - ) { + async removeSchemaAccessForUser(userId: number, schema: Pick) { const user = get(this.users).find((entry) => entry.id === userId); const schemaRole = user?.getRoleForSchema(schema); if (schemaRole) { @@ -345,7 +340,7 @@ class WritableUsersStore { ); } - getNormalUsersWithDirectSchemaRole(schema: Pick) { + getNormalUsersWithDirectSchemaRole(schema: Pick) { return derived(this.users, ($users) => $users.filter( (user) => !user.isSuperUser && user.hasDirectSchemaAccess(schema), @@ -353,7 +348,7 @@ class WritableUsersStore { ); } - getNormalUsersWithoutDirectSchemaRole(schema: Pick) { + getNormalUsersWithoutDirectSchemaRole(schema: Pick) { return derived(this.users, ($users) => $users.filter( (user) => !user.isSuperUser && !user.hasDirectSchemaAccess(schema), @@ -363,7 +358,7 @@ class WritableUsersStore { getUsersWithAccessToSchema( database: Pick, - schema: Pick, + schema: Pick, ) { return derived(this.users, ($users) => $users.filter((user) => user.hasSchemaAccess(database, schema)), diff --git a/mathesar_ui/src/systems/data-explorer/result-pane/QueryRunErrors.svelte b/mathesar_ui/src/systems/data-explorer/result-pane/QueryRunErrors.svelte index cca067558f..6efc59e488 100644 --- a/mathesar_ui/src/systems/data-explorer/result-pane/QueryRunErrors.svelte +++ b/mathesar_ui/src/systems/data-explorer/result-pane/QueryRunErrors.svelte @@ -89,7 +89,7 @@ class="btn btn-secondary" href={getExplorationEditorPageUrl( $currentDatabase.id, - $currentSchema.id, + $currentSchema.oid, $query.id, )} > diff --git a/mathesar_ui/src/systems/table-view/table-inspector/table/TableActions.svelte b/mathesar_ui/src/systems/table-view/table-inspector/table/TableActions.svelte index f24e68428b..4c36f76d7a 100644 --- a/mathesar_ui/src/systems/table-view/table-inspector/table/TableActions.svelte +++ b/mathesar_ui/src/systems/table-view/table-inspector/table/TableActions.svelte @@ -34,7 +34,7 @@ $currentDatabase && $currentSchema ? createDataExplorerUrlToExploreATable( $currentDatabase?.id, - $currentSchema.id, + $currentSchema.oid, { id: $tabularData.id, name: $tables.data.get($tabularData.id)?.name ?? '', @@ -47,7 +47,7 @@ } return constructDataExplorerUrlToSummarizeFromGroup( $currentDatabase.id, - $currentSchema.id, + $currentSchema.oid, { baseTable: { id, name: $currentTable.name }, columns: $columns, @@ -72,7 +72,7 @@ const schema = $currentSchema; if (database && schema) { await deleteTable(database, schema, $tabularData.id); - router.goto(getSchemaPageUrl(database.id, schema.id), true); + router.goto(getSchemaPageUrl(database.id, schema.oid), true); } }, }); diff --git a/mathesar_ui/src/utils/preloadData.ts b/mathesar_ui/src/utils/preloadData.ts index 09a3acc76e..c857d24128 100644 --- a/mathesar_ui/src/utils/preloadData.ts +++ b/mathesar_ui/src/utils/preloadData.ts @@ -2,11 +2,12 @@ import type { Connection } from '@mathesar/api/rest/connections'; import type { QueryInstance } from '@mathesar/api/rest/types/queries'; import type { TableEntry } from '@mathesar/api/rest/types/tables'; import type { User } from '@mathesar/api/rest/users'; -import type { AbstractTypeResponse, SchemaResponse } from '@mathesar/AppTypes'; +import type { Schema } from '@mathesar/api/rpc/schemas'; +import type { AbstractTypeResponse } from '@mathesar/AppTypes'; export interface CommonData { connections: Connection[]; - schemas: SchemaResponse[]; + schemas: Schema[]; tables: TableEntry[]; queries: QueryInstance[]; current_connection: Connection['id'] | null;