Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow opening Realms with asymmetric tables #1592

Merged
merged 5 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Fixed

- Fixed a bug where opening a Realm that contains asymmetric tables will crash the process with an error saying `You cannot query an asymmetric class`. ([#1591](https://github.com/realm/realm-studio/issues/1591))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should be moved to CHANGELOG instead?

- Fixed an issue where opening a synchronized Realm that is open in another process would result in an error with a message `History type not consistent`. ([#1593](https://github.com/realm/realm-studio/issues/1593))

### Internals
Expand Down
2 changes: 1 addition & 1 deletion src/services/data-exporter/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class JSONExportEngine implements IExportEngine {
public export(realm: Realm, destinationPath: string) {
const resultMap: ResultMap = realm.schema.reduce(
(map: ResultMap, objectSchema) => {
if (!objectSchema.embedded) {
if (!objectSchema.embedded && !objectSchema.asymmetric) {
map[objectSchema.name] = realm.objects(objectSchema.name).snapshot();
}
return map;
Expand Down
94 changes: 94 additions & 0 deletions src/ui/RealmBrowser/Content/AsymmetricObjectCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2023 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

/**
* Mock implementation of Realm.Result<T> that returns empty results. This is because an asymmetric table
* cannot be queried and thus we cannot obtain the results wrapping it.
*/
export class AsymmetricObjectCollection<T extends Realm.Object>
extends Array<T>
implements Realm.Results<T>
{
public readonly type: Realm.PropertyType;
public readonly optional = false;

constructor(schema: Realm.ObjectSchema) {
super();
this.type = schema.name;
}

public toJSON(): any[] {
return this.toJSON();
}

public update(): void {
throw new Error('Not implemented');
}

public description(): string {
throw new Error('Not implemented');
}

public isValid(): boolean {
return true;
}

public isEmpty(): boolean {
return true;
}

public min(property: string): any {
throw new Error('Not implemented');
}

public max(property: string): any {
throw new Error('Not implemented');
}

public sum(property: string): any {
throw new Error('Not implemented');
}

public avg(property: string): any {
throw new Error('Not implemented');
}

public filtered(): Realm.Results<T> {
return this;
}

public sorted(): Realm.Results<T> {
return this;
}

public snapshot(): Realm.Results<T> {
return this;
}

public addListener(): void {
throw new Error('Not implemented');
}

public removeListener(): void {
throw new Error('Not implemented');
}

public removeAllListeners(): void {
throw new Error('Not implemented');
}
}
8 changes: 4 additions & 4 deletions src/ui/RealmBrowser/Content/SingleObjectCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class SingleObjectCollection<T extends Realm.Object>
return this.toJSON();
}

public update() {
public update(): void {
throw new Error('Not implemented');
}

Expand Down Expand Up @@ -80,15 +80,15 @@ export class SingleObjectCollection<T extends Realm.Object>
return this;
}

public addListener() {
public addListener(): void {
throw new Error('Not implemented');
}

public removeListener() {
public removeListener(): void {
throw new Error('Not implemented');
}

public removeAllListeners() {
public removeAllListeners(): void {
throw new Error('Not implemented');
}
}
10 changes: 8 additions & 2 deletions src/ui/RealmBrowser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { isPrimitive } from './primitives';
import { RealmBrowser } from './RealmBrowser';
import * as schemaUtils from './schema-utils';
import { SingleObjectCollection } from './Content/SingleObjectCollection';
import { AsymmetricObjectCollection } from './Content/AsymmetricObjectCollection';

// TODO: Remove this interface once the Realm.ObjectSchemaProperty
// has a name parameter in its type definition.
Expand Down Expand Up @@ -637,10 +638,14 @@ class RealmBrowserContainer

private getClassFocus = (className: string): IClassFocus => {
if (this.realm) {
const schema = this.realm.schema.find(s => s.name === className);

return {
kind: 'class',
className,
results: this.realm.objects(className),
results: schema?.asymmetric
? new AsymmetricObjectCollection(schema)
: this.realm.objects(className),
properties: this.derivePropertiesFromClassName(className),
isEmbedded: this.isEmbeddedType(className),
};
Expand Down Expand Up @@ -700,7 +705,8 @@ class RealmBrowserContainer

private getSchemaLength = (name: string) => {
if (this.realm) {
return this.realm.objects(name).length;
const schema = this.realm.schema.find(s => s.name === name);
return schema?.asymmetric ? 0 : this.realm.objects(name).length;
} else {
return 0;
}
Expand Down