@Override public void printSQLSelectStatement( DatabaseCall call, ExpressionSQLPrinter printer, SQLSelectStatement statement) { int max = 0; int firstRow = 0; ReadQuery query = statement.getQuery(); if (query != null) { max = query.getMaxRows(); firstRow = query.getFirstResult(); } if (max <= 0 && firstRow <= 0) { // neither max nor firstRow is set super.printSQLSelectStatement(call, printer, statement); return; } if (max <= 0) { // if max row is not set use MAX_VALUE instead // this is done, because NewDB does not allow // OFFSET without LIMIT, and scrollable cursor is not supported // in order to support firstRows without MaxRows also MaxRow has to be set // this limits also the size of the result set in this case to Integer.MAX_VALUE rows query.setMaxRows(Integer.MAX_VALUE); } statement.setUseUniqueFieldAliases(true); call.setFields(statement.printSQL(printer)); printer.printString(" LIMIT "); printer.printParameter(DatabaseCall.MAXROW_FIELD); printer.printString(" OFFSET "); printer.printParameter(DatabaseCall.FIRSTRESULT_FIELD); call.setIgnoreFirstRowSetting(true); call.setIgnoreMaxResultsSetting(true); }
/** * INTERNAL: Execute the query building the objects directly from the database result-set. * * @exception DatabaseException - an error has occurred on the database * @return object - the first object found or null if none. */ protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException { UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) getSession(); DatabaseAccessor accessor = (DatabaseAccessor) unitOfWork.getAccessor(); DatabasePlatform platform = accessor.getPlatform(); DatabaseCall call = (DatabaseCall) getCall().clone(); call.setQuery(this); call.translate(this.translationRow, null, unitOfWork); Statement statement = null; ResultSet resultSet = null; boolean exceptionOccured = false; try { accessor.incrementCallCount(unitOfWork); statement = call.prepareStatement(accessor, this.translationRow, unitOfWork); resultSet = accessor.executeSelect(call, statement, unitOfWork); ResultSetMetaData metaData = resultSet.getMetaData(); Vector results = new Vector(); ObjectBuilder builder = this.descriptor.getObjectBuilder(); while (resultSet.next()) { results.add( builder.buildWorkingCopyCloneFromResultSet( this, this.joinedAttributeManager, resultSet, unitOfWork, accessor, metaData, platform)); } return results; } catch (SQLException exception) { exceptionOccured = true; DatabaseException commException = accessor.processExceptionForCommError(session, exception, call); if (commException != null) throw commException; throw DatabaseException.sqlException(exception, call, accessor, unitOfWork, false); } finally { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { accessor.releaseStatement(statement, call.getSQLString(), call, unitOfWork); } } catch (SQLException exception) { if (!exceptionOccured) { // in the case of an external connection pool the connection may be null after the // statement release // if it is null we will be unable to check the connection for a comm error and // therefore must return as if it was not a comm error. DatabaseException commException = accessor.processExceptionForCommError(session, exception, call); if (commException != null) throw commException; throw DatabaseException.sqlException(exception, call, accessor, session, false); } } } }
/** * INTERNAL: Used by SQLCall.translate(..) The binding *must* be performed (NCHAR, NSTRING, * NCLOB). In these special cases the method returns a wrapper object which knows whether it * should be bound or appended and knows how to do that. */ public Object getCustomModifyValueForCall( Call call, Object value, DatabaseField field, boolean shouldBind) { Class type = field.getType(); if ((type != null) && isOracle9Specific(type)) { if (value == null) { return null; } if (NCHAR.equals(type) || NSTRING.equals(type)) { return new NTypeBindCallCustomParameter(value); } else if (NCLOB.equals(type)) { value = convertToDatabaseType(value); if (shouldUseLocatorForLOBWrite()) { if (lobValueExceedsLimit(value)) { ((DatabaseCall) call).addContext(field, value); value = new String(" "); } } return new NTypeBindCallCustomParameter(value); } else if (XMLTYPE.equals(type)) { return getXMLTypeFactory().createXMLTypeBindCallCustomParameter(value); } } return super.getCustomModifyValueForCall(call, value, field, shouldBind); }
/** INTERNAL: */ public void validationAfterDescriptorInitialization(AbstractSession session) { Hashtable mapped = new Hashtable(); for (int operation = INSERT; operation <= UPDATE; operation++) { if ((main[operation][MAPPED] != null) && !main[operation][MAPPED].isEmpty()) { Iterator it = main[operation][MAPPED].iterator(); while (it.hasNext()) { DatabaseField field = (DatabaseField) it.next(); mapped.put(field, field); } } } if (!mapped.isEmpty()) { for (Enumeration fields = getDescriptor().getFields().elements(); fields.hasMoreElements(); ) { DatabaseField fieldInDescriptor = (DatabaseField) fields.nextElement(); DatabaseField fieldInMain = (DatabaseField) mapped.get(fieldInDescriptor); if (fieldInMain != null) { if (fieldInMain.getType() == null) { if (getDescriptor().isReturnTypeRequiredForReturningPolicy()) { session .getIntegrityChecker() .handleError( DescriptorException.returningPolicyMappedFieldTypeNotSet( fieldInMain.getName(), getDescriptor())); } } else if (isThereATypeConflict(fieldInMain, fieldInDescriptor)) { session .getIntegrityChecker() .handleError( DescriptorException.returningPolicyAndDescriptorFieldTypeConflict( fieldInMain.getName(), fieldInMain.getType().getName(), fieldInDescriptor.getType().getName(), getDescriptor())); } } } } if (!(session.getDatasourcePlatform() instanceof DatabasePlatform)) { // don't attempt further diagnostics on non-relational platforms return; } WriteObjectQuery[] query = { getDescriptor().getQueryManager().getInsertQuery(), getDescriptor().getQueryManager().getUpdateQuery() }; String[] queryTypeName = {"InsertObjectQuery", "UpdateObjectQuery"}; for (int operation = INSERT; operation <= UPDATE; operation++) { if ((main[operation][ALL] != null) && !main[operation][ALL].isEmpty()) { // this operation requires some fields to be returned if ((query[operation] == null) || (query[operation].getDatasourceCall() == null)) { if (!session.getPlatform().canBuildCallWithReturning()) { session .getIntegrityChecker() .handleError( DescriptorException.noCustomQueryForReturningPolicy( queryTypeName[operation], Helper.getShortClassName(session.getPlatform()), getDescriptor())); } } else if (query[operation].getDatasourceCall() instanceof StoredProcedureCall) { // SQLCall with custom SQL calculates its outputRowFields later (in prepare() method) - // that's why SQLCall can't be verified here. DatabaseCall customCall = (DatabaseCall) query[operation].getDatasourceCall(); Enumeration outputRowFields = customCall.getOutputRowFields().elements(); Collection notFoundInOutputRow = createCollection(); notFoundInOutputRow.addAll(main[operation][ALL]); while (outputRowFields.hasMoreElements()) { notFoundInOutputRow.remove(outputRowFields.nextElement()); } if (!notFoundInOutputRow.isEmpty()) { Iterator it = notFoundInOutputRow.iterator(); while (it.hasNext()) { DatabaseField field = (DatabaseField) it.next(); session .getIntegrityChecker() .handleError( DescriptorException.customQueryAndReturningPolicyFieldConflict( field.getName(), queryTypeName[operation], getDescriptor())); } } } } } }