Search in sources :

Example 11 with Relation

use of com.servoy.j2db.persistence.Relation in project servoy-client by Servoy.

the class DataProviderEditor method getValue.

public Object getValue() {
    Object retval = null;
    Object[] selections = list.getSelectedValues();
    IDataProvider[] array = new IDataProvider[selections.length];
    for (int i = 0; i < selections.length; i++) {
        Object o = selections[i];
        if (o instanceof IDataProvider) {
            Object item = relationsComboBox.getSelectedItem();
            if (item instanceof Relation && o instanceof IColumn) {
                array[i] = new ColumnWrapper((IColumn) o, new Relation[] { ((Relation) item) });
            } else {
                array[i] = (IDataProvider) o;
            }
        }
    }
    if (selections.length == 1) {
        retval = array[0];
    } else {
        retval = array;
    }
    if (// if used to setDataProviderID
    returnValueAsString) {
        if (array != null && array.length != 0 && array[0] != null) {
            retval = array[0].getDataProviderID();
        } else {
            return null;
        }
    }
    relation = null;
    return retval;
}
Also used : Relation(com.servoy.j2db.persistence.Relation) IColumn(com.servoy.j2db.persistence.IColumn) ColumnWrapper(com.servoy.j2db.persistence.ColumnWrapper) IDataProvider(com.servoy.j2db.persistence.IDataProvider)

Example 12 with Relation

use of com.servoy.j2db.persistence.Relation in project servoy-client by Servoy.

the class DataProviderEditor method fillRelationsComboBox.

protected void fillRelationsComboBox(Relation[] relations) throws Exception {
    boolean relationsAdded = false;
    String item = null;
    ITable table = null;
    if (definedTable == null) {
        FormManager fm = (FormManager) application.getFormManager();
        FormController fc = fm.getCurrentMainShowingFormController();
        if (fc != null) {
            Form form = fc.getForm();
            table = application.getFlattenedSolution().getTable(form.getDataSource());
        }
    } else {
        table = definedTable;
    // definedTable = null;//clear!
    }
    if (relationsComboBox.getItemCount() > 0)
        relationsComboBox.removeAllItems();
    Iterator it = application.getFlattenedSolution().getRelations(table, true, true);
    while (it.hasNext()) {
        Relation rel = (Relation) it.next();
        if (!showSortableOnly || (showSortableOnly && rel.isUsableInSort())) {
            relationsComboBox.addItem(rel);
            relationsAdded = true;
        }
    }
    if (!showRelatedOptionsOnly) {
        // $NON-NLS-1$
        String tname = "";
        if (table != null)
            tname = table.getName();
        item = "DataProviders for " + tname;
        if (relationsComboBox.getModel().getSize() > 0) {
            relationsComboBox.insertItemAt(item, 0);
        } else {
            relationsComboBox.addItem(item);
        }
    }
    if (relations == null) {
        if (item == null) {
            if (relationsComboBox.getModel().getSize() != 0)
                relationsComboBox.setSelectedIndex(0);
        } else {
            relationsComboBox.setSelectedItem(item);
        }
    } else {
        relationsComboBox.setSelectedItem(relations[0]);
    }
    relationsComboBox.setEnabled(relationsAdded && !showRelatedOptionsOnly);
}
Also used : FormController(com.servoy.j2db.FormController) Relation(com.servoy.j2db.persistence.Relation) FormManager(com.servoy.j2db.FormManager) Form(com.servoy.j2db.persistence.Form) Iterator(java.util.Iterator) ITable(com.servoy.j2db.persistence.ITable)

Example 13 with Relation

use of com.servoy.j2db.persistence.Relation in project servoy-client by Servoy.

the class FoundSet method findQueryRelationSequence.

private List<Relation> findQueryRelationSequence(QuerySelect sqlSelect, BaseQueryTable qTable) {
    if (sqlSelect.getTable() == qTable) {
        // column on base table, not related
        return Collections.emptyList();
    }
    // find the join to this table
    for (ISQLJoin join : iterate(sqlSelect.getJoins())) {
        if (join.getName() != null && join instanceof QueryJoin && ((QueryJoin) join).getForeignTable() == qTable) {
            Relation relation = fsm.getRelation(join.getName());
            if (relation != null && relation.getForeignDataSource().equals(qTable.getDataSource())) {
                List<Relation> subRelated = findQueryRelationSequence(sqlSelect, ((QueryJoin) join).getPrimaryTable());
                if (subRelated != null) {
                    // found matching relation sequence
                    List<Relation> relationSequence = new ArrayList<>(subRelated);
                    relationSequence.add(relation);
                    return relationSequence;
                }
            }
        }
    }
    // not found
    return null;
}
Also used : Relation(com.servoy.j2db.persistence.Relation) QueryJoin(com.servoy.j2db.query.QueryJoin) ArrayList(java.util.ArrayList) SafeArrayList(com.servoy.j2db.util.SafeArrayList) ISQLJoin(com.servoy.j2db.query.ISQLJoin)

