Skip to content

Commit

Permalink
Merge branch 'devel' into dbeaver/dbeaver-vscode#3-remove-redundunt-p…
Browse files Browse the repository at this point in the history
…lugins
  • Loading branch information
mr-anton-t authored Sep 18, 2024
2 parents b40a2d2 + 46309e9 commit 252f34b
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 76 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ You can see a live demo of CloudBeaver here: https://demo.cloudbeaver.io
## Contribution
As a community-driven open-source project, we warmly welcome contributions through GitHub pull requests.

[We are happy to reward](https://dbeaver.com/help-beaver/) our most active contributors every major sprint.
[We are happy to reward](https://dbeaver.com/help-dbeaver/) our most active contributors every major sprint.
The most significant contribution to our code for the major release 24.2.0 was made by:
1. [matthieukhl](https://github.com/matthieukhl)
17 changes: 5 additions & 12 deletions webapp/packages/core-authentication/src/UsersResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import { runInAction } from 'mobx';

import { injectable } from '@cloudbeaver/core-di';
import {
CACHED_RESOURCE_DEFAULT_PAGE_LIMIT,
CACHED_RESOURCE_DEFAULT_PAGE_OFFSET,
CachedMapAllKey,
CachedMapResource,
CachedResourceOffsetPageKey,
CachedResourceOffsetPageListKey,
getOffsetPageKeyInfo,
isResourceAlias,
type ResourceKey,
resourceKeyList,
Expand Down Expand Up @@ -260,19 +259,11 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso

usersList.push(user);
} else {
const pageKey =
this.aliases.isAlias(originalKey, CachedResourceOffsetPageKey) || this.aliases.isAlias(originalKey, CachedResourceOffsetPageListKey);
const { isPageListKey, offset, limit } = getOffsetPageKeyInfo(this, originalKey);
const filterKey = this.aliases.isAlias(originalKey, UsersResourceFilterKey);
let offset = CACHED_RESOURCE_DEFAULT_PAGE_OFFSET;
let limit = CACHED_RESOURCE_DEFAULT_PAGE_LIMIT;
let userIdMask: string | undefined;
let enabledState: boolean | undefined;

if (pageKey) {
offset = pageKey.options.offset;
limit = pageKey.options.limit;
}

if (filterKey) {
userIdMask = filterKey.options.userId;
enabledState = filterKey.options.enabledState;
Expand All @@ -294,7 +285,9 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
usersList.push(...users);

pages.push([
CachedResourceOffsetPageListKey(offset, users.length).setParent(filterKey!),
isPageListKey
? CachedResourceOffsetPageListKey(offset, users.length).setParent(filterKey)
: CachedResourceOffsetPageKey(offset, users.length).setParent(filterKey),
users.map(user => user.userId),
users.length === limit,
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
CachedResourceOffsetPageKey,
CachedResourceOffsetPageListKey,
CachedResourceOffsetPageTargetKey,
getOffsetPageKeyInfo,
isResourceAlias,
type ResourceKey,
resourceKeyList,
Expand Down Expand Up @@ -96,16 +97,8 @@ export class DBObjectResource extends CachedMapResource<string, DBObject> {
}

protected async loader(originalKey: ResourceKey<string>): Promise<Map<string, DBObject>> {
let limit = this.navTreeResource.childrenLimit;
let offset = CACHED_RESOURCE_DEFAULT_PAGE_OFFSET;
const parentKey = this.aliases.isAlias(originalKey, DBObjectParentKey);
const pageKey =
this.aliases.isAlias(originalKey, CachedResourceOffsetPageKey) || this.aliases.isAlias(originalKey, CachedResourceOffsetPageListKey);

if (pageKey) {
limit = pageKey.options.limit;
offset = pageKey.options.offset;
}
const { isPageListKey, offset, limit } = getOffsetPageKeyInfo(this, originalKey, undefined, this.navTreeResource.childrenLimit);

if (parentKey) {
const nodeId = parentKey.options.parentId;
Expand All @@ -116,11 +109,11 @@ export class DBObjectResource extends CachedMapResource<string, DBObject> {
this.set(resourceKeyList(keys), dbObjects);

this.offsetPagination.setPage(
CachedResourceOffsetPageKey(offset, limit).setParent(CachedResourceOffsetPageTargetKey(originalKey)),
isPageListKey
? CachedResourceOffsetPageListKey(offset, limit).setParent(parentKey || CachedResourceOffsetPageTargetKey(nodeId))
: CachedResourceOffsetPageKey(offset, limit).setParent(parentKey || CachedResourceOffsetPageTargetKey(nodeId)),
keys,
this.navTreeResource.offsetPagination.hasNextPage(
CachedResourceOffsetPageKey(offset, limit).setParent(CachedResourceOffsetPageTargetKey(nodeId)),
),
keys.length === limit,
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import { injectable } from '@cloudbeaver/core-di';
import { Executor, ExecutorInterrupter, IExecutionContext, IExecutor } from '@cloudbeaver/core-executor';
import { ProjectInfoResource } from '@cloudbeaver/core-projects';
import {
CACHED_RESOURCE_DEFAULT_PAGE_OFFSET,
CachedMapAllKey,
CachedMapResource,
CachedResourceOffsetPageKey,
CachedResourceOffsetPageListKey,
CachedResourceOffsetPageTargetKey,
getOffsetPageKeyInfo,
type ICachedResourceMetadata,
isResourceAlias,
isResourceKeyList,
Expand Down Expand Up @@ -275,9 +275,10 @@ export class NavTreeResource extends CachedMapResource<string, string[], Record<
parts.splice(parts.length - 1, 1, name);
const path = parts.join('/');

this.markTreeOutdated(parentId);
this.markOutdated(parentId);
this.markLoaded(node.id);
this.onDataOutdated.execute(parentId);

return path;
} finally {
this.markLoading(node.id, false);
Expand Down Expand Up @@ -461,27 +462,25 @@ export class NavTreeResource extends CachedMapResource<string, string[], Record<
}

protected async loader(originalKey: ResourceKey<string>): Promise<Map<string, string[]>> {
const pageKey =
this.aliases.isAlias(originalKey, CachedResourceOffsetPageKey) || this.aliases.isAlias(originalKey, CachedResourceOffsetPageListKey);
const { isPageListKey, pageTargetKey, offset, limit } = getOffsetPageKeyInfo(this, originalKey, undefined, this.childrenLimit);
const allKey = this.aliases.isAlias(originalKey, CachedMapAllKey);
const pageTarget = this.aliases.isAlias(originalKey, CachedResourceOffsetPageTargetKey);

if (allKey) {
throw new Error('Loading all nodes is prohibited');
}

const offset = pageKey?.options.offset ?? CACHED_RESOURCE_DEFAULT_PAGE_OFFSET;
const limit = pageKey?.options.limit ?? this.childrenLimit;
const values: NavNodeChildrenQuery[] = [];
const pages: Parameters<typeof this.offsetPagination.setPage>[] = [];

await ResourceKeyUtils.forEachAsync(originalKey, async key => {
const nodeId = pageTarget?.options?.target ?? key;
const nodeId = pageTargetKey ?? key;
const navNodeChildren = await this.loadNodeChildren(nodeId, offset, limit);
values.push(navNodeChildren);

pages.push([
CachedResourceOffsetPageKey(offset, navNodeChildren.navNodeChildren.length).setParent(CachedResourceOffsetPageTargetKey(nodeId)),
isPageListKey
? CachedResourceOffsetPageListKey(offset, navNodeChildren.navNodeChildren.length).setParent(CachedResourceOffsetPageTargetKey(nodeId))
: CachedResourceOffsetPageKey(offset, navNodeChildren.navNodeChildren.length).setParent(CachedResourceOffsetPageTargetKey(nodeId)),
navNodeChildren.navNodeChildren.map(node => node.id),
navNodeChildren.navNodeChildren.length === limit,
]);
Expand Down
72 changes: 45 additions & 27 deletions webapp/packages/core-resource/src/Resource/CachedResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { isResourceAlias } from './ResourceAlias';
import { ResourceError } from './ResourceError';
import type { ResourceKey, ResourceKeyFlat } from './ResourceKey';
import { resourceKeyAlias } from './ResourceKeyAlias';
import { resourceKeyList } from './ResourceKeyList';
import { isResourceKeyList, resourceKeyList } from './ResourceKeyList';
import { resourceKeyListAlias } from './ResourceKeyListAlias';
import { ResourceOffsetPagination } from './ResourceOffsetPagination';

Expand Down Expand Up @@ -91,41 +91,58 @@ export abstract class CachedResource<
this.aliases.add(CachedResourceParamKey, () => defaultKey);
this.aliases.add(CachedResourceListEmptyKey, () => resourceKeyList([]));
this.aliases.add(CachedResourceOffsetPageTargetKey, key => key.options.target);
this.aliases.add(CachedResourceOffsetPageKey, key => {
const keys = [];
const pageInfo = this.offsetPagination.getPageInfo(key);
this.aliases.add(
CachedResourceOffsetPageListKey,
key => key.parent! as any,
(param, key) => {
if (!isResourceKeyList(key)) {
return key as any;
}

if (pageInfo) {
const from = key.options.offset;
const to = key.options.offset + key.options.limit;
const keys = new Set<any>();
const pageInfo = this.offsetPagination.getPageInfo(param);

for (const page of pageInfo.pages) {
if (page.isHasCommonSegment(from, to)) {
keys.push(...page.get(from, to));
if (pageInfo) {
const from = param.options.offset;
const to = param.options.offset + param.options.limit;

for (const page of pageInfo.pages) {
if (page.isHasCommonSegment(from, to)) {
for (const pageKey of page.get(from, to)) {
keys.add(pageKey);
}
}
}
}
}
return resourceKeyList(key.filter(value => keys.has(value)));
},
);
this.aliases.add(
CachedResourceOffsetPageKey,
key => key.parent! as any,
(param, key) => {
if (!isResourceKeyList(key)) {
return key as any;
}

// todo: return single element?
return resourceKeyList([...new Set(keys)]);
});
this.aliases.add(CachedResourceOffsetPageListKey, key => {
const keys = [];
const pageInfo = this.offsetPagination.getPageInfo(key);
const keys = new Set<any>();
const pageInfo = this.offsetPagination.getPageInfo(param);

if (pageInfo) {
const from = key.options.offset;
const to = key.options.offset + key.options.limit;
if (pageInfo) {
const from = param.options.offset;
const to = param.options.offset + param.options.limit;

for (const page of pageInfo.pages) {
if (page.isHasCommonSegment(from, to)) {
keys.push(...page.get(from, to));
for (const page of pageInfo.pages) {
if (page.isHasCommonSegment(from, to)) {
for (const pageKey of page.get(from, to)) {
keys.add(pageKey);
}
}
}
}
}

return resourceKeyList([...new Set(keys)]);
});
return resourceKeyList(key.filter(value => keys.has(value)));
},
);

// this.logger.spy(this.beforeLoad, 'beforeLoad');
// this.logger.spy(this.onDataOutdated, 'onDataOutdated');
Expand Down Expand Up @@ -329,6 +346,7 @@ export abstract class CachedResource<
}

const pageKey = this.aliases.isAlias(param, CachedResourceOffsetPageKey) || this.aliases.isAlias(param, CachedResourceOffsetPageListKey);

if (pageKey) {
const pageInfo = this.offsetPagination.getPageInfo(pageKey);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export abstract class ResourceAlias<TKey, TOptions extends ResourceAliasOptions>
return undefined;
}

setParent(parent: ResourceAlias<TKey, any>): this {
setParent(parent: ResourceAlias<TKey, any> | undefined): this {
parent = this.parent ? this.parent.setParent(parent) : parent;
const copy = new (this.constructor as any)(this.id, this.options, parent) as this;
return copy;
Expand Down
45 changes: 36 additions & 9 deletions webapp/packages/core-resource/src/Resource/ResourceAliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,33 @@
import { toJS } from 'mobx';

import { isResourceAlias, type ResourceAlias, ResourceAliasFactory, type ResourceAliasOptions } from './ResourceAlias';
import type { ResourceKey } from './ResourceKey';
import type { ResourceKey, ResourceKeySimple } from './ResourceKey';
import type { ResourceKeyAlias } from './ResourceKeyAlias';
import { isResourceKeyList, ResourceKeyList } from './ResourceKeyList';
import type { ResourceKeyListAlias } from './ResourceKeyListAlias';
import type { ResourceLogger } from './ResourceLogger';

export type IParamAlias<TKey> = {
id: string;
getAlias: (param: ResourceAlias<TKey, any>) => ResourceKey<TKey>;
getAlias: ResourceAliasResolver<TKey, any>;
transformKey?: ResourceAliasKeyTransformer<TKey, any>;
};

export type ResourceAliasResolver<TKey, TOptions extends ResourceAliasOptions> = (param: ResourceAlias<TKey, TOptions>) => ResourceKey<TKey>;

export type ResourceAliasKeyTransformer<TKey, TOptions extends ResourceAliasOptions> = <T extends ResourceKeySimple<TKey>>(
param: ResourceAlias<TKey, TOptions>,
key: T,
) => T;

export class ResourceAliases<TKey> {
protected paramAliases: Array<IParamAlias<TKey>>;
private captureAliasGetterExecution: boolean;

constructor(private readonly logger: ResourceLogger, private readonly validateKey: (key: TKey) => boolean) {
constructor(
private readonly logger: ResourceLogger,
private readonly validateKey: (key: TKey) => boolean,
) {
this.paramAliases = [];

this.captureAliasGetterExecution = false;
Expand Down Expand Up @@ -52,21 +63,23 @@ export class ResourceAliases<TKey> {

add<TOptions extends ResourceAliasOptions>(
param: ResourceAlias<TKey, TOptions> | ResourceAliasFactory<TKey, TOptions>,
getAlias: (param: ResourceAlias<TKey, TOptions>) => ResourceKey<TKey>,
getAlias: ResourceAliasResolver<TKey, TOptions>,
transformKey?: ResourceAliasKeyTransformer<TKey, TOptions>,
): void {
this.paramAliases.push({ id: param.id, getAlias });
this.paramAliases.push({ id: param.id, getAlias, transformKey });
}

replace<TOptions extends ResourceAliasOptions>(
param: ResourceAlias<TKey, TOptions> | ResourceAliasFactory<TKey, TOptions>,
getAlias: (param: ResourceAlias<TKey, TOptions>) => ResourceKey<TKey>,
getAlias: ResourceAliasResolver<TKey, TOptions>,
transformKey?: ResourceAliasKeyTransformer<TKey, TOptions>,
): void {
const indexOf = this.paramAliases.findIndex(aliasInfo => aliasInfo.id === param.id);

if (indexOf === -1) {
this.add(param, getAlias);
this.add(param, getAlias, transformKey);
} else {
this.paramAliases.splice(indexOf, 1, { id: param.id, getAlias });
this.paramAliases.splice(indexOf, 1, { id: param.id, getAlias, transformKey });
}
}

Expand Down Expand Up @@ -111,6 +124,7 @@ export class ResourceAliases<TKey> {
transformToKey(param: ResourceKey<TKey>): TKey | ResourceKeyList<TKey> {
let deep = 0;

const transforms: Array<{ key: ResourceKeyAlias<TKey, any> | ResourceKeyListAlias<TKey, any>; alias: IParamAlias<TKey> }> = [];
while (deep < 10) {
if (!this.validateResourceKey(param)) {
let paramString = JSON.stringify(toJS(param));
Expand All @@ -124,7 +138,15 @@ export class ResourceAliases<TKey> {
if (isResourceAlias(param)) {
for (const alias of this.paramAliases) {
if (alias.id === param.id) {
param = this.captureGetAlias(alias, param);
transforms.push({ key: param, alias });
const nextParam = this.captureGetAlias(alias, param);

if (isResourceAlias(nextParam)) {
param = nextParam.setParent(param);
} else {
param = nextParam;
}

deep++;
break;
}
Expand All @@ -141,6 +163,11 @@ export class ResourceAliases<TKey> {
if (isResourceAlias(param)) {
throw new Error(`Alias ${param.toString()} is not registered in ${this.logger.getName()}`);
}

for (const { key, alias } of transforms) {
param = alias.transformKey ? alias.transformKey(key, param) : param;
}

return param;
}

Expand Down
Loading

0 comments on commit 252f34b

Please sign in to comment.