Search in sources :

Example 61 with DBPDataSource

use of org.jkiss.dbeaver.model.DBPDataSource in project dbeaver by dbeaver.

the class JDBCStructCache method loadChildren.

/**
 * Reads children objects from database
 *
 * @param monitor
 *            monitor
 * @param forObject
 *            object for which to read children. If null then reads children for all objects in this container.
 * @throws org.jkiss.dbeaver.DBException
 *             on error
 */
public synchronized void loadChildren(DBRProgressMonitor monitor, OWNER owner, @Nullable final OBJECT forObject) throws DBException {
    if ((forObject == null && this.childrenCached) || (forObject != null && (!forObject.isPersisted() || isChildrenCached(forObject))) || monitor.isCanceled()) {
        return;
    }
    if (forObject == null) {
        // If we have some child objects read before that - do not clear them.
        // We have to reuse them because there could be some references in cached model
        // clearChildrenCache(null);
        super.loadObjects(monitor, owner);
    }
    DBPDataSource dataSource = owner.getDataSource();
    if (dataSource == null) {
        throw new DBException(ModelMessages.error_not_connected_to_database);
    }
    try (JDBCSession session = DBUtils.openMetaSession(monitor, owner, "Load child objects")) {
        Map<OBJECT, List<CHILD>> objectMap = new HashMap<>();
        // Load columns
        try (JDBCStatement dbStat = prepareChildrenStatement(session, owner, forObject)) {
            dbStat.setFetchSize(DBConstants.METADATA_FETCH_SIZE);
            dbStat.executeStatement();
            JDBCResultSet dbResult = dbStat.getResultSet();
            if (dbResult != null) {
                try {
                    while (dbResult.next()) {
                        if (monitor.isCanceled()) {
                            return;
                        }
                        OBJECT object = forObject;
                        if (object == null) {
                            String objectName;
                            if (objectNameColumn instanceof Number) {
                                objectName = JDBCUtils.safeGetString(dbResult, ((Number) objectNameColumn).intValue());
                            } else {
                                objectName = JDBCUtils.safeGetStringTrimmed(dbResult, objectNameColumn.toString());
                            }
                            if (objectName == null) {
                                log.debug("NULL object name in " + this);
                                continue;
                            }
                            object = super.getCachedObject(objectName);
                            if (object == null) {
                                log.debug("Object '" + objectName + "' not found in struct cache (" + getClass().getSimpleName() + ")");
                                continue;
                            }
                        }
                        if (isChildrenCached(object)) {
                            // Already read
                            continue;
                        }
                        CHILD child = fetchChild(session, owner, object, dbResult);
                        if (child == null) {
                            continue;
                        }
                        // Add to map
                        List<CHILD> children = objectMap.get(object);
                        if (children == null) {
                            children = new ArrayList<>();
                            objectMap.put(object, children);
                        }
                        children.add(child);
                    }
                    if (monitor.isCanceled()) {
                        return;
                    }
                    // All children are read. Now assign them to parents
                    for (Map.Entry<OBJECT, List<CHILD>> colEntry : objectMap.entrySet()) {
                        if (!isChildrenCached(colEntry.getKey())) {
                            // isChildrenCached may return true if the same cache was read in other thread
                            // just skip
                            cacheChildren(colEntry.getKey(), colEntry.getValue());
                        }
                    }
                    if (forObject == null) {
                        if (objectMap.isEmpty()) {
                        // Nothing was read. May be it means empty list of children
                        // but possibly this feature is not supported [JDBC: SQLite]
                        } else {
                            // Now set empty column list for other tables
                            for (OBJECT tmpObject : getAllObjects(monitor, owner)) {
                                if (!isChildrenCached(tmpObject) && !objectMap.containsKey(tmpObject)) {
                                    cacheChildren(tmpObject, new ArrayList<>());
                                }
                            }
                            this.childrenCached = true;
                        }
                    } else if (!objectMap.containsKey(forObject)) {
                        cacheChildren(forObject, new ArrayList<>());
                    }
                } finally {
                    dbResult.close();
                }
            }
        }
    } catch (SQLException ex) {
        throw new DBException(ex, dataSource);
    }
}
Also used : DBException(org.jkiss.dbeaver.DBException) JDBCSession(org.jkiss.dbeaver.model.exec.jdbc.JDBCSession) SQLException(java.sql.SQLException) DBPDataSource(org.jkiss.dbeaver.model.DBPDataSource) JDBCStatement(org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement) JDBCResultSet(org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet)

Example 62 with DBPDataSource

use of org.jkiss.dbeaver.model.DBPDataSource in project dbeaver by dbeaver.

the class JDBCCompositeCache method loadObjects.