Example 14 with Relation

use of com.servoy.j2db.persistence.Relation in project servoy-client by Servoy.

the class FoundSetManager method getRelatedFoundSet.

// query for a substate
protected IFoundSetInternal getRelatedFoundSet(IRecordInternal state, SQLSheet childSheet, String relationName, List<SortColumn> defaultSortColumns) throws ServoyException {
    Relation relation = application.getFlattenedSolution().getRelation(relationName);
    if (!Relation.isValid(relation, application.getFlattenedSolution())) {
        return null;
    }
    if (relation.isParentRef()) {
        return state.getParentFoundSet();
    }
    RelatedHashedArgumentsWithState relatedArguments = calculateFKHash(state, relation, false);
    if (relatedArguments == null) {
        return null;
    }
    IFoundSetInternal retval = getCachedRelatedFoundset(relation.getName(), relatedArguments);
    List<RelatedHashedArgumentsWithState> toFetch = null;
    if (retval == null) {
        String lockString = relationName + relatedArguments.hashedArguments.hash;
        ConcurrentMap<String, RelatedFoundSet> rfs;
        synchronized (locks) {
            rfs = getCachedSubStates().get(relationName);
            if (rfs == null) {
                rfs = CacheBuilder.newBuilder().softValues().<String, RelatedFoundSet>build().asMap();
                getCachedSubStates().put(relationName, rfs);
            }
            while (locks.contains(lockString)) {
                try {
                    locks.wait();
                } catch (InterruptedException e) {
                    Debug.error(e);
                }
            }
            retval = rfs.get(relatedArguments.hashedArguments.hash);
            if (retval == null) {
                locks.add(lockString);
                // pre-fetch a number of sibling related found sets
                toFetch = new ArrayList<>();
                // first to fetch is the one currently requested
                toFetch.add(relatedArguments);
                IFoundSetInternal parent = state.getParentFoundSet();
                int currIndex = parent.getRecordIndex(state);
                if (currIndex >= 0 && parent instanceof FoundSet) {
                    int relatedChunkSize = config.chunkSize() / 3;
                    // take a snapshot of cachedRecords
                    Object[] siblingRecords = ((FoundSet) parent).getPksAndRecords().getCachedRecords().toArray();
                    for (int s = currIndex + 1; s < siblingRecords.length && toFetch.size() < relatedChunkSize; s++) {
                        IRecordInternal sibling = (IRecordInternal) siblingRecords[s];
                        if (sibling != null) {
                            RelatedHashedArgumentsWithState extra = calculateFKHash(sibling, relation, true);
                            if (extra != null && !rfs.containsKey(extra.hashedArguments.hash)) /* already cached */
                            {
                                String extraLockString = relationName + extra.hashedArguments.hash;
                                if (!locks.contains(extraLockString)) {
                                    locks.add(extraLockString);
                                    toFetch.add(extra);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (retval == null) {
            RelatedFoundSet[] retvals = null;
            try {
                IRecordInternal[] states = new IRecordInternal[toFetch.size()];
                Object[][] whereArgsList = new Object[toFetch.size()][];
                for (int f = 0; f < toFetch.size(); f++) {
                    RelatedHashedArgumentsWithState relargs = toFetch.get(f);
                    states[f] = relargs.state;
                    whereArgsList[f] = relargs.hashedArguments.whereArgs;
                }
                if (relation.getInitialSort() != null) {
                    defaultSortColumns = getSortColumns(relation.getForeignDataSource(), relation.getInitialSort());
                }
                retvals = (RelatedFoundSet[]) RelatedFoundSet.createRelatedFoundSets(foundsetfactory, this, states, relation, childSheet, whereArgsList, defaultSortColumns);
                // the first query is the one requested now, the rest is pre-fetch
                retval = retvals[0];
            } finally {
                synchronized (locks) {
                    for (int f = 0; f < toFetch.size(); f++) {
                        RelatedHashedArgumentsWithState relargs = toFetch.get(f);
                        if (retvals != null) {
                            rfs.put(relargs.hashedArguments.hash, retvals[f]);
                            if (relargs.hashedArguments.isDBIdentity()) {
                                List<RelatedHashedArguments> storedDBIdentArguments = dbIdentArguments.get(relationName);
                                if (storedDBIdentArguments == null) {
                                    storedDBIdentArguments = Collections.synchronizedList(new ArrayList<>());
                                    dbIdentArguments.put(relationName, storedDBIdentArguments);
                                }
                                storedDBIdentArguments.add(relargs.hashedArguments);
                            }
                        }
                        locks.remove(relationName + relargs.hashedArguments.hash);
                    }
                    locks.notifyAll();
                }
            }
            // inform global foundset event listeners that a new foundset has been created
            globalFoundSetEventListener.foundSetsCreated(retvals);
            // run runnables for firing events after foundsets have been created
            if (fireRunabbles.size() > 0) {
                Runnable[] runnables;
                synchronized (fireRunabbles) {
                    runnables = new ArrayList<Runnable>(fireRunabbles).toArray(new Runnable[fireRunabbles.size()]);
                    fireRunabbles.clear();
                }
                for (Runnable runnable : runnables) {
                    runnable.run();
                }
            }
        }
    }
    return retval;
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Relation(com.servoy.j2db.persistence.Relation) ServoyJSONObject(com.servoy.j2db.util.ServoyJSONObject)

Example 15 with Relation

use of com.servoy.j2db.persistence.Relation in project servoy-client by Servoy.

the class SQLGenerator method addSorts.

public void addSorts(QuerySelect sqlSelect, BaseQueryTable selectTable, IGlobalValueEntry provider, ITable table, List<SortColumn> orderByFields, boolean includeRelated, boolean permanentJoins) throws RepositoryException {
    List<Column> unusedRowidentColumns = new ArrayList<Column>(table.getRowIdentColumns());
    for (int i = 0; orderByFields != null && i < orderByFields.size(); i++) {
        SortColumn sc = orderByFields.get(i);
        // can be column or aggregate
        IColumn column = sc.getColumn();
        if (column.getDataProviderType() == MEDIA && (column.getFlags() & (IDENT_COLUMNS | UUID_COLUMN)) == 0) {
            // skip cannot sort blob columns
            continue;
        }
        SortOptions sortOptions = application.getFoundSetManager().getSortOptions(sc.getColumn());
        Relation[] relations = sc.getRelations();
        // compare on server objects, relation.foreignServerName may be different in case of duplicates
        boolean doRelatedJoin = (includeRelated && relations != null);
        if (doRelatedJoin) {
            FlattenedSolution fs = application.getFlattenedSolution();
            for (Relation relation : relations) {
                if (relation.isMultiServer() && !fs.getTable(relation.getForeignDataSource()).getServerName().equals(table.getServerName())) {
                    doRelatedJoin = false;
                    break;
                }
            }
        }
        if (doRelatedJoin) // related sort, cannot join across multiple servers
        {
            BaseQueryTable primaryQtable = selectTable;
            BaseQueryTable foreignQtable = null;
            for (Relation relation : relations) {
                // join must be re-created as it is possible to have globals involved;
                // first remove, then create it
                ISQLTableJoin join = (ISQLTableJoin) sqlSelect.getJoin(primaryQtable, relation.getName());
                if (join != null)
                    sqlSelect.getJoins().remove(join);
                if (join == null) {
                    ITable foreignTable = application.getFlattenedSolution().getTable(relation.getForeignDataSource());
                    foreignQtable = new QueryTable(foreignTable.getSQLName(), foreignTable.getDataSource(), foreignTable.getCatalog(), foreignTable.getSchema());
                } else {
                    foreignQtable = join.getForeignTable();
                }
                sqlSelect.addJoin(createJoin(application.getFlattenedSolution(), relation, primaryQtable, foreignQtable, permanentJoins, provider));
                primaryQtable = foreignQtable;
            }
            IQuerySelectValue queryColumn;
            if (column instanceof Column) {
                queryColumn = ((Column) column).queryColumn(foreignQtable);
                unusedRowidentColumns.remove(column);
            } else if (column instanceof AggregateVariable) {
                AggregateVariable aggregate = (AggregateVariable) column;
                queryColumn = new QueryAggregate(aggregate.getType(), new QueryColumn(foreignQtable, -1, aggregate.getColumnNameToAggregate(), aggregate.getDataProviderType(), aggregate.getLength(), 0, null, aggregate.getFlags()), aggregate.getName());
                // there has to be a group-by clause for all selected fields
                List<IQuerySelectValue> columns = sqlSelect.getColumns();
                for (IQuerySelectValue selectVal : columns) {
                    List<IQuerySelectValue> groupBy = sqlSelect.getGroupBy();
                    if (selectVal instanceof QueryColumn && (groupBy == null || !groupBy.contains(selectVal))) {
                        sqlSelect.addGroupBy(selectVal);
                    }
                }
                // if the aggregate has not been selected yet, add it and skip it in the result
                QueryAggregate skippedAggregate = new QueryAggregate(aggregate.getType(), QueryAggregate.ALL, new QueryColumn(foreignQtable, -1, aggregate.getColumnNameToAggregate(), aggregate.getDataProviderType(), aggregate.getLength(), 0, null, aggregate.getFlags()), aggregate.getName(), null, true);
                if (!columns.contains(skippedAggregate)) {
                    sqlSelect.addColumn(skippedAggregate);
                }
            } else {
                // $NON-NLS-1$
                Debug.log("Skipping sort on unexpected related column type " + column.getClass());
                continue;
            }
            sqlSelect.addSort(new QuerySort(queryColumn, sc.getSortOrder() == ASCENDING, sortOptions));
        } else {
            // make sure an invalid sort is not possible
            if (column instanceof Column && column.getTable().getName().equals(table.getName())) {
                sqlSelect.addSort(new QuerySort(((Column) column).queryColumn(selectTable), sc.getSortOrder() == ASCENDING, sortOptions));
                unusedRowidentColumns.remove(column);
            } else {
                // $NON-NLS-1$ //$NON-NLS-2$
                Debug.log("Skipping sort on unrelated column " + column.getName() + '.' + column.getTable().getName() + " for table " + table.getName());
            }
        }
    }
    // Make sure pk is part of the sort, in case of non-unique sort columns, the sorted result may not be the same in each fetch
    if (enforcePkInSort) {
        for (Column column : unusedRowidentColumns) {
            SortOptions sortOptions = application.getFoundSetManager().getSortOptions(column);
            sqlSelect.addSort(new QuerySort(column.queryColumn(selectTable), true, sortOptions));
        }
    }
}
Also used : QueryAggregate(com.servoy.j2db.query.QueryAggregate) ArrayList(java.util.ArrayList) SafeArrayList(com.servoy.j2db.util.SafeArrayList) FlattenedSolution(com.servoy.j2db.FlattenedSolution) AggregateVariable(com.servoy.j2db.persistence.AggregateVariable) BaseQueryTable(com.servoy.base.query.BaseQueryTable) QueryTable(com.servoy.j2db.query.QueryTable) Relation(com.servoy.j2db.persistence.Relation) IRelation(com.servoy.j2db.persistence.IRelation) BaseQueryTable(com.servoy.base.query.BaseQueryTable) QueryColumn(com.servoy.j2db.query.QueryColumn) BaseQueryColumn(com.servoy.base.query.BaseQueryColumn) IColumn(com.servoy.j2db.persistence.IColumn) Column(com.servoy.j2db.persistence.Column) IColumn(com.servoy.j2db.persistence.IColumn) ISQLTableJoin(com.servoy.j2db.query.ISQLTableJoin) QueryColumn(com.servoy.j2db.query.QueryColumn) BaseQueryColumn(com.servoy.base.query.BaseQueryColumn) QuerySort(com.servoy.j2db.query.QuerySort) IQuerySort(com.servoy.j2db.query.IQuerySort) ITable(com.servoy.j2db.persistence.ITable) List(java.util.List) ArrayList(java.util.ArrayList) SafeArrayList(com.servoy.j2db.util.SafeArrayList) Collectors.toList(java.util.stream.Collectors.toList) SortOptions(com.servoy.j2db.query.SortOptions) IQuerySelectValue(com.servoy.j2db.query.IQuerySelectValue)

Aggregations

Relation (com.servoy.j2db.persistence.Relation)53 ServoyException (com.servoy.j2db.util.ServoyException)16 ArrayList (java.util.ArrayList)16 FlattenedSolution (com.servoy.j2db.FlattenedSolution)15 RepositoryException (com.servoy.j2db.persistence.RepositoryException)15 Column (com.servoy.j2db.persistence.Column)11 ITable (com.servoy.j2db.persistence.ITable)11 RemoteException (java.rmi.RemoteException)10 BaseQueryTable (com.servoy.base.query.BaseQueryTable)9 IDataProvider (com.servoy.j2db.persistence.IDataProvider)8 QuerySelect (com.servoy.j2db.query.QuerySelect)8 QueryTable (com.servoy.j2db.query.QueryTable)8 IColumn (com.servoy.j2db.persistence.IColumn)7 Placeholder (com.servoy.j2db.query.Placeholder)7 ApplicationException (com.servoy.j2db.ApplicationException)6 Table (com.servoy.j2db.persistence.Table)6 QueryColumn (com.servoy.j2db.query.QueryColumn)6 IQuerySelectValue (com.servoy.j2db.query.IQuerySelectValue)5 ISQLTableJoin (com.servoy.j2db.query.ISQLTableJoin)5 SafeArrayList (com.servoy.j2db.util.SafeArrayList)5