feat: CB-835 execution context unique id

This commit is contained in:
Wroud
2021-12-20 01:56:26 +03:00
parent 9a066907e2
commit 86802a34da
17 changed files with 79 additions and 101 deletions
@@ -30,8 +30,6 @@ type DatabaseObjectInfo {
description: String
# Object type. Java class name in most cases
type: String
# NavigationNodeInfo for object
navNode: NavigatorNodeInfo
# Read object properties.
# Optional parameter 'ids' filters properties by id. null means all properties.
@@ -86,8 +84,8 @@ type NavigatorNodeInfo {
}
type DatabaseCatalog {
catalog: DatabaseObjectInfo!
schemaList: [ DatabaseObjectInfo! ]!
catalog: NavigatorNodeInfo!
schemaList: [ NavigatorNodeInfo! ]!
}
type DatabaseStructContainers {
@@ -30,23 +30,23 @@ public class WebCatalog {
private static final Log log = Log.getLog(WebCatalog.class);
private WebDatabaseObjectInfo catalog;
private List<WebDatabaseObjectInfo> schemaList = new ArrayList<>();
private WebNavigatorNodeInfo catalog;
private List<WebNavigatorNodeInfo> schemaList = new ArrayList<>();
public WebCatalog(@NotNull WebDatabaseObjectInfo catalog) {
public WebCatalog(@NotNull WebNavigatorNodeInfo catalog) {
this.catalog = catalog;
}
@NotNull
public WebDatabaseObjectInfo getCatalog() {
public WebNavigatorNodeInfo getCatalog() {
return catalog;
}
public List<WebDatabaseObjectInfo> getSchemaList() {
public List<WebNavigatorNodeInfo> getSchemaList() {
return schemaList;
}
public void setSchemaList(List<WebDatabaseObjectInfo> schemaList) {
public void setSchemaList(List<WebNavigatorNodeInfo> schemaList) {
this.schemaList = schemaList;
}
}
@@ -55,15 +55,6 @@ public class WebDatabaseObjectInfo {
// General properties
///////////////////////////////////
@Property
public WebNavigatorNodeInfo getNavNode(){
DBNModel navigatorModel = session.getNavigatorModel();
DBRProgressMonitor monitor = this.session.getProgressMonitor();
DBNNode node = navigatorModel.getNodeByObject(monitor, this.object, false);
return node == null ? null : new WebNavigatorNodeInfo(session, node);
}
@Property
public String getName() {
return object.getName();
@@ -23,6 +23,7 @@ import io.cloudbeaver.model.WebConnectionInfo;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.service.navigator.*;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBUtils;
@@ -189,30 +190,36 @@ public class WebServiceNavigator implements DBWServiceNavigator {
}
if(node instanceof DBSCatalog) {
WebDatabaseObjectInfo catalogObjectInfo = new WebDatabaseObjectInfo(connection.getSession(), node);
WebCatalog webCatalog = new WebCatalog(catalogObjectInfo);
WebNavigatorNodeInfo catalogObjectInfo = this.getNodeFromObject(connection.getSession(), node);
if(contextDefaults.supportsSchemaChange()) {
try {
if (catalogObjectInfo != null) {
WebCatalog webCatalog = new WebCatalog(catalogObjectInfo);
List<WebDatabaseObjectInfo> schemaList = webCatalog.getSchemaList();
Collection<? extends DBSObject> objectsCollection = ((DBSObjectContainer) node).getChildren(monitor);
if (contextDefaults.supportsSchemaChange()) {
try {
List<WebNavigatorNodeInfo> schemaList = webCatalog.getSchemaList();
Collection<? extends DBSObject> objectsCollection = ((DBSObjectContainer) node).getChildren(monitor);
for (DBSObject schemaObject : objectsCollection) {
if (!dataSource.getContainer().getNavigatorSettings().isShowSystemObjects() && DBUtils.isSystemObject(node)) {
continue;
}
if (schemaObject instanceof DBSSchema) {
schemaList.add(new WebDatabaseObjectInfo(connection.getSession(), schemaObject));
for (DBSObject schemaObject : objectsCollection) {
if (!dataSource.getContainer().getNavigatorSettings().isShowSystemObjects() && DBUtils.isSystemObject(node)) {
continue;
}
if (schemaObject instanceof DBSSchema) {
WebNavigatorNodeInfo schemaNodeInfo = this.getNodeFromObject(connection.getSession(), schemaObject);
if(schemaNodeInfo != null){
schemaList.add(schemaNodeInfo);
}
}
}
} catch (DBException e) {
// throw new DBWebException("Error reading schema list", e);
// TODO: we need to log some message to console
}
} catch (DBException e) {
// throw new DBWebException("Error reading schema list", e);
// TODO: we need to log some message to console
}
}
catalogList.add(webCatalog);
catalogList.add(webCatalog);
}
}
}
return structContainers;
@@ -236,6 +243,15 @@ public class WebServiceNavigator implements DBWServiceNavigator {
return Collections.emptyList();
}
@Nullable
protected WebNavigatorNodeInfo getNodeFromObject(WebSession session, DBSObject object){
DBNModel navigatorModel = session.getNavigatorModel();
DBRProgressMonitor monitor = session.getProgressMonitor();
DBNNode node = navigatorModel.getNodeByObject(monitor, object, false);
return node == null ? null : new WebNavigatorNodeInfo(session, node);
}
@Override
public String renameNode(@NotNull WebSession session, @NotNull String nodePath, @NotNull String newName) throws DBWebException {
try {
@@ -289,7 +305,8 @@ public class WebServiceNavigator implements DBWServiceNavigator {
Map<String, Object> options = new LinkedHashMap<>();
for (Map.Entry<DBNDatabaseNode, DBEObjectMaker> ne : nodes.entrySet()) {
DBSObject object = ne.getKey().getObject();
DBCExecutionContext executionContext = getCommandExecutionContext(object);
DBPDataSource dataSource = ((DBNDatabaseNode) object).getDataSource();
DBCExecutionContext executionContext = getCommandExecutionContext(dataSource);
DBECommandContext commandContext = new WebCommandContext(executionContext, false);
ne.getValue().deleteObject(commandContext, object, options);
commandContext.saveChanges(session.getProgressMonitor(), options);
@@ -64,8 +64,6 @@ public class WebSQLProcessor {
private final SQLRuleManager ruleManager;
private final Map<String, WebSQLContextInfo> contexts = new LinkedHashMap<>();
private AtomicInteger contextId = new AtomicInteger();
WebSQLProcessor(@NotNull WebSession webSession, @NotNull WebConnectionInfo connection) {
this.webSession = webSession;
this.connection = connection;
@@ -110,10 +108,10 @@ public class WebSQLProcessor {
@NotNull
public WebSQLContextInfo createContext(String defaultCatalog, String defaultSchema) throws DBCException {
String contextId = String.valueOf(this.contextId.incrementAndGet());
WebSQLContextInfo contextInfo = new WebSQLContextInfo(this, contextId, defaultCatalog, defaultSchema);
UUID uuid = UUID.randomUUID();
WebSQLContextInfo contextInfo = new WebSQLContextInfo(this, uuid.toString(), defaultCatalog, defaultSchema);
synchronized (contexts) {
contexts.put(contextId, contextInfo);
contexts.put(uuid.toString(), contextInfo);
}
return contextInfo;
}
@@ -22,7 +22,7 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -web-config conf/cloudbeaver.conf"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dosgi.requiredJavaVersion=1.6 -Xms40m -Xmx512m"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="C:\devel\my\cloudbeaver\deploy\cloudbeaver\"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="D:\Work\cloudbeaver\workspace"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="io.cloudbeaver.product.ce.product"/>
<stringAttribute key="productFile" value="\web-server\DBeaverWebServer.product"/>
@@ -100,7 +100,7 @@
<setEntry value="org.jkiss.bundle.jedis@default:default"/>
<setEntry value="org.jkiss.bundle.lightcouch@default:default"/>
<setEntry value="org.jkiss.bundle.sshj@default:default"/>
<setEntry value="org.objectweb.asm*9.1.0.v20210209-1849@default:default"/>
<setEntry value="org.objectweb.asm@default:default"/>
<setEntry value="org.slf4j.api@default:default"/>
</setAttribute>
<setAttribute key="selected_workspace_bundles">
@@ -57,7 +57,7 @@ export class ConnectionExecutionContextResource extends CachedMapResource<string
this.updateContexts(baseContext);
this.markOutdated(); // TODO: should be removed, currently multiple contexts for same connection may change catalog/schema for all contexts of connection
return this.get(baseContext.baseId)!;
return this.get(baseContext.id)!;
});
}
@@ -159,7 +159,7 @@ export class ConnectionExecutionContextResource extends CachedMapResource<string
const connection = this.connectionInfoResource.get(connectionId);
return context.connectionId === connectionId && !connection?.connected;
})
)).map(context => context.baseId)
)).map(context => context.id)
)
);
}
@@ -170,13 +170,13 @@ export class ConnectionExecutionContextResource extends CachedMapResource<string
flat(ResourceKeyUtils.map(
key,
connectionId => this.values.filter(context => context.connectionId === connectionId)
)).map(context => context.baseId)
)).map(context => context.id)
)
);
}
private updateContexts(...contexts: IConnectionExecutionContextInfo[]): ResourceKeyList<string> {
const key = resourceKeyList(contexts.map(context => context.baseId));
const key = resourceKeyList(contexts.map(context => context.id));
const oldContexts = this.get(key);
this.set(key, oldContexts.map((context, i) => ({ ...context, ...contexts[i] })));
@@ -188,7 +188,6 @@ export class ConnectionExecutionContextResource extends CachedMapResource<string
function getBaseContext(context: SqlContextInfo): IConnectionExecutionContextInfo {
return {
...context,
baseId: getContextBaseId(context.connectionId, context.id),
};
}
@@ -47,6 +47,6 @@ export class ConnectionExecutionContextService {
): Promise<ConnectionExecutionContext> {
const context = await this.connectionExecutionContextResource.create(connectionId, defaultCatalog, defaultSchema);
return this.contexts.get(context.baseId);
return this.contexts.get(context.id);
}
}
@@ -9,5 +9,4 @@
import type { SqlContextInfo } from '@cloudbeaver/core-sdk';
export interface IConnectionExecutionContextInfo extends SqlContextInfo {
baseId: string;
}
@@ -12,13 +12,13 @@ import { injectable } from '@cloudbeaver/core-di';
import {
GraphQLService,
CachedDataResource,
DatabaseObjectInfo, ICachedResourceMetadata, ResourceKeyUtils, CachedMapAllKey
NavNodeInfoFragment, ICachedResourceMetadata, ResourceKeyUtils, CachedMapAllKey
} from '@cloudbeaver/core-sdk';
import { MetadataMap } from '@cloudbeaver/core-utils';
import { ConnectionInfoResource } from './ConnectionInfoResource';
export type ObjectContainer = Pick<DatabaseObjectInfo, 'name' | 'description' | 'type' | 'features'>;
export type ObjectContainer = NavNodeInfoFragment;
export interface ICatalogData {
catalog: ObjectContainer;
schemaList: ObjectContainer[];
@@ -139,6 +139,7 @@ string
const { navGetStructContainers } = await this.graphQLService.sdk.navGetStructContainers({
connectionId,
catalogId,
withDetails: false,
});
this.data.set(connectionId, navGetStructContainers.catalogList);
@@ -1,23 +1,11 @@
query navGetStructContainers($connectionId: ID!, $catalogId: ID) {
query navGetStructContainers($connectionId: ID!, $catalogId: ID, $withDetails: Boolean!) {
navGetStructContainers(connectionId: $connectionId, catalog: $catalogId) {
catalogList {
catalog {
name
description
type
navNode {
id
}
features
...NavNodeInfo
}
schemaList {
name
description
type
navNode {
id
}
features
...NavNodeInfo
}
}
}
+8 -20
View File
@@ -225,8 +225,8 @@ export interface DatabaseAuthModel {
}
export interface DatabaseCatalog {
catalog: DatabaseObjectInfo;
schemaList: DatabaseObjectInfo[];
catalog: NavigatorNodeInfo;
schemaList: NavigatorNodeInfo[];
}
export interface DatabaseDocument {
@@ -242,7 +242,6 @@ export interface DatabaseObjectInfo {
features?: Maybe<Array<Scalars['String']>>;
fullyQualifiedName?: Maybe<Scalars['String']>;
name?: Maybe<Scalars['String']>;
navNode?: Maybe<NavigatorNodeInfo>;
ordinalPosition?: Maybe<Scalars['Int']>;
overloadedName?: Maybe<Scalars['String']>;
properties?: Maybe<Array<Maybe<ObjectPropertyInfo>>>;
@@ -1672,9 +1671,10 @@ export interface RemoveDataTransferFileQuery { result?: Maybe<boolean> }
export type NavGetStructContainersQueryVariables = Exact<{
connectionId: Scalars['ID'];
catalogId?: Maybe<Scalars['ID']>;
withDetails: Scalars['Boolean'];
}>;
export interface NavGetStructContainersQuery { navGetStructContainers: { catalogList: Array<{ catalog: { name?: Maybe<string>; description?: Maybe<string>; type?: Maybe<string>; features?: Maybe<string[]>; navNode?: Maybe<{ id: string }> }; schemaList: Array<{ name?: Maybe<string>; description?: Maybe<string>; type?: Maybe<string>; features?: Maybe<string[]>; navNode?: Maybe<{ id: string }> }> }> } }
export interface NavGetStructContainersQuery { navGetStructContainers: { catalogList: Array<{ catalog: { id: string; name?: Maybe<string>; hasChildren?: Maybe<boolean>; nodeType?: Maybe<string>; icon?: Maybe<string>; folder?: Maybe<boolean>; inline?: Maybe<boolean>; navigable?: Maybe<boolean>; features?: Maybe<string[]>; object?: Maybe<{ features?: Maybe<string[]> }>; nodeDetails?: Maybe<Array<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>> }; schemaList: Array<{ id: string; name?: Maybe<string>; hasChildren?: Maybe<boolean>; nodeType?: Maybe<string>; icon?: Maybe<string>; folder?: Maybe<boolean>; inline?: Maybe<boolean>; navigable?: Maybe<boolean>; features?: Maybe<string[]>; object?: Maybe<{ features?: Maybe<string[]> }>; nodeDetails?: Maybe<Array<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>> }> }> } }
export type FormatSqlQueryQueryVariables = Exact<{
connectionId: Scalars['ID'];
@@ -2766,31 +2766,19 @@ export const RemoveDataTransferFileDocument = `
}
`;
export const NavGetStructContainersDocument = `
query navGetStructContainers($connectionId: ID!, $catalogId: ID) {
query navGetStructContainers($connectionId: ID!, $catalogId: ID, $withDetails: Boolean!) {
navGetStructContainers(connectionId: $connectionId, catalog: $catalogId) {
catalogList {
catalog {
name
description
type
navNode {
id
}
features
...NavNodeInfo
}
schemaList {
name
description
type
navNode {
id
}
features
...NavNodeInfo
}
}
}
}
`;
${NavNodeInfoFragmentDoc}`;
export const FormatSqlQueryDocument = `
query formatSqlQuery($connectionId: ID!, $contextId: ID!, $query: String!) {
query: sqlFormatQuery(
@@ -103,7 +103,7 @@ export class SqlEditorTabService extends Bootstrap {
);
for (const tab of tabs) {
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext!.baseId);
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext!.id);
if (!executionContext?.context) {
this.resetConnectionInfo(tab.handlerState);
@@ -119,7 +119,7 @@ export class SqlEditorTabService extends Bootstrap {
);
for (const tab of tabs) {
if (ResourceKeyUtils.includes(key, tab.handlerState.executionContext!.baseId)) {
if (ResourceKeyUtils.includes(key, tab.handlerState.executionContext!.id)) {
this.resetConnectionInfo(tab.handlerState);
}
}
@@ -137,7 +137,6 @@ export class SqlEditorTabService extends Bootstrap {
|| !['undefined', 'object'].includes(typeof tab.handlerState.executionContext)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.connectionId)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.id)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.baseId)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.defaultCatalog)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.defaultSchema)
|| !['string', 'undefined', 'object'].includes(typeof tab.handlerState.currentTabId)
@@ -153,7 +152,7 @@ export class SqlEditorTabService extends Bootstrap {
if (tab.handlerState.executionContext) {
await this.connectionInfo.load(CachedMapAllKey);
await this.connectionExecutionContextResource.loadAll();
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.baseId);
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.id);
if (!executionContext) {
this.resetConnectionInfo(tab.handlerState);
@@ -210,7 +209,7 @@ export class SqlEditorTabService extends Bootstrap {
return false;
}
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.baseId);
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.id);
if (!executionContext) {
return false;
@@ -234,7 +233,7 @@ export class SqlEditorTabService extends Bootstrap {
return false;
}
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.baseId);
const executionContext = this.connectionExecutionContextService.get(tab.handlerState.executionContext.id);
if (!executionContext) {
return false;
@@ -266,13 +265,13 @@ export class SqlEditorTabService extends Bootstrap {
}
private async destroyContext(contextInfo: IConnectionExecutionContextInfo) {
const executionContext = this.connectionExecutionContextService.get(contextInfo.baseId);
const executionContext = this.connectionExecutionContextService.get(contextInfo.id);
if (executionContext) {
try {
await executionContext.destroy();
} catch (exception) {
this.notificationService.logException(exception, `Failed to destroy SQL-context ${executionContext.context?.baseId}`, '', true);
this.notificationService.logException(exception, `Failed to destroy SQL-context ${executionContext.context?.id}`, '', true);
}
}
}
@@ -49,7 +49,7 @@ export const SqlEditorScreen: ScreenComponent<ISqlEditorScreenParams> = observer
},
}), { state: observable }, false);
if (context?.context?.baseId !== state.state?.executionContext?.baseId) {
if (context?.context?.id !== state.state?.executionContext?.id) {
state.setState(context?.context);
}
@@ -61,7 +61,7 @@ export class SqlEditorController implements IInitializableController, IDestructi
return true;
}
const context = this.connectionExecutionContextService.get(this.state.executionContext.baseId);
const context = this.connectionExecutionContextService.get(this.state.executionContext.id);
return context?.executing || false;
}
@@ -45,7 +45,7 @@ export class SqlExecutionPlanService {
): Promise<void> {
const contextInfo = editorState.executionContext;
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.baseId);
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.id);
if (!contextInfo || !executionContext) {
console.error('executeExecutionPlan executionContext is not provided');
@@ -61,7 +61,7 @@ export class SqlQueryService {
inNewTab: boolean
): Promise<void> {
const contextInfo = editorState.executionContext;
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.baseId);
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.id);
if (!contextInfo || !executionContext) {
console.error('executeEditorQuery executionContext is not provided');
@@ -126,7 +126,7 @@ export class SqlQueryService {
options?: IQueryExecutionOptions
): Promise<void> {
const contextInfo = editorState.executionContext;
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.baseId);
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.id);
if (!contextInfo || !executionContext) {
console.error('executeEditorQuery executionContext is not provided');