diff --git a/frontend/src/metabase-lib/metadata/Schema.ts b/frontend/src/metabase-lib/metadata/Schema.ts index 0bd70db35acbf8fda4d1878e9325aaa776411dad..543dddbcff6120549e92a5a48ee95a0e159f2fed 100644 --- a/frontend/src/metabase-lib/metadata/Schema.ts +++ b/frontend/src/metabase-lib/metadata/Schema.ts @@ -1,20 +1,30 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck -import { titleize, humanize } from "metabase/lib/formatting"; -import Base from "./Base"; +import { humanize, titleize } from "metabase/lib/formatting"; +import { NormalizedSchema } from "metabase-types/api"; import type Metadata from "./Metadata"; import type Database from "./Database"; import type Table from "./Table"; -/** - * Wrapper class for a {@link Database} schema. Contains {@link Table}s. - */ -export default class Schema extends Base { - id: string; - name: string; - database: Database; - tables: Table[]; - metadata: Metadata; +export default class Schema { + private readonly schema: NormalizedSchema; + metadata?: Metadata; + database?: Database; + tables: Table[] = []; + + constructor(schema: NormalizedSchema) { + this.schema = schema; + } + + get id() { + return this.schema.id; + } + + get name() { + return this.schema.name; + } + + getPlainObject() { + return this.schema; + } displayName() { return this.name ? titleize(humanize(this.name)) : null; @@ -23,18 +33,4 @@ export default class Schema extends Base { getTables() { return this.tables; } - - /** - * @private - * @param {string} name - * @param {Database} database - * @param {Table[]} tables - */ - - /* istanbul ignore next */ - _constructor(name, database, tables) { - this.name = name; - this.database = database; - this.tables = tables; - } } diff --git a/frontend/src/metabase-lib/metadata/Schema.unit.spec.ts b/frontend/src/metabase-lib/metadata/Schema.unit.spec.ts index e7120a4c7581c9cd8018bbf793d73a101ef8c0c4..bc6845e8e87fd82ca0caddc08a64aec53f191a60 100644 --- a/frontend/src/metabase-lib/metadata/Schema.unit.spec.ts +++ b/frontend/src/metabase-lib/metadata/Schema.unit.spec.ts @@ -1,24 +1,25 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck import Schema from "./Schema"; -import Base from "./Base"; + describe("Schema", () => { describe("instantiation", () => { it("should create an instance of Schema", () => { - expect(new Schema()).toBeInstanceOf(Schema); + expect(new Schema({ id: "1:public", name: "public" })).toBeInstanceOf( + Schema, + ); }); - it("should add `object` props to the instance (because it extends Base)", () => { - expect(new Schema()).toBeInstanceOf(Base); + it("should add `object` props to the instance", () => { expect( new Schema({ - foo: "bar", + id: "1:public", + name: "public", }), - ).toHaveProperty("foo", "bar"); + ).toHaveProperty("name", "public"); }); }); describe("displayName", () => { it("should return a formatted `name` string", () => { const schema = new Schema({ + id: "name: public", name: "foo_bar", }); expect(schema.displayName()).toBe("Foo Bar"); diff --git a/frontend/src/metabase/admin/permissions/utils/data-entity-id.ts b/frontend/src/metabase/admin/permissions/utils/data-entity-id.ts index 8b877f0c33b5603636c0dc657685adc11cb1f741..6a8ec4622d790188ec0be67fdc2015958cab1086 100644 --- a/frontend/src/metabase/admin/permissions/utils/data-entity-id.ts +++ b/frontend/src/metabase/admin/permissions/utils/data-entity-id.ts @@ -1,3 +1,4 @@ +import { checkNotNull } from "metabase/core/utils/types"; import type { ConcreteTableId } from "metabase-types/api"; import type Database from "metabase-lib/metadata/Database"; import type Schema from "metabase-lib/metadata/Schema"; @@ -9,7 +10,7 @@ export const getDatabaseEntityId = (databaseEntity: Database) => ({ }); export const getSchemaEntityId = (schemaEntity: Schema) => ({ - databaseId: schemaEntity.database.id, + databaseId: checkNotNull(schemaEntity.database).id, schemaName: schemaEntity.name, }); diff --git a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorDatabaseSchemaPicker/DataSelectorDatabaseSchemaPicker.tsx b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorDatabaseSchemaPicker/DataSelectorDatabaseSchemaPicker.tsx index 954f214eb3500133dd23e331c054403bc847a564..6825b0ec6af79a413db971465646605d7c9e664a 100644 --- a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorDatabaseSchemaPicker/DataSelectorDatabaseSchemaPicker.tsx +++ b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorDatabaseSchemaPicker/DataSelectorDatabaseSchemaPicker.tsx @@ -107,7 +107,7 @@ const DataSelectorDatabaseSchemaPicker = ({ } let openSection = selectedSchema - ? databases.findIndex(db => db.id === selectedSchema.database.id) + ? databases.findIndex(db => db.id === selectedSchema.database?.id) : selectedDatabase ? databases.findIndex(db => db.id === selectedDatabase.id) : -1; diff --git a/frontend/src/metabase/selectors/metadata.ts b/frontend/src/metabase/selectors/metadata.ts index 837fb501741c1f54891ee1a429cb021d0c1e4f0c..421754b23823c8721630b27183368bbda2619f88 100644 --- a/frontend/src/metabase/selectors/metadata.ts +++ b/frontend/src/metabase/selectors/metadata.ts @@ -127,10 +127,8 @@ export const getMetadata: ( ); }); // schema - hydrate( - metadata.schemas, - "database", - schema => metadata.database(schema.database) as Database, + hydrate(metadata.schemas, "database", schema => + metadata.database(schema.getPlainObject().database), ); // table @@ -151,10 +149,11 @@ export const getMetadata: ( ); }); - hydrate(metadata.schemas, "tables", schema => - schema.tables + hydrate(metadata.schemas, "tables", schema => { + const tableIds = schema.getPlainObject().tables; + return tableIds ? // use the schema tables if they exist - schema.tables.map(table => metadata.table(table)) + tableIds.map(table => metadata.table(table)) : schema.database && schema.database.tables.length > 0 ? // if the schema has a database with tables, use those schema.database.tables.filter( @@ -163,8 +162,8 @@ export const getMetadata: ( : // otherwise use any loaded tables that match the schema id Object.values(metadata.tables).filter( table => table.schema && table.schema.id === schema.id, - ), - ); + ); + }); // segments hydrate(