UNPKG

@itwin/core-backend

Version:
288 lines • 18.9 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { expect } from "chai"; import { join } from "path"; import { Guid, Logger, LogLevel, OpenMode } from "@itwin/core-bentley"; import { ViewStore } from "../../ViewStore"; import { KnownTestLocations } from "../KnownTestLocations"; describe("ViewStore", function () { this.timeout(0); let vs1; before(async () => { Logger.setLevel("SQLite", LogLevel.None); // we're expecting errors const dbName = join(KnownTestLocations.outputDir, "viewStore.db"); ViewStore.ViewDb.createNewDb(dbName); vs1 = new ViewStore.ViewDb({ guidMap: {} }); vs1.openDb(dbName, OpenMode.ReadWrite); }); after(async () => { vs1.closeDb(true); Logger.setLevel("SQLite", LogLevel.Error); }); it("ViewDb", async () => { const c1 = vs1.addCategorySelectorRow({ name: "first cat", json: "cat1-json" }); const ds1 = vs1.addDisplayStyleRow({ name: "first style", json: "style1-json" }); expect(vs1.getViewByNameSync({ name: "view1" })).to.be.undefined; const v1Id = vs1.addViewRow({ className: "spatial", name: "view1", json: "json1", owner: "owner10", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 }); expect(v1Id).equals(1); const v1 = vs1.getViewByNameSync({ name: "view1" }); expect(vs1.findViewIdByName({ name: "view1" })).equals(v1Id); expect(vs1.findViewIdByName({ name: "/view1" })).equals(v1Id); expect(v1.owner).equals("owner10"); expect(v1.className).equals("spatial"); expect(v1.groupId).equals("@1"); expect(v1.isPrivate).to.be.true; expect(v1.name).equals("view1"); await vs1.updateViewShared({ viewId: v1Id, isShared: true, owner: "owner10" }); const v1Updated = vs1.getViewByNameSync({ name: "view1" }); expect(v1Updated.isPrivate).to.be.false; const v1Id2 = vs1.addViewRow({ className: "spatial", name: "v2", json: "json-v2", owner: "owner1", groupId: 1, categorySel: c1, displayStyle: ds1 }); expect(v1Id2).equals(2); const v2 = vs1.getViewRow(v1Id2); expect(v2.name).equals("v2"); vs1.deleteViewRow(v1Id2); expect(vs1.findViewIdByName({ name: "v2", groupId: 1 })).equals(0); expect(() => vs1.addViewGroupRow({ name: "", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewGroupRow({ name: " ", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewGroupRow({ name: "@bad", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewGroupRow({ name: "bad/name", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewGroupRow({ name: "^fd", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewGroupRow({ name: "sd#fd", json: "" })).to.throw("illegal group"); expect(() => vs1.addViewRow({ className: "spatial", name: "@bad", json: "json-v2", owner: "owner1", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw("illegal view"); expect(() => vs1.addViewRow({ className: "spatial", name: "bad/name", json: "json-v2", owner: "owner1", groupId: 1, categorySel: c1, displayStyle: ds1 })).to.throw("illegal view"); const g1 = vs1.addViewGroupRow({ name: "group1", json: "group1-json" }); const g2 = vs1.addViewGroupRow({ name: "group2", json: "group2-json" }); const g3 = vs1.addViewGroupRow({ name: "group 3", parentId: g2, json: "group3-json" }); const g4 = vs1.addViewGroupRow({ name: "group4", parentId: g3, json: "group3-json" }); const v2Id = vs1.addViewRow({ className: "spatial2", name: "view2", json: "json2", groupId: g4, categorySel: c1, displayStyle: ds1 }); expect(v2Id).equals(3); for (let i = 0; i < 100; i++) vs1.addViewRow({ className: "spatial", name: `test view ${i}`, json: `json${i}`, owner: "owner1", groupId: g2, categorySel: c1, displayStyle: ds1 }); // duplicate name in a group should throw expect(() => vs1.addViewRow({ className: "spatial3", name: "test view 0", json: "json-blah", owner: "owner1", groupId: g2, categorySel: c1, displayStyle: ds1 })).to.throw("UNIQUE"); // allow the same name in different groups const v103 = vs1.addViewRow({ className: "spatial3", name: "test view 0", json: "json-blah", owner: "owner1", groupId: 1, categorySel: c1, displayStyle: ds1 }); const v104 = vs1.addViewRow({ className: "spatial3", name: "another view", json: "json-blah", owner: "owner10", groupId: 1, categorySel: c1, displayStyle: ds1 }); const g3Id = vs1.getViewGroupByName("group 3", g2); expect(g3Id).equals(g3); expect(vs1.findViewGroup("group1")).equals(g1); expect(vs1.findViewGroup("group 3")).equals(0); // not in the root group expect(vs1.findViewGroup("/group2/group 3/")).equals(g3); expect(vs1.findViewGroup("/group2/group 3/group4")).equals(g4); expect(vs1.findViewGroup("group2/group 3/group4")).equals(g4); expect(vs1.findViewGroup(ViewStore.fromRowId(g4))).equals(g4); expect(vs1.findViewGroup("group2/group 3/group4/blah")).equals(0); expect(vs1.findViewGroup("group2/blah/group4")).equals(0); expect(vs1.findViewGroup("blah")).equals(0); expect(vs1.findViewGroup("/")).equals(1); expect(vs1.findViewGroup("")).equals(1); expect(vs1.getViewByNameSync({ name: "view2", groupId: g4 })?.groupId).equals(ViewStore.fromRowId(g4)); expect(vs1.findViewIdByName({ name: "/group2/group 3/group4/view2" })).equals(v2Id); expect(vs1.findViewIdByName({ name: "group2/group 3/group4/view2" })).equals(v2Id); expect(vs1.findViewIdByName({ name: `${ViewStore.fromRowId(g4)}/view2` })).equals(v2Id); expect(vs1.findViewIdByName({ name: "group2/group 3/group4/not there" })).equals(0); expect(vs1.findViewIdByName({ name: "group2/test view 3" })).not.equal(0); const group3 = vs1.getViewGroup(g3Id); expect(group3.name).equals("group 3"); expect(group3.parentId).equals(g2); expect(group3.json).equals("group3-json"); await vs1.renameViewGroup({ groupId: g3Id, name: "group3-updated" }); vs1.updateViewGroupJson(g3Id, "group3-json-updated"); const g3Updated = vs1.getViewGroup(g3Id); expect(g3Updated.name).equals("group3-updated"); expect(g3Updated.json).equals("group3-json-updated"); expect(vs1.queryViewsSync({ group: "group2", classNames: ["spatial"] }).length).equals(100); expect(vs1.queryViewsSync({ group: ViewStore.fromRowId(g4), classNames: ["spatial2"] }).length).equals(1); expect(vs1.queryViewsSync({ classNames: ["spatial", "spatial3", "blah"] }).length).equals(3); expect(vs1.queryViewsSync({ classNames: [] }).length).equals(0); expect(vs1.queryViewsSync({ classNames: ["blah"] }).length).equals(0); expect((await vs1.findViewsByOwner({ owner: "owner1" })).length).equals(101); const thumbnail1 = new Uint8Array([2, 33, 23, 0, 202]); const format1 = { width: 100, height: 200, format: "jpeg" }; const format2 = { width: 10, height: 20, format: "png" }; vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v1Id, format: format1 }); vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: v2Id, format: format2 }); const thumbnail2 = vs1.getThumbnailRow(v2Id); expect(thumbnail2?.data).deep.equals(thumbnail1); expect(thumbnail2?.format).deep.equals(format2); const thumb3 = new Uint8Array([2, 33, 23, 0, 203]); vs1.addOrReplaceThumbnailRow({ data: thumb3, viewId: v2Id, format: format2 }); const thumbnail3 = vs1.getThumbnailRow(v2Id); expect(thumbnail3?.data).deep.equals(thumb3); vs1.addOrReplaceThumbnailRow({ data: thumbnail1, viewId: 33, format: format1 }); expect(vs1.getThumbnailRow(33)).to.not.be.undefined; vs1.deleteThumbnailSync(ViewStore.fromRowId(33)); expect(vs1.getThumbnailRow(33)).to.be.undefined; await vs1.deleteViewGroup({ name: "group1" }); expect(vs1.getViewByNameSync({ name: "view2", groupId: g1 })).to.be.undefined; const cat01 = vs1.addCategorySelectorRow({ name: "cat1", json: "cat1-json" }); vs1.addCategorySelectorRow({ name: "cat2", json: "cat2-json" }); const cat1Id = vs1.findCategorySelectorByName("cat1"); expect(cat1Id).equals(cat01); let cat1 = vs1.getCategorySelectorRow(cat1Id); expect(cat1.name).equals("cat1"); expect(cat1.json).equals("cat1-json"); await vs1.updateCategorySelectorJson(cat1Id, "cat1-json-updated"); // eslint-disable-line @typescript-eslint/await-thenable cat1 = vs1.getCategorySelectorRow(cat1Id); expect(cat1.json).equals("cat1-json-updated"); vs1.deleteCategorySelectorSync(cat1Id); expect(vs1.findCategorySelectorByName("cat1")).equals(0); const ds01 = vs1.addDisplayStyleRow({ name: "style1", json: "style1-json" }); vs1.addDisplayStyleRow({ name: "style2", json: "style2-json" }); const style1Id = vs1.findDisplayStyleByName("style1"); expect(style1Id).equals(ds01); const style1 = vs1.getDisplayStyleRow(style1Id); expect(style1.name).equals("style1"); expect(style1.json).equals("style1-json"); await vs1.renameDisplayStyle({ id: style1Id, name: "style1-updated" }); const style1UpdatedNameId = vs1.findDisplayStyleByName("style1-updated"); expect(style1UpdatedNameId).equals(style1Id); vs1.updateDisplayStyleJson(style1Id, "style1-json-updated"); const style1Updated = vs1.getDisplayStyleRow(style1Id); expect(style1Updated.json).equals("style1-json-updated"); vs1.deleteDisplayStyleSync(style1Id); expect(vs1.findDisplayStyleByName("style1")).equals(0); expect(vs1.findDisplayStyleByName("style2")).equals(3); vs1.addModelSelectorRow({ name: "model1", json: "model1-json" }); const ms2 = vs1.addModelSelectorRow({ json: "model2-json" }); const model1Id = vs1.findModelSelectorByName("model1"); expect(model1Id).equals(1); const model1 = vs1.getModelSelectorRow(model1Id); expect(model1.name).equals("model1"); expect(model1.json).equals("model1-json"); const model2 = vs1.getModelSelectorRow(ms2); expect(model2.name).undefined; expect(model2.json).equals("model2-json"); await vs1.renameModelSelector({ id: model1Id, name: "model1-updated" }); const model1UpdatedNameId = vs1.findModelSelectorByName("model1-updated"); expect(model1UpdatedNameId).equals(model1Id); await vs1.renameModelSelector({ id: model1Id, name: undefined }); expect(vs1.getModelSelectorRow(model1Id).name).undefined; vs1.updateModelSelectorJson(model1Id, "model1-json-updated"); const model1Updated = vs1.getModelSelectorRow(model1Id); expect(model1Updated.json).equals("model1-json-updated"); vs1.deleteModelSelectorSync(model1Id); expect(vs1.findModelSelectorByName("model1")).equals(0); vs1.addTimelineRow({ name: "timeline1", json: "timeline1-json" }); vs1.addTimelineRow({ name: "timeline2", json: "timeline2-json" }); const timeline1Id = vs1.findTimelineByName("timeline1"); const timeline2Id = vs1.findTimelineByName("timeline2"); expect(timeline1Id).equals(1); const timeline1 = vs1.getTimelineRow(timeline1Id); expect(timeline1.name).equals("timeline1"); expect(timeline1.json).equals("timeline1-json"); await vs1.renameTimeline({ id: timeline1Id, name: "timeline1-updated" }); const timeline1UpdatedNameId = vs1.findTimelineByName("timeline1-updated"); expect(timeline1UpdatedNameId).equals(timeline1Id); vs1.updateTimelineJson(timeline1Id, "timeline1-json-updated"); const timeline1Updated = vs1.getTimelineRow(timeline1Id); expect(timeline1Updated.json).equals("timeline1-json-updated"); vs1.deleteTimelineSync(timeline2Id); expect(vs1.findTimelineByName("timeline2")).equals(0); const t1 = vs1.addTag({ name: "tag1", json: "tag1-json", owner: "owner1" }); vs1.addTag({ name: "tag2", json: "tag2-json" }); const tag1Id = vs1.findTagByName("tag1"); expect(tag1Id).equals(t1); const tag1 = vs1.getTag(tag1Id); expect(tag1.name).equals("tag1"); expect(tag1.json).equals("tag1-json"); expect(tag1.owner).equals("owner1"); for (let i = 0; i < 5; i++) vs1.addTag({ name: `test tag ${i}`, json: `newTag${i}-json` }); vs1.addTagToView({ viewId: v1Id, tagId: tag1Id }); vs1.addTagToView({ viewId: v1Id, tagId: 2 }); vs1.addTagToView({ viewId: v103, tagId: 2 }); vs1.addTagToView({ viewId: v104, tagId: 2 }); vs1.addTagToView({ viewId: v1Id, tagId: 3 }); const taggedViewIds = vs1.findViewsForTag(tag1Id); expect(taggedViewIds.length).equals(1); expect(taggedViewIds[0]).equals(v1Id); const tags = vs1.getTagsForView(v1Id); expect(tags.length).equals(3); expect(tags[0]).equals("tag1"); expect(tags[1]).equals("tag2"); expect(tags[2]).equals("test tag 0"); vs1.addViewRow({ className: "BisCore:SpatialViewDefinition", name: "my private 2", json: "json1", owner: "owner10", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 }); vs1.addViewRow({ className: "BisCore:OrthographicViewDefinition", name: "my private 3", json: "json1", owner: "owner10", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 }); vs1.addViewRow({ className: "BisCore:SheetViewDefinition", name: "sheet 3", json: "json1", owner: "owner10", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 }); vs1.addViewRow({ className: "BisCore:DrawingViewDefinition", name: "drawing 3", json: "json1", owner: "owner10", isPrivate: true, groupId: 1, categorySel: c1, displayStyle: ds1 }); let views = vs1.queryViewsSync({ group: "/" }); expect(views.length).equals(3); expect(views[0].name).equals("another view"); expect(vs1.queryViewsSync({ group: "group1" }).length).equals(0); expect(vs1.queryViewsSync({ group: "group2" }).length).equal(100); expect(vs1.queryViewsSync({ group: "group2", offset: 20, limit: 10 }).length).equals(10); expect(vs1.queryViewsSync({ group: "group2", offset: 20, limit: 100 }).length).equals(80); views = vs1.queryViewsSync({ group: "group2", nameSearch: "%20%", nameCompare: "LIKE" }); expect(views.length).equals(1); expect(views[0].name).equals("test view 20"); views = vs1.queryViewsSync({ group: "group2", nameSearch: "*2*", nameCompare: "GLOB" }); expect(views.length).equals(19); expect(vs1.queryViewsSync({ group: "group2", tags: ["tag1"] }).length).equal(0); expect(vs1.queryViewsSync({ tags: ["tag1"] }).length).equal(1); views = vs1.queryViewsSync({ tags: ["tag2", "tag1"] }); expect(views.length).equal(3); expect(views[2].tags?.length).equal(3); views = vs1.queryViewsSync({ owner: "owner10" }); expect(views.length).equal(7); views = vs1.queryViewsSync({ owner: "owner10", nameSearch: "my%", nameCompare: "LIKE" }); expect(views.length).equal(2); expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:SpatialViewDefinition"] }).length).equal(1); expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:SpatialViewDefinition", "BisCore:OrthographicViewDefinition"] }).length).equal(2); expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:DrawingViewDefinition"] }).length).equal(1); expect(vs1.queryViewsSync({ owner: "owner10", classNames: ["BisCore:DrawingViewDefinition", "BisCore:SheetViewDefinition"] }).length).equal(2); await vs1.renameTag({ oldName: "tag2", newName: "tag2-renamed" }); views = vs1.queryViewsSync({ tags: ["tag2-renamed"] }); expect(views.length).equal(3); vs1.deleteTagSync({ name: "tag2-renamed" }); const tagIdsAfterDelete = vs1.getTagsForView(v1Id); expect(tagIdsAfterDelete.length).equals(2); expect(tagIdsAfterDelete[0]).equals("tag1"); expect(tagIdsAfterDelete[1]).equals("test tag 0"); await vs1.addSearch({ name: "search1", json: "search1-json" }); const search2 = await vs1.addSearch({ name: "search2", json: "search2-json" }); await expect(vs1.addSearch({ name: "search1", json: "search1-json" })).to.be.rejectedWith("UNIQUE"); const search1Id = vs1.findSearchByName("search1"); expect(search1Id).equals(1); const search1 = vs1.getSearch(search1Id); expect(search1.name).equals("search1"); expect(search1.json).equals("search1-json"); await vs1.renameSearch({ id: search1Id, name: "search1-updated" }); const search1UpdatedNameId = vs1.findSearchByName("search1-updated"); expect(search1UpdatedNameId).equals(search1Id); vs1.updateSearchJson(search1Id, "search1-json-updated"); const search1Updated = vs1.getSearch(search1Id); expect(search1Updated.json).equals("search1-json-updated"); vs1.deleteSearch(search2); expect(vs1.findSearchByName("search2")).equals(0); const guids = []; const rowIds = []; const nGuids = 1000; for (let i = 0; i < nGuids; i++) { const guid = Guid.createValue(); const rowId = vs1.addGuid(guid); guids.push(guid); rowIds.push(rowId); } for (let i = 0; i < nGuids; i++) { expect(vs1.getGuid(rowIds[i])).equals(guids[i]); expect(vs1.addGuid(guids[i])).equals(rowIds[i]); } let count = 0; vs1.iterateGuids(rowIds, (guid, row) => { count++; expect(guid).not.undefined; expect(guids.indexOf(guid)).not.equals(-1); const rowString1 = ViewStore.fromRowId(row); expect(rowString1.startsWith("@")).true; expect(ViewStore.toRowId(rowString1)).equals(row); // round trip }); expect(count).equals(nGuids); const largeNumber = 0x7ffffffffffff; expect(ViewStore.toRowId(ViewStore.fromRowId(largeNumber))).equals(largeNumber); vs1.vacuum(); }); }); //# sourceMappingURL=ViewStoreDb.test.js.map