提交 ebae85f7 编写于 作者: C Charly

Merge branch 'devel' of https://github.com/dbeaver/dbeaver.git into devel

......@@ -531,7 +531,7 @@ toolbar.dbeaver-general.label = Datenbank Toolbar
toolbar.dbeaver-transaction-monitor.label = Transaktionsmonitor
toolbar.dbeaver-transactions.label = Transaktionen
view.database.navigator.title = Databanknavigator
view.database.navigator.title = Datenbanknavigator
view.database.output.title = Ausgabe
view.project.explorer.title = Projektexplorer
view.project.navigator.title = Projekte
......
......@@ -2077,7 +2077,7 @@ pref_page_sql_completion_label_show_column_procedures = Zeigt gespeicherte Proze
pref_page_sql_completion_label_show_column_procedures_tip = Vorschlag von gespeicherten Prozeduren nach SELECT und WHERE Schl\u00FCsselw\u00F6rtern
pref_page_sql_completion_label_use_global_search = Verwende globaloe Suche (in allen Schemata)
pref_page_sql_completion_label_use_global_search = Verwende globale Suche (in allen Schemata)
pref_page_sql_completion_label_use_global_search_tip = Suche nach Objekten in allen Schemata. Andernfalls nur in den ktuellen/Systemschemata suchen.
......
......@@ -20,6 +20,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
......@@ -212,6 +213,15 @@ public class DBeaverUI implements DBPPlatformUI {
return showError(title, null, new Status(IStatus.ERROR, DBeaverCore.PLUGIN_ID, message));
}
@Override
public void showMessageBox(String title, String message, boolean error) {
UIUtils.showMessageBox(
UIUtils.getActiveWorkbenchShell(),
title,
message,
error ? SWT.ICON_ERROR : SWT.ICON_INFORMATION);
}
@Override
public long getLongOperationTimeout() {
return DBeaverCore.getGlobalPreferenceStore().getLong(DBeaverPreferences.AGENT_LONG_OPERATION_TIMEOUT);
......
......@@ -433,7 +433,7 @@ class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgressMonito
if (request.activeQuery == null) {
final SQLScriptElement queryAtPos = request.editor.extractQueryAtPos(request.documentOffset);
if (queryAtPos != null) {
request.activeQuery = queryAtPos.getText() + " ";
request.activeQuery = queryAtPos.getText();
}
}
if (request.activeQuery == null) {
......
......@@ -177,7 +177,7 @@ public class SearchDataQuery implements ISearchQuery {
List<DBDAttributeConstraint> constraints = new ArrayList<>();
for (DBSEntityAttribute attribute : CommonUtils.safeCollection(entity.getAttributes(session.getProgressMonitor()))) {
if (params.fastSearch) {
if (!DBUtils.isIndexedAttribute(session.getProgressMonitor(), attribute)) {
if (DBUtils.findAttributeIndex(session.getProgressMonitor(), attribute) == null) {
continue;
}
}
......
......@@ -25,13 +25,16 @@ import org.jkiss.dbeaver.ext.generic.model.*;
import org.jkiss.dbeaver.model.DBPDataKind;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameterKind;
import org.jkiss.utils.CommonUtils;
import org.osgi.framework.Version;
import java.lang.reflect.InvocationTargetException;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
......@@ -191,6 +194,18 @@ public class FireBirdUtils {
return sql.toString();
}
public static String getPlan(JDBCPreparedStatement statement) {
String plan = "";
try {
plan = (String) statement.getOriginal().getClass().getMethod("getExecutionPlan").invoke(statement.getOriginal());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return plan;
}
private static Pattern VERSION_PATTERN = Pattern.compile(".+\\-V([0-9]+\\.[0-9]+\\.[0-9]+).+");
......
......@@ -16,19 +16,25 @@
*/
package org.jkiss.dbeaver.ext.firebird.model;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ext.firebird.model.plan.FireBirdPlanAnalyser;
import org.jkiss.dbeaver.ext.generic.GenericConstants;
import org.jkiss.dbeaver.ext.generic.model.*;
import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaModel;
import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaObject;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCDatabaseMetaData;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCConstants;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.exec.plan.DBCPlanStyle;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
......@@ -42,7 +48,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FireBirdDataSource extends GenericDataSource {
public class FireBirdDataSource extends GenericDataSource
implements DBCQueryPlanner {
private static final Log log = Log.getLog(FireBirdDataSource.class);
......@@ -124,4 +131,23 @@ public class FireBirdDataSource extends GenericDataSource {
// Init
super.initialize(monitor);
}
@NotNull
@Override
public FireBirdDataSource getDataSource() {
return this;
}
@Override
public DBCPlan planQueryExecution(DBCSession session, String query) throws DBException {
FireBirdPlanAnalyser plan = new FireBirdPlanAnalyser(this, (JDBCSession) session, query);
plan.explain();
return plan;
}
@Override
public DBCPlanStyle getPlanStyle() {
return DBCPlanStyle.PLAN;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.firebird.FireBirdUtils;
import org.jkiss.dbeaver.ext.firebird.model.FireBirdDataSource;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.exec.plan.DBCPlanNode;
public class FireBirdPlanAnalyser implements DBCPlan {
private FireBirdDataSource dataSource;
private JDBCSession session;
private String query;
private List<FireBirdPlanNode> rootNodes;
public FireBirdPlanAnalyser(FireBirdDataSource dataSource, JDBCSession session, String query)
{
this.dataSource = dataSource;
this.session = session;
this.query = query;
}
public void explain()
throws DBException
{
try {
JDBCPreparedStatement dbStat = session.prepareStatement(getQueryString());
// Read explained plan
try {
String plan = FireBirdUtils.getPlan(dbStat);
FireBirdPlanBuilder builder = new FireBirdPlanBuilder(plan);
rootNodes = builder.Build(session);
} finally {
dbStat.close();
}
} catch (SQLException e) {
throw new DBCException(e, session.getDataSource());
}
}
@Override
public String getQueryString() {
return query;
}
@Override
public String getPlanQueryString() throws DBException {
return null;
}
@Override
public Collection<? extends DBCPlanNode> getPlanNodes() {
return rootNodes;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.util.ArrayList;
import java.util.List;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
public class FireBirdPlanBuilder {
private String plan;
public FireBirdPlanBuilder(String plan) {
super();
this.plan = plan;
}
public List<FireBirdPlanNode> Build(JDBCSession session) throws DBCException {
List<FireBirdPlanNode> rootNodes = new ArrayList<>();
String [] plans = plan.split("\\n");
for (String plan: plans) {
FireBirdPlanParser pm = new FireBirdPlanParser(plan, session);
FireBirdPlanNode node = null;
try {
node = pm.parse();
} catch (FireBirdPlanException e) {
throw new DBCException(e.getMessage());
}
rootNodes.add(node);
}
return rootNodes;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
class FireBirdPlanException extends Exception {
/**
* FireBirdPlanException
*/
private static final long serialVersionUID = 1L;
public FireBirdPlanException(String expected, String actual, int position, String plan) {
super(makeMessage(expected, actual, position, plan));
}
public FireBirdPlanException(String unexpected, int position, String plan) {
super(makeMessage(unexpected, position, plan));
}
public FireBirdPlanException(String info, String index) {
super(String.format("Error when getting info about %1$s index(%2$s)", index, info));
}
private static String makeMessage(String expected, String actual, int position, String plan)
{
return addPlanMark(
String.format("Error parsing plan - expected %1$s at position %2$d but got %3$s", expected, position, actual),
position, plan);
}
private static String makeMessage(String unexpected, int position, String plan)
{
return addPlanMark(
String.format("Error parsing plan - unexpected token %1$s at position %2$d", unexpected, position),
position, plan);
}
private static String addPlanMark(String message, int position, String plan)
{
StringBuilder sb = new StringBuilder(message);
sb.append("\n");
sb.append(plan.substring(0, position - 1));
sb.append("^^^");
sb.append(plan.substring(position));
return sb.toString();
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jkiss.dbeaver.model.exec.plan.DBCPlanNode;
public class FireBirdPlanNode implements DBCPlanNode {
String plan;
FireBirdPlanNode parent;
private List<FireBirdPlanNode> nested;
public FireBirdPlanNode(String plan) {
this.plan = plan;
this.nested = new ArrayList<>();
}
@Override
public DBCPlanNode getParent() {
return parent;
}
@Override
public Collection<FireBirdPlanNode> getNested() {
return nested;
}
@Override
public String toString()
{
return plan;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.sql.SQLException;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
class FireBirdPlanParser {
private String plan;
private JDBCSession session;
private FireBirdPlanTokenMatcher tokenMatch;
FireBirdPlanParser(String plan, JDBCSession session) {
this.plan = plan;
this.session = session;
this.tokenMatch = new FireBirdPlanTokenMatcher(plan);
}
/*
PLAN <plan-expr>
<plan-expr> ::= (<plan-item> [, <plan-item> ...])
| <sorted-item>
| <joined-item>
| <merged-item>
<sorted-item> ::= SORT (<plan-item>)
<joined-item> ::= JOIN (<plan-item>, <plan-item> [, <plan-item> ...])
<merged-item> ::= [SORT] MERGE (<sorted-item>, <sorted-item> [, <sorted-item> ...])
<plan-item> ::= <basic-item> | <plan-expr>
<basic-item> ::= <relation>
{NATURAL
| INDEX (<indexlist>)
| ORDER index [INDEX (<indexlist>)]}
<relation> ::= table | view [table]
<indexlist> ::= index [, index ...]
*/
FireBirdPlanNode parse() throws FireBirdPlanException {
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.PLAN);
FireBirdPlanNode node = addPlanNode(null, plan);
tokenMatch.jump();
planExpr(node);
return node;
}
private void planExpr(FireBirdPlanNode parent) throws FireBirdPlanException {
switch (tokenMatch.token) {
case LEFTPARENTHESE:
do {
tokenMatch.jump();
planItem(parent);
} while (tokenMatch.token == FireBirdPlanToken.COMMA);
//tokenMatch.checkToken(FireBirdPlanToken.RIGHTPARENTHESE);
break;
case SORT:
sortedItem(parent);
break;
case JOIN:
joinedItem(parent);
break;
case SORT_MERGE:
mergedItem(parent, true);
break;
case MERGE:
mergedItem(parent, false);
break;
default:
tokenMatch.raisePlanTokenException();
}
}
private void planItem(FireBirdPlanNode parent) throws FireBirdPlanException {
switch (tokenMatch.token) {
case IDENTIFICATOR:
basicItem(parent);
break;
default:
planExpr(parent);
break;
}
}
private void joinedItem(FireBirdPlanNode parent) throws FireBirdPlanException {
tokenMatch.checkToken(FireBirdPlanToken.JOIN);
FireBirdPlanNode node = addPlanNode(parent, "JOIN");
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.LEFTPARENTHESE);
do {
tokenMatch.jump();
planItem(node);
tokenMatch.jump();
} while (tokenMatch.getToken() == FireBirdPlanToken.COMMA);
tokenMatch.checkToken(FireBirdPlanToken.RIGHTPARENTHESE);
}
private void mergedItem(FireBirdPlanNode parent, Boolean sorted) throws FireBirdPlanException {
if (sorted) {
tokenMatch.checkToken(FireBirdPlanToken.SORT_MERGE);
} else {
tokenMatch.checkToken(FireBirdPlanToken.MERGE);
}
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.LEFTPARENTHESE);
FireBirdPlanNode node = null;
if (sorted) {
node = addPlanNode(parent, "SORT MERGE");
} else {
node = addPlanNode(parent, "MERGE");
}
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.LEFTPARENTHESE);
do {
tokenMatch.jump();
sortedItem(node);
tokenMatch.jump();
} while (tokenMatch.getToken() == FireBirdPlanToken.COMMA);
tokenMatch.checkToken(FireBirdPlanToken.RIGHTPARENTHESE);
}
private void sortedItem(FireBirdPlanNode parent) throws FireBirdPlanException {
tokenMatch.checkToken(FireBirdPlanToken.SORT);
FireBirdPlanNode node = addPlanNode(parent, "SORT");
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.LEFTPARENTHESE);
tokenMatch.jump();
planItem(node);
tokenMatch.checkToken(FireBirdPlanToken.RIGHTPARENTHESE);
}
private void basicItem(FireBirdPlanNode parent) throws FireBirdPlanException {
String aliases = collectIdentifiers();
switch (tokenMatch.token) {
case NATURAL:
addPlanNode(parent, aliases + " NATURAL");
break;
case INDEX:
String indexes = collectIndexes();
addPlanNode(parent, aliases + " INDEX (" + indexes + ")");
break;
case ORDER:
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.IDENTIFICATOR);
String orderIndex = tokenMatch.getValue();
tokenMatch.jump();
String text = aliases + " ORDER " + orderIndex;
if (tokenMatch.getToken() == FireBirdPlanToken.INDEX) {
String orderIndexes = collectIndexes();
text = text + " INDEX(" + orderIndexes + ")";
}
addPlanNode(parent, text);
break;
default:
tokenMatch.raisePlanTokenException();
}
}
private String collectIdentifiers() {
String identifiers = "";
while (tokenMatch.getToken() == FireBirdPlanToken.IDENTIFICATOR) {
identifiers = identifiers + tokenMatch.getValue() + " ";
tokenMatch.jump();
};
return identifiers;
}
private String collectIndexes() throws FireBirdPlanException {
tokenMatch.jump();
tokenMatch.checkToken(FireBirdPlanToken.LEFTPARENTHESE);
String indexes = "";
tokenMatch.jump();
while (tokenMatch.getToken() != FireBirdPlanToken.RIGHTPARENTHESE) {
indexes = indexes + tokenMatch.getValue() + indexInfo(tokenMatch.getValue());
tokenMatch.jump();
if(tokenMatch.getToken() == FireBirdPlanToken.COMMA) {
indexes = indexes + ",";
tokenMatch.jump();
}
};
return indexes;
}
private FireBirdPlanNode addPlanNode(FireBirdPlanNode parent, String text) {
FireBirdPlanNode node;
node = new FireBirdPlanNode(text);
node.parent = parent;
if (parent != null) {
parent.getNested().add(node);
}
return node;
}
private String indexInfo(String index) throws FireBirdPlanException {
StringBuilder sb = new StringBuilder();
sb.append("( ");
try {
JDBCPreparedStatement dbStat;
dbStat = session.prepareStatement(
"SELECT RDB$FIELD_NAME, RDB$STATISTICS FROM RDB$INDEX_SEGMENTS "
+ "WHERE RDB$INDEX_NAME = ? ORDER BY RDB$FIELD_POSITION");
try {
dbStat.setString(1, index);
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
while (dbResult.next()) {
sb.append(String.format("%1$s[%2$f]", dbResult.getString(1).trim(), dbResult.getDouble(2)));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
}
} finally {
dbStat.close();
}
} catch (SQLException e) {
throw new FireBirdPlanException(index, e.getMessage());
}
sb.append(" )");
return sb.toString();
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
enum FireBirdPlanToken {
PLAN("\\GPLAN\\b"),
JOIN("\\GJOIN\\b"),
NATURAL("\\GNATURAL\\b"),
SORT_MERGE("\\GSORT\\w+MERGE\\b"),
SORT("\\GSORT\\b"),
MERGE("\\GMERGE\\b"),
ORDER("\\GORDER\\b"),
INDEX("\\GINDEX\\b"),
LEFTPARENTHESE("\\G\\("),
RIGHTPARENTHESE("\\G\\)"),
COMMA("\\G,"),
WHITESPACE("\\G\\s+"),
IDENTIFICATOR("\\G\\b[\\w$]+\\b"),
UNRECOGNIZED("\\G\\b[^\\s]+\\b");
private final Pattern pattern;
private FireBirdPlanToken(String regex) {
pattern = Pattern.compile(regex);
}
public Matcher newMatcher(String text) {
Matcher matcher = pattern.matcher(text);
return matcher;
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ext.firebird.model.plan;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
class FireBirdPlanTokenMatcher {
private List<Matcher> matchers = new ArrayList<>(FireBirdPlanToken.values().length);
private Map<Matcher,FireBirdPlanToken> matchertokens = new HashMap<>(FireBirdPlanToken.values().length);
private int position = 0;
FireBirdPlanToken token;
private String value;
private String subject;
public FireBirdPlanTokenMatcher(String subject) {
super();
this.subject = subject;
for (FireBirdPlanToken token: FireBirdPlanToken.values()) {
Matcher matcher = token.newMatcher(subject);
matchers.add(matcher);
matchertokens.put(matcher, token);
}
}
FireBirdPlanToken getToken() {
return token;
}
String getValue() {
return value;
}
void find() {
for (Matcher matcher: matchers) {
if (matcher.find(position)) {
position = position + matcher.group().length();
token = matchertokens.get(matcher);
value = matcher.group();
return;
}
}
token = FireBirdPlanToken.IDENTIFICATOR;
value = "???";
return;
}
void jump() {
do {
find();
} while (token == FireBirdPlanToken.WHITESPACE);
return;
}
void checkToken(FireBirdPlanToken expected) throws FireBirdPlanException {
if (expected != this.token) {
raisePlanTokenException(expected, this.token);
}
}
void raisePlanTokenException(FireBirdPlanToken expected, FireBirdPlanToken actual) throws FireBirdPlanException {
throw new FireBirdPlanException(expected.toString(), actual.toString(),
position - value.length(), subject);
}
void raisePlanTokenException() throws FireBirdPlanException {
throw new FireBirdPlanException(token.toString(),
position - value.length(), subject);
}
}
\ No newline at end of file
......@@ -234,7 +234,7 @@ public class MockDataExecuteWizard extends AbstractToolWizard<DBSDataManipulato
boolean hasMiltiUniqs = false;
Set<String> miltiUniqColumns = new HashSet<>();
for (DBSAttributeBase attribute : attributes) {
if (DBUtils.checkUnique(monitor, dbsEntity, attribute) == DBUtils.UNIQ_TYPE.MULTI) {
if (MockDataUtils.checkUnique(monitor, dbsEntity, attribute) == MockDataUtils.UNIQ_TYPE.MULTI) {
hasMiltiUniqs = true;
// collect the columns from multi-uniqs
......
......@@ -18,9 +18,15 @@
package org.jkiss.dbeaver.ext.mockdata;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.IntKeyMap;
import java.math.BigDecimal;
import java.util.List;
import java.util.Random;
public class MockDataUtils {
......@@ -30,6 +36,10 @@ public class MockDataUtils {
public static int SHORT_PRECISION = String.valueOf(Short.MAX_VALUE).length(); // 5
public static int BYTE_PRECISION = String.valueOf(Byte.MAX_VALUE).length(); // 3
public enum UNIQ_TYPE {
SINGLE, MULTI
}
private static final Random random = new Random();
private static IntKeyMap<Integer> degrees = new IntKeyMap<Integer>();
......@@ -135,4 +145,23 @@ public class MockDataUtils {
}
return getRandomInt(minimum, maximum, random);
}
public static UNIQ_TYPE checkUnique(DBRProgressMonitor monitor, DBSEntity dbsEntity, DBSAttributeBase attribute) throws DBException {
for (DBSEntityConstraint constraint : CommonUtils.safeCollection(dbsEntity.getConstraints(monitor))) {
DBSEntityConstraintType constraintType = constraint.getConstraintType();
if (constraintType.isUnique()) {
DBSEntityAttributeRef constraintAttribute = DBUtils.getConstraintAttribute(monitor, ((DBSEntityReferrer) constraint), attribute.getName());
if (constraintAttribute != null && constraintAttribute.getAttribute() == attribute) {
List<? extends DBSEntityAttributeRef> refColumns = ((DBSEntityReferrer) constraint).getAttributeReferences(monitor);
if (refColumns.size() > 1) {
return UNIQ_TYPE.MULTI;
} else {
return UNIQ_TYPE.SINGLE;
}
}
}
}
return null;
}
}
......@@ -189,7 +189,7 @@ public class MockDataWizardPageSettings extends ActiveWizardPage<MockDataExecute
cell.setImage(DBeaverIcons.getImage(DBValueFormatting.getTypeImage(attribute)));
cell.setText(attribute.getName());
try {
if (DBUtils.checkUnique(mockDataSettings.getMonitor(), mockDataSettings.getEntity(), attribute) != null) {
if (MockDataUtils.checkUnique(mockDataSettings.getMonitor(), mockDataSettings.getEntity(), attribute) != null) {
cell.setFont(boldFont);
}
} catch (DBException e) {
......
......@@ -18,6 +18,7 @@
package org.jkiss.dbeaver.ext.mockdata.generator;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.mockdata.MockDataUtils;
import org.jkiss.dbeaver.ext.mockdata.model.MockValueGenerator;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
......@@ -80,7 +81,7 @@ public abstract class AbstractMockValueGenerator implements MockValueGenerator {
public Object generateValue(DBRProgressMonitor monitor) throws DBException, IOException {
if (isFirstRun) {
isFirstRun = false;
isUnique = (DBUtils.checkUnique(monitor, dbsEntity, attribute) == DBUtils.UNIQ_TYPE.SINGLE);
isUnique = (MockDataUtils.checkUnique(monitor, dbsEntity, attribute) == MockDataUtils.UNIQ_TYPE.SINGLE);
if (isUnique && (attribute instanceof DBSAttributeEnumerable)) {
uniqueValues = new HashSet<>();
Collection<DBDLabelValuePair> valuePairs = readColumnValues(monitor, (DBSAttributeEnumerable) attribute, UNIQUE_VALUES_SET_SIZE);
......
......@@ -19,6 +19,7 @@ package org.jkiss.dbeaver.ext.mockdata.generator;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ext.mockdata.MockDataUtils;
import org.jkiss.dbeaver.model.DBPNamedObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
......@@ -72,7 +73,7 @@ public class FKGenerator extends AbstractMockValueGenerator
throw new DBException("Can't find reference column for '" + attribute.getName() + "'");
}
int numberRefRecords = (DBUtils.checkUnique(monitor, dbsEntity, attribute) == DBUtils.UNIQ_TYPE.SINGLE) ? UNIQ_REF_RECORDS_LIMIT : REF_RECORDS_LIMIT;
int numberRefRecords = (MockDataUtils.checkUnique(monitor, dbsEntity, attribute) == MockDataUtils.UNIQ_TYPE.SINGLE) ? UNIQ_REF_RECORDS_LIMIT : REF_RECORDS_LIMIT;
Collection<DBDLabelValuePair> values = readColumnValues(monitor, (DBSAttributeEnumerable) column.getReferencedColumn(), numberRefRecords);
for (DBDLabelValuePair value : values) {
refValues.add(value.getValue());
......
......@@ -100,7 +100,7 @@ public class SQLServerTableManager extends SQLTableManager<SQLServerTable, SQLSe
"Add table comment",
"EXEC " + SQLServerUtils.getSystemTableName(table.getDatabase(), isUpdate ? "sp_updateextendedproperty" : "sp_addextendedproperty") +
" 'MS_Description', " + SQLUtils.quoteString(command.getObject(), command.getObject().getDescription()) + "," +
" 'user', '" + table.getSchema().getName() + "'," +
" 'schema', '" + table.getSchema().getName() + "'," +
" 'table', '" + table.getName() + "'"));
}
}
......
......@@ -453,7 +453,7 @@ public class SQLServerSchema implements DBSSchema, DBPSaveableObject, DBPQualifi
if (forParent != null) {
sql.append(" AND kc.parent_object_id=?");
}
sql.append("\nORDER BY name");
sql.append("\nORDER BY kc.name");
JDBCPreparedStatement dbStat = session.prepareStatement(sql.toString());
dbStat.setLong(1, schema.getObjectId());
......@@ -696,7 +696,7 @@ public class SQLServerSchema implements DBSSchema, DBPSaveableObject, DBPQualifi
"\nFROM " + SQLServerUtils.getSystemTableName(schema.getDatabase(), "all_objects") + " p" +
"\nLEFT OUTER JOIN " + SQLServerUtils.getExtendedPropsTableName(schema.getDatabase()) + " ep ON ep.class=" + SQLServerObjectClass.OBJECT_OR_COLUMN.getClassId() + " AND ep.major_id=p.object_id AND ep.minor_id=0 AND ep.name='" + SQLServerConstants.PROP_MS_DESCRIPTION + "'" +
"\nWHERE p.type IN ('P','PC','X','TF','FN','IF') AND p.schema_id=?" +
"\nORDER BY name";
"\nORDER BY p.name";
JDBCPreparedStatement dbStat = session.prepareStatement(sql);
dbStat.setLong(1, schema.getObjectId());
......
......@@ -149,11 +149,7 @@ public class OracleSchemaManager extends SQLObjectEditor<OracleSchema, OracleDat
passwordText = UIUtils.createLabelText(composite, "User Password", null, SWT.BORDER | SWT.PASSWORD);
passwordText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
CLabel infoLabel = UIUtils.createInfoLabel(composite, "Creating a schema is the same as creating a user.\nYou need to specify a password.");
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
infoLabel.setLayoutData(gd);
UIUtils.createInfoLabel(composite, "Creating a schema is the same as creating a user.\nYou need to specify a password.", GridData.FILL_HORIZONTAL, 2);
return parent;
}
......
......@@ -154,7 +154,7 @@ public class PostgreConnectionPage extends ConnectionPageAbstract implements ICo
secureGroup.setLayoutData(gd);
secureGroup.setLayout(new GridLayout(2, false));
showNonDefault = UIUtils.createCheckbox(secureGroup, PostgreMessages.dialog_setting_connection_nondefaultDatabase, PostgreMessages.dialog_setting_connection_nondefaultDatabase_tip, true, 2);
showNonDefault = UIUtils.createCheckbox(secureGroup, PostgreMessages.dialog_setting_connection_nondefaultDatabase, PostgreMessages.dialog_setting_connection_nondefaultDatabase_tip, false, 2);
showNonDefault.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
......
......@@ -1341,19 +1341,19 @@ public final class DBUtils {
}
}
public static boolean isIndexedAttribute(DBRProgressMonitor monitor, DBSEntityAttribute attribute) throws DBException {
public static DBSTableIndex findAttributeIndex(DBRProgressMonitor monitor, DBSEntityAttribute attribute) throws DBException {
DBSEntity entity = attribute.getParentObject();
if (entity instanceof DBSTable) {
Collection<? extends DBSTableIndex> indexes = ((DBSTable) entity).getIndexes(monitor);
if (!CommonUtils.isEmpty(indexes)) {
for (DBSTableIndex index : indexes) {
if (getConstraintAttribute(monitor, index, attribute) != null) {
return true;
return index;
}
}
}
}
return false;
return null;
}
@Nullable
......@@ -1658,28 +1658,6 @@ public final class DBUtils {
return instance == null ? null : instance.getDefaultContext(meta);
}
public enum UNIQ_TYPE {
SINGLE, MULTI
}
public static UNIQ_TYPE checkUnique(DBRProgressMonitor monitor, DBSEntity dbsEntity, DBSAttributeBase attribute) throws DBException {
for (DBSEntityConstraint constraint : CommonUtils.safeCollection(dbsEntity.getConstraints(monitor))) {
DBSEntityConstraintType constraintType = constraint.getConstraintType();
if (constraintType.isUnique()) {
DBSEntityAttributeRef constraintAttribute = getConstraintAttribute(monitor, ((DBSEntityReferrer) constraint), attribute.getName());
if (constraintAttribute != null && constraintAttribute.getAttribute() == attribute) {
List<? extends DBSEntityAttributeRef> refColumns = ((DBSEntityReferrer) constraint).getAttributeReferences(monitor);
if (refColumns.size() > 1) {
return UNIQ_TYPE.MULTI;
} else {
return UNIQ_TYPE.SINGLE;
}
}
}
}
return null;
}
public static DBSEntityConstraint getConstraint(DBRProgressMonitor monitor, DBSEntity dbsEntity, DBSAttributeBase attribute) throws DBException {
for (DBSEntityConstraint constraint : CommonUtils.safeCollection(dbsEntity.getConstraints(monitor))) {
DBSEntityAttributeRef constraintAttribute = getConstraintAttribute(monitor, ((DBSEntityReferrer) constraint), attribute.getName());
......
......@@ -52,6 +52,7 @@ public interface DBPPlatformUI {
UserResponse showError(@NotNull final String title, @Nullable final String message, @NotNull final IStatus status);
UserResponse showError(@NotNull final String title, @Nullable final String message, @NotNull final Throwable e);
UserResponse showError(@NotNull final String title, @Nullable final String message);
void showMessageBox(@NotNull final String title, @Nullable final String message, boolean error);
/**
* Notification agent
......
......@@ -55,6 +55,11 @@ public class ConsoleUserInterface implements DBPPlatformUI {
return UserResponse.OK;
}
@Override
public void showMessageBox(String title, String message, boolean error) {
System.out.println(title + (message == null ? "" : ": " + message));
}
@Override
public long getLongOperationTimeout() {
return 0;
......
......@@ -522,6 +522,18 @@ public class UIUtils {
return tipLabel;
}
public static CLabel createInfoLabel(Composite parent, String text, int gridStyle, int hSpan) {
CLabel tipLabel = new CLabel(parent, SWT.NONE);
tipLabel.setImage(JFaceResources.getImage(org.eclipse.jface.dialogs.Dialog.DLG_IMG_MESSAGE_INFO));
tipLabel.setText(text);
GridData gd = new GridData(gridStyle);
if (hSpan > 1) {
gd.horizontalSpan = hSpan;
}
tipLabel.setLayoutData(gd);
return tipLabel;
}
public static Text createLabelText(Composite parent, String label, String value)
{
return createLabelText(parent, label, value, SWT.BORDER);
......
......@@ -7,5 +7,5 @@ instructions.configure=\
addRepository(type:1,location:https${#58}//dbeaver.io/update/svg/latest/,name:DBeaver SVG format support,enabled:true);\
addRepository(type:0,location:https${#58}//dbeaver.io/update/sshj/latest/,name:DBeaver SSHJ extension,enabled:true);\
addRepository(type:1,location:https${#58}//dbeaver.io/update/sshj/latest/,name:DBeaver SSHJ extension,enabled:true);\
addRepository(type:0,location:http${#58}//download.eclipse.org/releases/2018-09/,name:Eclipse 2018-09,enabled:true);\
addRepository(type:1,location:http${#58}//download.eclipse.org/releases/2018-09/,name:Eclipse 2018-09,enabled:true);
addRepository(type:0,location:http${#58}//download.eclipse.org/releases/oxygen/,name:Eclipse Oxygen,enabled:true);\
addRepository(type:1,location:http${#58}//download.eclipse.org/releases/oxygen/,name:Eclipse Oxygen,enabled:true);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册