Search in sources :

Example 16 with TablePlaceholderKey

use of com.servoy.j2db.query.TablePlaceholderKey in project servoy-client by Servoy.

the class RowManager method getRowUpdateInfo.

RowUpdateInfo getRowUpdateInfo(Row row, boolean tracking) throws ServoyException {
    try {
        if (row.getRowManager() != this) {
            // $NON-NLS-1$
            throw new IllegalArgumentException("I'm not the row manager from row");
        }
        if (adjustingForChangeByOtherPKHashKey.get() != null && adjustingForChangeByOtherPKHashKey.get().equals(row.getPKHashKey())) {
            row.flagExistInDB();
            // we ignore changes here because stored calc with time element are always changed,resulting in endlessloop between clients
            return null;
        }
        if (row.getLastException() instanceof DataException) {
            // cannot update an row which is not changed (which clears the dataexception)
            return null;
        }
        if (!row.isChanged())
            return null;
        boolean mustRequeryRow = false;
        List<Column> dbPKReturnValues = new ArrayList<Column>();
        SQLSheet.SQLDescription sqlDesc = null;
        int statement_action;
        ISQLUpdate sqlUpdate = null;
        IServer server = fsm.getApplication().getSolution().getServer(sheet.getServerName());
        boolean oracleServer = SQLSheet.isOracleServer(server);
        boolean usesLobs = false;
        Table table = sheet.getTable();
        boolean doesExistInDB = row.existInDB();
        List<String> aggregatesToRemove = new ArrayList<String>(8);
        List<String> changedColumns = null;
        if (doesExistInDB) {
            statement_action = ISQLActionTypes.UPDATE_ACTION;
            sqlDesc = sheet.getSQLDescription(SQLSheet.UPDATE);
            sqlUpdate = (QueryUpdate) AbstractBaseQuery.deepClone(sqlDesc.getSQLQuery());
            List<String> req = sqlDesc.getRequiredDataProviderIDs();
            List<String> old = sqlDesc.getOldRequiredDataProviderIDs();
            Object[] olddata = row.getRawOldColumnData();
            if (// for safety only, nothing changed
            olddata == null) {
                return null;
            }
            Object[] newdata = row.getRawColumnData();
            for (int i = 0; i < olddata.length; i++) {
                String dataProviderID = req.get(i);
                Column c = table.getColumn(dataProviderID);
                ColumnInfo ci = c.getColumnInfo();
                if (ci != null && ci.isDBManaged()) {
                    mustRequeryRow = true;
                } else {
                    Object modificationValue = c.getModificationValue(fsm.getApplication());
                    if (modificationValue != null) {
                        row.setRawValue(dataProviderID, modificationValue);
                    }
                    if (newdata[i] instanceof BlobMarkerValue) {
                        // because that would be a byte[]
                        continue;
                    }
                    if (!Utils.equalObjects(olddata[i], newdata[i])) {
                        if (sheet.isUsedByAggregate(dataProviderID)) {
                            aggregatesToRemove.addAll(sheet.getAggregateName(dataProviderID));
                        }
                        Object robj = c.getAsRightType(newdata[i]);
                        if (robj == null)
                            robj = ValueFactory.createNullValue(c.getType());
                        ((QueryUpdate) sqlUpdate).addValue(c.queryColumn(((QueryUpdate) sqlUpdate).getTable()), robj);
                        if (changedColumns == null) {
                            changedColumns = new ArrayList<String>(olddata.length - i);
                        }
                        changedColumns.add(c.getName());
                        if (oracleServer && !usesLobs) {
                            int type = c.getType();
                            if (type == Types.BLOB && robj instanceof byte[] && ((byte[]) robj).length > 4000) {
                                usesLobs = true;
                            } else if (type == Types.CLOB && robj instanceof String && ((String) robj).length() > 4000) {
                                usesLobs = true;
                            }
                        }
                    }
                }
            }
            if (// nothing changed after all
            changedColumns == null) {
                // clear the old data now else it will be kept and in a changed state.
                row.flagExistInDB();
                return null;
            }
            // add PK
            Object[] pkValues = new Object[old.size()];
            for (int j = 0; j < old.size(); j++) {
                String dataProviderID = old.get(j);
                pkValues[j] = row.getOldRequiredValue(dataProviderID);
            }
            // TODO: check for success
            AbstractBaseQuery.setPlaceholderValue(sqlUpdate, new TablePlaceholderKey(((QueryUpdate) sqlUpdate).getTable(), SQLGenerator.PLACEHOLDER_PRIMARY_KEY), pkValues);
        } else {
            List<Object> argsArray = new ArrayList<Object>();
            statement_action = ISQLActionTypes.INSERT_ACTION;
            sqlDesc = sheet.getSQLDescription(SQLSheet.INSERT);
            sqlUpdate = (ISQLUpdate) AbstractBaseQuery.deepClone(sqlDesc.getSQLQuery());
            List<String> req = sqlDesc.getRequiredDataProviderIDs();
            if (Debug.tracing())
                Debug.trace(sqlUpdate.toString());
            for (int i = 0; i < req.size(); i++) {
                String dataProviderID = req.get(i);
                if (sheet.isUsedByAggregate(dataProviderID)) {
                    aggregatesToRemove.addAll(sheet.getAggregateName(dataProviderID));
                }
                Column c = table.getColumn(dataProviderID);
                QueryColumn queryColumn = c.queryColumn(((QueryInsert) sqlUpdate).getTable());
                ColumnInfo ci = c.getColumnInfo();
                if (c.isDBIdentity()) {
                    dbPKReturnValues.add(c);
                    argsArray.add(row.getDbIdentValue());
                } else if (ci != null && ci.isDBManaged()) {
                    mustRequeryRow = true;
                } else {
                    int columnIndex = getSQLSheet().getColumnIndex(dataProviderID);
                    // HACK: DIRTY way, should use some kind of identifier preferably
                    if (c.getDatabaseDefaultValue() != null && row.getRawValue(columnIndex, false) == null && c.getRowIdentType() == IBaseColumn.NORMAL_COLUMN) {
                        // The database has a default value, and the value is null, and this is an insert...
                        // Remove the column from the query entirely and make sure the default value is requeried from the db.
                        mustRequeryRow = true;
                        ((QueryInsert) sqlUpdate).removeColumn(queryColumn);
                    } else {
                        Object robj = c.getAsRightType(row.getRawValue(columnIndex, false));
                        if (robj == null)
                            robj = ValueFactory.createNullValue(c.getType());
                        argsArray.add(robj);
                        if (oracleServer && !usesLobs) {
                            int type = c.getType();
                            if (type == Types.BLOB && robj instanceof byte[] && ((byte[]) robj).length > 4000) {
                                usesLobs = true;
                            } else if (type == Types.CLOB && robj instanceof String && ((String) robj).length() > 4000) {
                                usesLobs = true;
                            }
                        }
                    }
                }
            }
            AbstractBaseQuery.setPlaceholderValue(sqlUpdate, new TablePlaceholderKey(((QueryInsert) sqlUpdate).getTable(), SQLGenerator.PLACEHOLDER_INSERT_KEY), argsArray.toArray());
        }
        Object[] pk = row.getPK();
        IDataSet pks = new BufferedDataSet();
        pks.addRow(pk);
        String tid = null;
        GlobalTransaction gt = fsm.getGlobalTransaction();
        if (gt != null) {
            tid = gt.getTransactionID(sheet.getServerName());
        }
        QuerySelect requerySelect = null;
        if (mustRequeryRow) {
            requerySelect = (QuerySelect) AbstractBaseQuery.deepClone(sheet.getSQL(SQLSheet.SELECT));
            if (!requerySelect.setPlaceholderValue(new TablePlaceholderKey(requerySelect.getTable(), SQLGenerator.PLACEHOLDER_PRIMARY_KEY), pk)) {
                Debug.error(new RuntimeException(// $NON-NLS-1$
                "Could not set placeholder " + new TablePlaceholderKey(requerySelect.getTable(), SQLGenerator.PLACEHOLDER_PRIMARY_KEY) + " in query " + requerySelect + // $NON-NLS-1$//$NON-NLS-2$
                "-- continuing"));
            }
        }
        SQLStatement statement = new SQLStatement(statement_action, sheet.getServerName(), table.getName(), pks, tid, sqlUpdate, fsm.getTableFilterParams(sheet.getServerName(), sqlUpdate), requerySelect);
        // check that the row is updated (skip check for insert)
        if (doesExistInDB)
            statement.setExpectedUpdateCount(1);
        if (changedColumns != null) {
            statement.setChangedColumns(changedColumns.toArray(new String[changedColumns.size()]));
        }
        statement.setOracleFixTrackingData(usesLobs && !tracking);
        statement.setIdentityColumn(dbPKReturnValues.size() == 0 ? null : dbPKReturnValues.get(0));
        if (tracking || usesLobs) {
            statement.setTrackingData(sheet.getColumnNames(), row.getRawOldColumnData() != null ? new Object[][] { row.getRawOldColumnData() } : null, row.getRawColumnData() != null ? new Object[][] { row.getRawColumnData() } : null, fsm.getApplication().getUserUID(), fsm.getTrackingInfo(), fsm.getApplication().getClientID());
        }
        return new RowUpdateInfo(row, statement, dbPKReturnValues, aggregatesToRemove);
    } catch (RemoteException e) {
        throw new RepositoryException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) SafeArrayList(com.servoy.j2db.util.SafeArrayList) ColumnInfo(com.servoy.j2db.persistence.ColumnInfo) QueryColumn(com.servoy.j2db.query.QueryColumn) IBaseColumn(com.servoy.base.persistence.IBaseColumn) Column(com.servoy.j2db.persistence.Column) QueryInsert(com.servoy.j2db.query.QueryInsert) IServer(com.servoy.j2db.persistence.IServer) QueryTable(com.servoy.j2db.query.QueryTable) Table(com.servoy.j2db.persistence.Table) TablePlaceholderKey(com.servoy.j2db.query.TablePlaceholderKey) RepositoryException(com.servoy.j2db.persistence.RepositoryException) QuerySelect(com.servoy.j2db.query.QuerySelect) ISQLUpdate(com.servoy.j2db.query.ISQLUpdate) BlobMarkerValue(com.servoy.j2db.dataprocessing.ValueFactory.BlobMarkerValue) QueryColumn(com.servoy.j2db.query.QueryColumn) QueryUpdate(com.servoy.j2db.query.QueryUpdate) RemoteException(java.rmi.RemoteException)

Aggregations

TablePlaceholderKey (com.servoy.j2db.query.TablePlaceholderKey)16 QuerySelect (com.servoy.j2db.query.QuerySelect)9 Placeholder (com.servoy.j2db.query.Placeholder)8 ArrayList (java.util.ArrayList)8 RepositoryException (com.servoy.j2db.persistence.RepositoryException)7 SafeArrayList (com.servoy.j2db.util.SafeArrayList)7 Column (com.servoy.j2db.persistence.Column)6 QueryColumn (com.servoy.j2db.query.QueryColumn)6 RemoteException (java.rmi.RemoteException)5 BaseQueryTable (com.servoy.base.query.BaseQueryTable)4 IColumn (com.servoy.j2db.persistence.IColumn)4 IQuerySelectValue (com.servoy.j2db.query.IQuerySelectValue)4 QueryTable (com.servoy.j2db.query.QueryTable)4 BaseQueryColumn (com.servoy.base.query.BaseQueryColumn)3 ColumnInfo (com.servoy.j2db.persistence.ColumnInfo)3 ITable (com.servoy.j2db.persistence.ITable)3 Table (com.servoy.j2db.persistence.Table)3 ISQLTableJoin (com.servoy.j2db.query.ISQLTableJoin)2 QueryColumnValue (com.servoy.j2db.query.QueryColumnValue)2 QueryInsert (com.servoy.j2db.query.QueryInsert)2