use of com.servoy.j2db.query.Placeholder in project servoy-client by Servoy.
the class SQLGenerator method getEmptyDataSetForDummyQuery.
/**
* check if the query is will never return any rows, in that case just return an empty dataset.
*/
public static IDataSet getEmptyDataSetForDummyQuery(ISQLSelect sqlSelect) {
if (sqlSelect instanceof QuerySelect && ((QuerySelect) sqlSelect).getCondition(CONDITION_SEARCH) != null) {
// all named conditions in QuerySelecta are AND-ed, if one always results to false, skip the query
for (IBaseSQLCondition condition : ((QuerySelect) sqlSelect).getCondition(CONDITION_SEARCH).getConditions()) {
boolean skipQuery = false;
if (condition instanceof SetCondition && ((SetCondition) condition).isAndCondition()) {
// check for EQUALS_OPERATOR
int ncols = ((SetCondition) condition).getKeys().length;
int[] operators = ((SetCondition) condition).getOperators();
boolean eqop = true;
for (int i = 0; i < ncols; i++) {
if (operators[i] != IBaseSQLCondition.EQUALS_OPERATOR) {
eqop = false;
}
}
if (eqop) {
Object value = ((SetCondition) condition).getValues();
if (value instanceof Placeholder) {
Object phval = ((Placeholder) value).getValue();
// cleared foundset
skipQuery = phval instanceof DynamicPkValuesArray && ((DynamicPkValuesArray) phval).getPKs().getRowCount() == 0;
} else if (value instanceof Object[][]) {
skipQuery = ((Object[][]) value).length == 0 || ((Object[][]) value)[0].length == 0;
}
}
}
if (skipQuery) {
// no need to query, dummy condition (where 1=2) here
List<IQuerySelectValue> columns = ((QuerySelect) sqlSelect).getColumns();
String[] columnNames = new String[columns.size()];
ColumnType[] columnTypes = new ColumnType[columns.size()];
for (int i = 0; i < columns.size(); i++) {
IQuerySelectValue col = columns.get(i);
columnNames[i] = col.getAliasOrName();
BaseColumnType columnType = col.getColumnType();
columnTypes[i] = columnType == null ? ColumnType.getInstance(Types.OTHER, 0, 0) : ColumnType.getInstance(columnType.getSqlType(), columnType.getLength(), columnType.getScale());
}
return BufferedDataSetInternal.createBufferedDataSet(columnNames, columnTypes, new SafeArrayList<Object[]>(0), false);
}
}
}
// query needs to be run
return null;
}
use of com.servoy.j2db.query.Placeholder in project servoy-client by Servoy.
the class SQLSheet method getNewRowData.
/**
* Returns raw (not using column converters) row data for a new record
* @param app
* @param fs
* @return
*/
Object[] getNewRowData(IServiceProvider app, FoundSet fs) {
Object[][] creationArgs = null;
// INSERT
SQLDescription desc = getSQLDescription(SELECT);
// RequiredDataProviderIDs();
List<?> list = desc.getDataProviderIDsDilivery();
Column[] fcols = null;
Relation relation = null;
String relationName = fs.getRelationName();
if (relationName != null) {
try {
relation = app.getFlattenedSolution().getRelation(relationName);
if (relation != null) {
fcols = relation.getForeignColumns(app.getFlattenedSolution());
QuerySelect creationSQLString = fs.getCreationSqlSelect();
Placeholder ph = creationSQLString.getPlaceholder(SQLGenerator.createRelationKeyPlaceholderKey(creationSQLString.getTable(), relation.getName()));
if (ph != null && ph.isSet()) {
// a matrix as wide as the relation keys and 1 deep
creationArgs = (Object[][]) ph.getValue();
}
}
} catch (RepositoryException e) {
Debug.error(e);
}
}
Object[] array = new Object[list.size()];
for (int i = 0; i < list.size(); i++) {
try {
boolean filled = false;
Column c = table.getColumn((String) list.get(i));
if (c.isDBIdentity()) {
array[i] = ValueFactory.createDbIdentValue();
filled = true;
} else {
ColumnInfo ci = c.getColumnInfo();
if (c.getRowIdentType() != IBaseColumn.NORMAL_COLUMN && ci != null && ci.hasSequence()) {
// this is here for safety, it can happen that a form has (unwanted) still a related foundset which is created by relation based on primary key
array[i] = c.getNewRecordValue(app);
filled = true;
} else {
if (// created via relation, so fill the foreign key with foreign value
creationArgs != null && creationArgs.length != 0 && fcols != null) {
for (int j = 0; j < fcols.length; j++) {
if (c.equals(fcols[j]) && ((relation.getOperators()[j] & IBaseSQLCondition.OPERATOR_MASK) == IBaseSQLCondition.EQUALS_OPERATOR)) {
// creationArgs is a matrix as wide as the relation keys and 1 deep
array[i] = creationArgs[j][0];
filled = true;
break;
}
}
}
}
}
if (!filled) {
array[i] = c.getNewRecordValue(app);
}
} catch (Exception ex) {
Debug.error(ex);
}
}
return array;
}
use of com.servoy.j2db.query.Placeholder in project servoy-client by Servoy.
the class RelatedFoundSet method getWhereArgs.
public Object[] getWhereArgs(boolean onlyEqualsConditions) {
Placeholder ph = creationSqlSelect.getPlaceholder(SQLGenerator.createRelationKeyPlaceholderKey(creationSqlSelect.getTable(), getRelationName()));
if (ph == null || !ph.isSet()) {
if (!findMode) {
Debug.error(// $NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
"RelatedFoundset, creation args not found\nplaceholder=" + ph + "\nrelation=" + getRelationName() + "\ncreationSqlSelect=" + creationSqlSelect, new RuntimeException("RelatedFoundset, creation args not found!!"));
}
// how can this happen (other then in find mode) ??
return null;
}
Relation relation = fsm.getApplication().getFlattenedSolution().getRelation(relationName);
if (relation == null) {
// $NON-NLS-1$
throw new IllegalStateException("Relation not found for related foundset: " + relationName);
}
Object[][] foreignData = (Object[][]) ph.getValue();
Column[] columns;
try {
columns = relation.getForeignColumns(fsm.getApplication().getFlattenedSolution());
} catch (RepositoryException e) {
Debug.error(e);
// $NON-NLS-1$
throw new IllegalStateException("Relation columns not found for related foundset: " + relationName);
}
if (columns.length != foreignData.length) {
// $NON-NLS-1$
throw new IllegalStateException("Relation where-args inconsistent with columns for relation" + relationName);
}
IntStream columnIndexesStream;
if (onlyEqualsConditions) {
int[] columnIndexes = getIndexesEqualsEntries();
if (columnIndexes.length == 0) {
return null;
}
columnIndexesStream = IntStream.of(columnIndexes);
} else {
columnIndexesStream = IntStream.range(0, columns.length);
}
return columnIndexesStream.mapToObj(i -> {
// Use converted value for hash
int colindex = getSQLSheet().getColumnIndex(columns[i].getDataProviderID());
return getSQLSheet().convertValueToObject(foreignData[i][0], colindex, fsm.getColumnConverterManager());
}).toArray();
}
use of com.servoy.j2db.query.Placeholder in project servoy-client by Servoy.
the class SQLGenerator method createRelatedCondition.
public static ISQLCondition createRelatedCondition(IServiceProvider app, Relation relation, QueryTable foreignTable) throws RepositoryException {
IDataProvider[] primary = relation.getPrimaryDataProviders(app.getFlattenedSolution());
Column[] foreign = relation.getForeignColumns(app.getFlattenedSolution());
int[] operators = relation.getOperators();
IQuerySelectValue[] keys = new IQuerySelectValue[primary.length];
int[] swapped = new int[primary.length];
for (int x = 0; x < primary.length; x++) {
// need all keys as columns on the left side......
int operator = RelationItem.swapOperator(operators[x]);
if (operator == -1) {
throw new RepositoryException("Cannot swap relation operator for relation " + relation.getName());
}
// column = ? construct
IQuerySelectValue key = foreign[x].queryColumn(foreignTable);
// When we have a text and non-text column we can cast the non-text column to string
int primaryType = primary[x].getDataProviderType();
int foreignType = mapToDefaultType(key.getColumn().getColumnType());
if (!"uuid".equalsIgnoreCase(key.getColumn().getNativeTypename()) && foreignType == IColumnTypes.TEXT && primaryType != IColumnTypes.TEXT && primaryType != 0) {
// key is text, value is non-text, cast the value to text when we supply it
operator |= IBaseSQLCondition.CAST_TO_MODIFIER;
} else if (primaryType == IColumnTypes.TEXT && foreignType != IColumnTypes.TEXT) {
// value is text, key is non-text, cast the key to text
key = new QueryFunction(cast, new IQuerySelectValue[] { key, new QueryColumnValue(IQueryConstants.TYPE_STRING, null, true) }, null);
}
keys[x] = key;
swapped[x] = operator;
}
return new SetCondition(swapped, keys, new Placeholder(createRelationKeyPlaceholderKey(foreignTable, relation.getName())), true);
}
use of com.servoy.j2db.query.Placeholder in project servoy-client by Servoy.
the class SQLGenerator method createJoin.
/**
* Join clause for this relation.
*/
public static ISQLTableJoin createJoin(IDataProviderHandler flattenedSolution, IRelation relation, BaseQueryTable primaryTable, BaseQueryTable foreignTable, boolean permanentJoin, final IGlobalValueEntry provider) throws RepositoryException {
if (relation instanceof AbstractBase) {
ISQLTableJoin queryJoin = ((AbstractBase) relation).getRuntimeProperty(Relation.RELATION_JOIN);
if (queryJoin != null) {
// a query join was defined for this relation, just relink the tables for the first and last in the joins
queryJoin = deepClone(queryJoin);
queryJoin = AbstractBaseQuery.relinkTable(queryJoin.getPrimaryTable(), primaryTable, queryJoin);
queryJoin = AbstractBaseQuery.relinkTable(queryJoin.getForeignTable(), foreignTable, queryJoin);
// update the placeholders for globals
queryJoin.acceptVisitor(new IVisitor() {
public Object visit(Object o) {
if (o instanceof Placeholder && ((Placeholder) o).getKey() instanceof ObjectPlaceholderKey) {
Object value = provider.getDataProviderValue(((ObjectPlaceholderKey<int[]>) ((Placeholder) o).getKey()).getName());
int[] args = ((ObjectPlaceholderKey<int[]>) ((Placeholder) o).getKey()).getObject();
int dataProviderType = args[0];
int flags = args[1];
if (value == null) {
return ValueFactory.createNullValue(dataProviderType);
}
return Column.getAsRightType(dataProviderType, flags, value, Integer.MAX_VALUE, false, false);
}
return o;
}
});
return queryJoin;
}
}
// build a join from the relation items
IDataProvider[] primary = relation.getPrimaryDataProviders(flattenedSolution);
Column[] foreign = relation.getForeignColumns(flattenedSolution);
int[] operators = relation.getOperators();
AndCondition joinCondition = new AndCondition();
for (int x = 0; x < primary.length; x++) {
Column primaryColumn = null;
// check if stored script calc or table column
if (primary[x] instanceof ScriptCalculation) {
ScriptCalculation sc = ((ScriptCalculation) primary[x]);
// null when not stored
primaryColumn = sc.getTable().getColumn(sc.getName());
} else if (primary[x] instanceof Column) {
primaryColumn = (Column) primary[x];
}
QueryColumn foreignColumn = foreign[x].queryColumn(foreignTable);
Object value;
if (primaryColumn == null) {
if (primary[x] instanceof LiteralDataprovider) {
value = ((LiteralDataprovider) primary[x]).getValue();
value = foreign[x].getAsRightType(value);
} else {
value = provider.getDataProviderValue(primary[x].getDataProviderID());
if (value == null) {
value = ValueFactory.createNullValue(primary[x].getDataProviderType());
} else if (value instanceof Placeholder) {
if (((Placeholder) value).getKey() instanceof ObjectPlaceholderKey<?>) {
((ObjectPlaceholderKey) ((Placeholder) value).getKey()).setObject(new int[] { primary[x].getDataProviderType(), primary[x].getFlags() });
}
} else {
value = Column.getAsRightType(primary[x].getDataProviderType(), primary[x].getFlags(), value, Integer.MAX_VALUE, false, false);
}
}
} else // table type, can be stored calc
{
value = primaryColumn.queryColumn(primaryTable);
}
// all operators are swappable because only relation operators in RelationItem.RELATION_OPERATORS can be defined.
// NOTE: elements in joinCondition MUST be CompareConditions (expected in QueryGenerator and SQLGenerator.createConditionFromFindState)
joinCondition.addCondition(new CompareCondition(RelationItem.swapOperator(operators[x]), foreignColumn, value));
}
if (joinCondition.getConditions().size() == 0) {
// $NON-NLS-1$
throw new RepositoryException("Missing join condition in relation " + relation.getName());
}
return new QueryJoin(relation.getName(), primaryTable, foreignTable, joinCondition, relation.getJoinType(), permanentJoin);
}
Aggregations