Skip to content

Commit

Permalink
Merge branch 'CB-3864-tree-css-modules' of https://github.com/dbeaver…
Browse files Browse the repository at this point in the history
…/cloudbeaver into CB-3864-tree-css-modules
  • Loading branch information
devnaumov committed Sep 20, 2023
2 parents a80df16 + 73bc7a3 commit 680e9bf
Show file tree
Hide file tree
Showing 49 changed files with 908 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ enum CBServerEventId {
cb_rm_project_removed,

cb_object_permissions_updated,
cb_subject_permissions_updated
cb_subject_permissions_updated,

cb_database_output_log_updated
}

# Events sent by client
Expand All @@ -48,7 +50,8 @@ enum CBEventTopic {
cb_scripts,
cb_projects,
cb_object_permissions,
cb_subject_permissions
cb_subject_permissions,
cb_database_output_log
}

# Base server event interface
Expand Down Expand Up @@ -153,6 +156,22 @@ type CBProjectsActiveEvent implements CBClientEvent {
projectIds: [String!]! # list of active projects
}

# Database output log event
type CBDatabaseOutputLogEvent implements CBServerEvent {
id: CBServerEventId!
topicId: CBEventTopic
contextId: String!
messages: [WSOutputLogInfo!]!
eventTimestamp: Int!
}

# Define the type for WSOutputLogInfo
type WSOutputLogInfo {
severity: String
message: String
# Add more fields as needed
}