protected void loadObjects(DBRProgressMonitor monitor, OWNER owner, PARENT forParent) throws DBException {
    synchronized (objectCache) {
        if ((forParent == null && isFullyCached()) || (forParent != null && (!forParent.isPersisted() || objectCache.containsKey(forParent)))) {
            return;
        }
    }
    // Load tables and columns first
    if (forParent == null) {
        parentCache.loadObjects(monitor, owner);
        parentCache.loadChildren(monitor, owner, null);
    }
    Map<PARENT, Map<String, ObjectInfo>> parentObjectMap = new LinkedHashMap<>();
    // Load index columns
    DBPDataSource dataSource = owner.getDataSource();
    assert (dataSource != null);
    monitor.beginTask("Load composite cache", 1);
    try (JDBCSession session = DBUtils.openMetaSession(monitor, owner, "Load composite objects")) {
        JDBCStatement dbStat = prepareObjectsStatement(session, owner, forParent);
        dbStat.setFetchSize(DBConstants.METADATA_FETCH_SIZE);
        try {
            dbStat.executeStatement();
            JDBCResultSet dbResult = dbStat.getResultSet();
            if (dbResult != null)
                try {
                    while (dbResult.next()) {
                        if (monitor.isCanceled()) {
                            return;
                        }
                        String parentName = forParent != null ? forParent.getName() : (parentColumnName instanceof Number ? JDBCUtils.safeGetString(dbResult, ((Number) parentColumnName).intValue()) : JDBCUtils.safeGetString(dbResult, parentColumnName.toString()));
                        String objectName = objectColumnName instanceof Number ? JDBCUtils.safeGetString(dbResult, ((Number) objectColumnName).intValue()) : JDBCUtils.safeGetString(dbResult, objectColumnName.toString());
                        if (CommonUtils.isEmpty(objectName)) {
                            // Use default name
                            objectName = getDefaultObjectName(dbResult, parentName);
                        }
                        if (forParent == null && CommonUtils.isEmpty(parentName)) {
                            // No parent - can't evaluate it
                            log.debug("Empty parent name in " + this);
                            continue;
                        }
                        PARENT parent = forParent;
                        if (parent == null) {
                            parent = parentCache.getObject(monitor, owner, parentName, parentType);
                            if (parent == null) {
                                log.debug("Object '" + objectName + "' owner '" + parentName + "' not found");
                                continue;
                            }
                        }
                        synchronized (objectCache) {
                            if (objectCache.containsKey(parent)) {
                                // Already cached
                                continue;
                            }
                        }
                        // Add to map
                        Map<String, ObjectInfo> objectMap = parentObjectMap.get(parent);
                        if (objectMap == null) {
                            objectMap = new TreeMap<>();
                            parentObjectMap.put(parent, objectMap);
                        }
                        ObjectInfo objectInfo = objectMap.get(objectName);
                        if (objectInfo == null) {
                            OBJECT object = fetchObject(session, owner, parent, objectName, dbResult);
                            if (object == null || !isValidObject(monitor, owner, object)) {
                                // Can't fetch object
                                continue;
                            }
                            objectName = object.getName();
                            objectInfo = new ObjectInfo(object);
                            objectMap.put(objectName, objectInfo);
                        }
                        ROW_REF[] rowRef = fetchObjectRow(session, parent, objectInfo.object, dbResult);
                        if (rowRef == null || rowRef.length == 0) {
                            // At least one of rows is broken.
                            // So entire object is broken, let's just skip it.
                            objectInfo.broken = true;
                            // log.debug("Object '" + objectName + "' metadata corrupted - NULL child returned");
                            continue;
                        }
                        for (ROW_REF row : rowRef) {
                            if (row != null) {
                                objectInfo.rows.add(row);
                            }
                        }
                    }
                } finally {
                    dbResult.close();
                }
        } finally {
            dbStat.close();
        }
    } catch (SQLException ex) {
        if (ex instanceof SQLFeatureNotSupportedException) {
            log.debug("Error reading cache: feature not supported", ex);
        } else {
            throw new DBException(ex, dataSource);
        }
    } finally {
        monitor.done();
    }
    if (monitor.isCanceled()) {
        return;
    }
    // Fill global cache
    synchronized (this) {
        synchronized (objectCache) {
            if (forParent != null || !parentObjectMap.isEmpty()) {
                if (forParent == null) {
                    // Cache global object list
                    List<OBJECT> globalCache = new ArrayList<>();
                    for (Map<String, ObjectInfo> objMap : parentObjectMap.values()) {
                        if (objMap != null) {
                            for (ObjectInfo info : objMap.values()) {
                                if (!info.broken) {
                                    globalCache.add(info.object);
                                }
                            }
                        }
                    }
                    // Save precached objects in global cache
                    for (List<OBJECT> objects : objectCache.values()) {
                        globalCache.addAll(objects);
                    }
                    // Add precached objects to global cache too
                    super.setCache(globalCache);
                    this.invalidateObjects(monitor, owner, new CacheIterator());
                }
            }
            // All objects are read. Now assign them to parents
            for (Map.Entry<PARENT, Map<String, ObjectInfo>> colEntry : parentObjectMap.entrySet()) {
                if (colEntry.getValue() == null || objectCache.containsKey(colEntry.getKey())) {
                    // Do not overwrite this object's cache
                    continue;
                }
                Collection<ObjectInfo> objectInfos = colEntry.getValue().values();
                ArrayList<OBJECT> objects = new ArrayList<>(objectInfos.size());
                for (ObjectInfo objectInfo : objectInfos) {
                    objectInfo.needsCaching = true;
                    objects.add(objectInfo.object);
                }
                objectCache.put(colEntry.getKey(), objects);
            }
            // Now set empty object list for other parents
            if (forParent == null) {
                for (PARENT tmpParent : parentCache.getTypedObjects(monitor, owner, parentType)) {
                    if (!parentObjectMap.containsKey(tmpParent) && !objectCache.containsKey(tmpParent)) {
                        objectCache.put(tmpParent, new ArrayList<OBJECT>());
                    }
                }
            } else if (!parentObjectMap.containsKey(forParent) && !objectCache.containsKey(forParent)) {
                objectCache.put(forParent, new ArrayList<OBJECT>());
            }
        }
        // Cache children lists (we do it in the end because children caching may operate with other model objects)
        for (Map.Entry<PARENT, Map<String, ObjectInfo>> colEntry : parentObjectMap.entrySet()) {
            for (ObjectInfo objectInfo : colEntry.getValue().values()) {
                if (objectInfo.needsCaching) {
                    cacheChildren(monitor, objectInfo.object, objectInfo.rows);
                }
            }
        }
        for (Map.Entry<PARENT, Map<String, ObjectInfo>> colEntry : parentObjectMap.entrySet()) {
            for (ObjectInfo objectInfo : colEntry.getValue().values()) {
                if (objectInfo.needsCaching) {
                    cacheChildren2(monitor, objectInfo.object, objectInfo.rows);
                }
            }
        }
    }
}
Also used : JDBCSession(org.jkiss.dbeaver.model.exec.jdbc.JDBCSession) DBException(org.jkiss.dbeaver.DBException) SQLException(java.sql.SQLException) SQLFeatureNotSupportedException(java.sql.SQLFeatureNotSupportedException) DBPDataSource(org.jkiss.dbeaver.model.DBPDataSource) JDBCStatement(org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement) JDBCResultSet(org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet)

Example 63 with DBPDataSource

use of org.jkiss.dbeaver.model.DBPDataSource in project dbeaver by dbeaver.

the class SQLCompletionProposal method validate.

@Override
public boolean validate(IDocument document, int offset, DocumentEvent event) {
    if (event == null) {
        return false;
    }
    SQLSyntaxManager syntaxManager = getContext().getSyntaxManager();
    DBPDataSource dataSource = getContext().getDataSource();
    final SQLWordPartDetector wordDetector = new SQLWordPartDetector(document, syntaxManager, offset);
    String wordPart = wordDetector.getWordPart();
    int divPos = wordPart.lastIndexOf(syntaxManager.getStructSeparator());
    if (divPos != -1) {
        if (divPos == wordPart.length() - 1) {
            // It is valid only if full word matches (it should be the only proposal)
            if (replacementString.equals(wordPart.substring(0, divPos))) {
                {
                    // Call completion popup again
                    UIUtils.asyncExec(() -> {
                        IEditorPart activeEditor = UIUtils.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
                        if (activeEditor != null) {
                            ITextViewer textViewer = activeEditor.getAdapter(ITextViewer.class);
                            if (textViewer != null) {
                                textViewer.getTextOperationTarget().doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
                            }
                        }
                    });
                }
            }
            return false;
        }
        wordPart = wordPart.substring(divPos + 1);
    }
    String wordLower = wordPart.toLowerCase(Locale.ENGLISH);
    if (!CommonUtils.isEmpty(wordPart)) {
        boolean matchContains = dataSource != null && dataSource.getContainer().getPreferenceStore().getBoolean(SQLPreferenceConstants.PROPOSALS_MATCH_CONTAINS);
        boolean matched;
        if (getObject() == null || !matchContains) {
            // For keywords use strict matching
            matched = (matchContains ? replacementFull.contains(wordLower) : replacementFull.startsWith(wordLower)) && (CommonUtils.isEmpty(event.getText()) || replacementFull.contains(event.getText().toLowerCase(Locale.ENGLISH))) || (this.replacementLast != null && this.replacementLast.startsWith(wordLower));
        } else {
            // For objects use fuzzy matching
            int score = TextUtils.fuzzyScore(replacementFull, wordLower);
            matched = (score > 0 && (CommonUtils.isEmpty(event.getText()) || TextUtils.fuzzyScore(replacementFull, event.getText()) > 0)) || (this.replacementLast != null && TextUtils.fuzzyScore(this.replacementLast, wordLower) > 0);
            if (matched) {
                setProposalScore(score);
            }
        }
        if (matched) {
            setPosition(wordDetector);
            return true;
        }
    } else if (divPos != -1) {
        // Most likely it is a column name after an alias - all columns are valid
        if (getObject() != null) {
            return true;
        }
    }
    return false;
}
Also used : SQLWordPartDetector(org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector) SQLSyntaxManager(org.jkiss.dbeaver.model.sql.SQLSyntaxManager) DBPDataSource(org.jkiss.dbeaver.model.DBPDataSource) StyledString(org.eclipse.jface.viewers.StyledString) IEditorPart(org.eclipse.ui.IEditorPart) Point(org.eclipse.swt.graphics.Point) ITextViewer(org.eclipse.jface.text.ITextViewer)