extend type Query {
emptyEvent: Boolean
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ extend type Mutation {
sql: String!,
resultId: ID,
filter: SQLDataFilter,
dataFormat: ResultDataFormat # requested data format. May be ignored by server
dataFormat: ResultDataFormat, # requested data format. May be ignored by server
readLogs: Boolean # added 23.2.1
): AsyncTaskInfo!

# Read data from table
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2023 DBeaver Corp and others
*
* 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.
*/
package io.cloudbeaver.server.jobs;

import io.cloudbeaver.model.session.WebSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.DBCStatement;
import org.jkiss.dbeaver.model.exec.output.DBCOutputSeverity;
import org.jkiss.dbeaver.model.exec.output.DBCOutputWriter;
import org.jkiss.dbeaver.model.exec.output.DBCServerOutputReader;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.websocket.event.WSOutputLogInfo;
import org.jkiss.dbeaver.model.websocket.event.session.WSOutputDBLogEvent;
import org.jkiss.dbeaver.runtime.DBWorkbench;

import java.util.ArrayList;
import java.util.List;


public class SqlOutputLogReaderJob extends AbstractJob {

private static final Log log = Log.getLog(SqlOutputLogReaderJob.class);

@NotNull
private final WebSession webSession;
@NotNull
private final DBCExecutionContext dbcExecutionContext;
@NotNull
private final DBCStatement dbcStatement;
@NotNull
private final DBCServerOutputReader dbcServerOutputReader;
@NotNull
private final String contextInfoId;

public SqlOutputLogReaderJob(@NotNull WebSession webSession,
@NotNull DBCExecutionContext dbcExecutionContext,
@NotNull DBCStatement dbcStatement,
@NotNull DBCServerOutputReader dbcServerOutputReader,
@NotNull String contextInfoId) {
super("Sql log state job");
this.webSession = webSession;
this.dbcExecutionContext = dbcExecutionContext;
this.dbcStatement = dbcStatement;
this.dbcServerOutputReader = dbcServerOutputReader;
this.contextInfoId = contextInfoId;
}

@Override
protected IStatus run(DBRProgressMonitor monitor) {
if (!DBWorkbench.getPlatform().isShuttingDown()) {
try {
if (!dbcStatement.isStatementClosed()) {
dumpOutput(monitor);
schedule(100);
}
} catch (Exception e) {
log.debug("Failed to execute job " + e.getMessage(), e);
}
}
return Status.OK_STATUS;
}

private void dumpOutput(DBRProgressMonitor monitor) {
if (!monitor.isCanceled()) {
if (dbcServerOutputReader.isAsyncOutputReadSupported()) {
try {
if (!dbcStatement.isStatementClosed()) {
List<WSOutputLogInfo> messages = new ArrayList<>();
dbcServerOutputReader.readServerOutput(monitor, dbcExecutionContext, null, dbcStatement, new DBCOutputWriter() {
@Override
public void println(@Nullable DBCOutputSeverity severity, @Nullable String message) {
if (message != null && severity != null) {
messages.add(new WSOutputLogInfo(severity.getName(), message));
}
}

@Override
public void flush() {
messages.clear();
}
});
webSession.addSessionEvent(new WSOutputDBLogEvent(
contextInfoId,
messages,
System.currentTimeMillis()));
}
} catch (DBCException e) {
log.error(e);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ WebAsyncTaskInfo asyncExecuteQuery(
@NotNull String sql,
@Nullable String resultId,
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat) throws DBException;
@Nullable WebDataFormat dataFormat,
boolean readLogs,
@NotNull WebSession webSession) throws DBException;

@WebAction
WebAsyncTaskInfo asyncReadDataFromContainer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.cloudbeaver.model.WebConnectionInfo;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.model.session.WebSessionProvider;
import io.cloudbeaver.server.jobs.SqlOutputLogReaderJob;
import org.eclipse.jface.text.Document;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
Expand All @@ -31,10 +32,12 @@
import org.jkiss.dbeaver.model.data.*;
import org.jkiss.dbeaver.model.edit.DBEPersistAction;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.exec.output.DBCServerOutputReader;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlannerConfiguration;
import org.jkiss.dbeaver.model.impl.AbstractExecutionSource;
import org.jkiss.dbeaver.model.impl.DefaultServerOutputReader;
import org.jkiss.dbeaver.model.navigator.DBNDatabaseItem;
import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
Expand Down Expand Up @@ -152,7 +155,9 @@ public WebSQLExecuteInfo processQuery(
@NotNull String sql,
@Nullable String resultId,
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat) throws DBWebException {
@Nullable WebDataFormat dataFormat,
@NotNull WebSession webSession,
boolean readLogs) throws DBWebException {
if (filter == null) {
// Use default filter
filter = new WebSQLDataFilter();
Expand Down Expand Up @@ -203,6 +208,17 @@ public WebSQLExecuteInfo processQuery(
webDataFilter.getOffset(),
webDataFilter.getLimit()))
{
SqlOutputLogReaderJob sqlOutputLogReaderJob = null;
if (readLogs) {
DBPDataSource dataSource = context.getDataSource();
DBCServerOutputReader dbcServerOutputReader = DBUtils.getAdapter(DBCServerOutputReader.class, dataSource);
if (dbcServerOutputReader == null) {
dbcServerOutputReader = new DefaultServerOutputReader();
}
sqlOutputLogReaderJob = new SqlOutputLogReaderJob(
webSession, context, dbStat, dbcServerOutputReader, contextInfo.getId());
sqlOutputLogReaderJob.schedule();
}
// Set query timeout
int queryTimeout = (int) session.getDataSource().getContainer().getPreferenceStore()
.getDouble(WebSQLConstants.QUOTA_PROP_SQL_QUERY_TIMEOUT);
Expand All @@ -220,6 +236,11 @@ public WebSQLExecuteInfo processQuery(
}

boolean hasResultSet = dbStat.executeStatement();

// Wait SqlLogStateJob, if its starts
if (sqlOutputLogReaderJob != null) {
sqlOutputLogReaderJob.join();
}
fillQueryResults(contextInfo, dataContainer, dbStat, hasResultSet, executeInfo, webDataFilter, dataFilter, dataFormat);
} catch (DBException e) {
throw new InvocationTargetException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ public void bindWiring(DBWBindingContext model) throws DBWebException {
env.getArgument("sql"),
env.getArgument("resultId"),
getDataFilter(env),
getDataFormat(env)))
getDataFormat(env),
CommonUtils.toBoolean(env.getArgument("readLogs")),
getWebSession(env)))
.dataFetcher("asyncReadDataFromContainer", env ->
getService(env).asyncReadDataFromContainer(
getSQLContext(env),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,18 @@ public WebAsyncTaskInfo asyncExecuteQuery(
@NotNull String sql,
@Nullable String resultId,
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat)
@Nullable WebDataFormat dataFormat,
boolean readLogs,
@NotNull WebSession webSession)
{
WebAsyncTaskProcessor<String> runnable = new WebAsyncTaskProcessor<String>() {
WebAsyncTaskProcessor<String> runnable = new WebAsyncTaskProcessor<>() {
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
try {
monitor.beginTask("Execute query", 1);
monitor.subTask("Process query " + sql);
WebSQLExecuteInfo executeResults = contextInfo.getProcessor().processQuery(
monitor, contextInfo, sql, resultId, filter, dataFormat);
monitor, contextInfo, sql, resultId, filter, dataFormat, webSession, readLogs);
this.result = executeResults.getStatusMessage();
this.extendedResults = executeResults;
} catch (Throwable e) {
Expand Down
9 changes: 9 additions & 0 deletions webapp/packages/core-blocks/src/FormControls/InputField.m.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
height: 100%;
}
}

.customIconContainer {
composes: iconContainer;
right: 4px;
width: 24px;
height: 24px;
cursor: auto;
}

.input[disabled] + .iconContainer {
cursor: auto;
opacity: 0.8;
Expand Down
5 changes: 4 additions & 1 deletion webapp/packages/core-blocks/src/FormControls/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { forwardRef, useCallback, useContext, useLayoutEffect, useRef, useState } from 'react';
import React, { forwardRef, useCallback, useContext, useLayoutEffect, useRef, useState } from 'react';
import styled, { use } from 'reshadow';

import type { ComponentStyle } from '@cloudbeaver/core-theming';
Expand Down Expand Up @@ -41,6 +41,7 @@ type BaseProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' |
style?: ComponentStyle;
canShowPassword?: boolean;
onCustomCopy?: () => void;
icon?: React.ReactElement;
};

type ControlledProps = BaseProps & {
Expand Down Expand Up @@ -90,6 +91,7 @@ export const InputField: InputFieldType = observer(
canShowPassword = true,
onChange,
onCustomCopy,
icon,
...rest
}: ControlledProps | ObjectProps<any, any>,
ref,
Expand Down Expand Up @@ -196,6 +198,7 @@ export const InputField: InputFieldType = observer(
<Icon name="copy" viewBox="0 0 32 32" className={styles.icon} />
</div>
)}
{icon && <div data-testid="icon-container" className={styles.customIconContainer}>{icon}</div>}
</div>
{(description || passwordType) && (
<div data-testid="field-description" className={s(styles, { fieldDescription: true, valid: !error, invalid: error })}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mutation asyncSqlExecuteQuery(
$resultId: ID
$filter: SQLDataFilter
$dataFormat: ResultDataFormat
$readLogs: Boolean
) {
taskInfo: asyncSqlExecuteQuery(
connectionId: $connectionId
Expand All @@ -13,6 +14,7 @@ mutation asyncSqlExecuteQuery(
resultId: $resultId
filter: $filter
dataFormat: $dataFormat
readLogs: $readLogs
) {
...AsyncTaskInfo
}
Expand Down
44 changes: 42 additions & 2 deletions webapp/packages/plugin-codemirror6/src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,49 @@ import { useCodemirrorExtensions } from './useCodemirrorExtensions';
import { type IDefaultExtensions, useEditorDefaultExtensions } from './useEditorDefaultExtensions';

export const Editor = observer<IEditorProps & IDefaultExtensions, IEditorRef>(
forwardRef(function Editor({ lineNumbers, extensions, ...rest }, ref) {
forwardRef(function Editor(
{
extensions,
lineNumbers,
tooltips,
highlightSpecialChars,
syntaxHighlighting,
bracketMatching,
dropCursor,
crosshairCursor,
foldGutter,
highlightActiveLineGutter,
highlightSelectionMatches,
highlightActiveLine,
indentOnInput,
rectangularSelection,
keymap,
lineWrapping,
...rest
},
ref,
) {
extensions = useCodemirrorExtensions(extensions);
const defaultExtensions = useEditorDefaultExtensions({ lineNumbers });


const defaultExtensions = useEditorDefaultExtensions({
lineNumbers,
tooltips,
highlightSpecialChars,
syntaxHighlighting,
bracketMatching,
dropCursor,
crosshairCursor,
foldGutter,
highlightActiveLineGutter,
highlightSelectionMatches,
highlightActiveLine,
indentOnInput,
rectangularSelection,
keymap,
lineWrapping,
});

extensions.set(...defaultExtensions);

return styled(EDITOR_BASE_STYLES)(
Expand Down
Loading

0 comments on commit 680e9bf

Please sign in to comment.