Example 64 with DBPDataSource

use of org.jkiss.dbeaver.model.DBPDataSource in project dbeaver by dbeaver.

the class ExplainPlanViewer method refresh.

@Override
public void refresh() {
    DBCQueryPlanner planner;
    DBCExecutionContext executionContext = contextProvider.getExecutionContext();
    if (executionContext != null) {
        DBPDataSource dataSource = executionContext.getDataSource();
        planner = GeneralUtils.adapt(dataSource, DBCQueryPlanner.class);
    } else {
        planner = null;
    }
    if (planner == null) {
        DBWorkbench.getPlatformUI().showError("No SQL Plan", "This datasource doesn't support execution plans");
    } else {
        explainService = LoadingJob.createService(new ExplainPlanService(planner, executionContext, lastQuery.getText(), lastQueryId), planPresentationContainer.createVisualizer());
        explainService.schedule();
    }
}
Also used : DBCExecutionContext(org.jkiss.dbeaver.model.exec.DBCExecutionContext) DBPDataSource(org.jkiss.dbeaver.model.DBPDataSource)

Example 65 with DBPDataSource

use of org.jkiss.dbeaver.model.DBPDataSource in project dbeaver by dbeaver.

the class SQLCompletionSorter method compare.

@Override
public int compare(ICompletionProposal p1, ICompletionProposal p2) {
    if (p1 instanceof SQLCompletionProposal && p2 instanceof SQLCompletionProposal) {
        int score1 = ((SQLCompletionProposal) p1).getProposalScore();
        int score2 = ((SQLCompletionProposal) p2).getProposalScore();
        if (score1 > 0 && score2 > 0) {
            if (score1 == score2) {
                DBPDataSource dataSource = ((SQLCompletionProposal) p1).getDataSource();
                if (dataSource != null && dataSource.getContainer().getPreferenceStore().getBoolean(SQLPreferenceConstants.PROPOSAL_SORT_ALPHABETICALLY)) {
                    return p1.getDisplayString().compareToIgnoreCase(p2.getDisplayString());
                }
            }
            return score2 - score1;
        }
    }
    return 0;
}
Also used : DBPDataSource(org.jkiss.dbeaver.model.DBPDataSource)

Aggregations

DBPDataSource (org.jkiss.dbeaver.model.DBPDataSource)154 DBException (org.jkiss.dbeaver.DBException)57 DBSObject (org.jkiss.dbeaver.model.struct.DBSObject)28 DBPDataSourceContainer (org.jkiss.dbeaver.model.DBPDataSourceContainer)19 InvocationTargetException (java.lang.reflect.InvocationTargetException)15 DBCExecutionContext (org.jkiss.dbeaver.model.exec.DBCExecutionContext)15 DBRProgressMonitor (org.jkiss.dbeaver.model.runtime.DBRProgressMonitor)14 ArrayList (java.util.ArrayList)12 GridData (org.eclipse.swt.layout.GridData)12 JDBCStatement (org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement)12 SQLException (java.sql.SQLException)10 IEditorPart (org.eclipse.ui.IEditorPart)10 JDBCResultSet (org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet)10 JDBCSession (org.jkiss.dbeaver.model.exec.jdbc.JDBCSession)10 IWorkbenchPart (org.eclipse.ui.IWorkbenchPart)8 DBCExecutionContextDefaults (org.jkiss.dbeaver.model.exec.DBCExecutionContextDefaults)8 DBNDatabaseNode (org.jkiss.dbeaver.model.navigator.DBNDatabaseNode)8 DBSCatalog (org.jkiss.dbeaver.model.struct.rdb.DBSCatalog)8 DBSSchema (org.jkiss.dbeaver.model.struct.rdb.DBSSchema)8 ISelection (org.eclipse.jface.viewers.ISelection)6