org.eclipse.persistence.queries.SQLCall Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// arnaud nauwynck, tware - Bug 274975 - ensure custom sql calls are only translated once
package org.eclipse.persistence.queries;
import java.util.List;
import java.io.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
/**
* Purpose: Used as an abstraction of an SQL call.
* A call is an SQL string with parameters.
*/
public class SQLCall extends DatabaseCall implements QueryStringCall {
protected boolean hasCustomSQLArguments;
transient protected boolean isTranslatedCustomQuery;
/**
* PUBLIC:
* Create a new SQL call.
*/
public SQLCall() {
super();
this.hasCustomSQLArguments = false;
this.isTranslatedCustomQuery = false;
}
/**
* PUBLIC:
* Create a new SQL call.
* Warning: Allowing an unverified SQL string to be passed into this
* method makes your application vulnerable to SQL injection attacks.
*/
public SQLCall(String sqlString) {
this();
setSQLString(sqlString);
}
/**
* INTERNAL:
* Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
*/
protected void afterTranslateCustomQuery(List updatedParameters, List updatedParameterTypes) {
int size = getParameters().size();
for (int i = 0; i < size; i++) {
ParameterType parameterType = this.parameterTypes.get(i);
Object parameter = this.parameters.get(i);
if ((parameterType == ParameterType.MODIFY) || (parameterType == ParameterType.OUT) || (parameterType == ParameterType.OUT_CURSOR) || ((parameterType == ParameterType.IN) && parameter instanceof DatabaseField)) {
DatabaseField field = afterTranslateCustomQueryUpdateParameter((DatabaseField)parameter, i, parameterType, updatedParameters, updatedParameterTypes);
if (field!=null){
this.parameters.set(i, field);
}
} else if (parameterType == ParameterType.INOUT) {
DatabaseField outField = afterTranslateCustomQueryUpdateParameter((DatabaseField)((Object[])parameter)[1], i, parameterType, updatedParameters, updatedParameterTypes);
if (outField != null) {
if (((Object[])parameter)[0] instanceof DatabaseField){
if ( ((Object[])parameter)[0] != ((Object[])parameter)[1] ) {
DatabaseField inField = outField.clone();
inField.setName( ((DatabaseField)((Object[])parameter)[0]).getName());
((Object[])parameter)[0] = inField;
} else {
((Object[])parameter)[0] = outField;
}
}
((Object[])parameter)[1] = outField;
}
}
}
}
/**
* INTERNAL:
* Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
* This will return the null if the user did not add the field/type using the setCustomSQLArgumentType method
*/
protected DatabaseField afterTranslateCustomQueryUpdateParameter(DatabaseField field, int index, ParameterType parameterType, List updatedParameters, List updatedParameterTypes) {
int size = updatedParameters.size();
for (int j = 0; j < size; j++) {
DatabaseField updateField = (DatabaseField)updatedParameters.get(j);
if (field.equals(updateField)) {
ParameterType updateParameterType = updatedParameterTypes.get(j);
if (updateParameterType == null) {
return updateField;
} else if (updateParameterType == ParameterType.OUT_CURSOR) {
if (parameterType == ParameterType.OUT) {
this.parameterTypes.set(index, ParameterType.OUT_CURSOR);
return updateField;
} else {
throw ValidationException.cannotSetCursorForParameterTypeOtherThanOut(field.getName(), toString());
}
}
break;
}
}
return null;
}
/**
* INTERNAL:
* Used to avoid misinterpreting the # in custom SQL.
*/
public boolean hasCustomSQLArguments() {
return hasCustomSQLArguments;
}
@Override
public boolean isSQLCall() {
return true;
}
@Override
public boolean isQueryStringCall() {
return true;
}
/**
* INTERNAL:
* Called by prepare method only.
*/
@Override
protected void prepareInternal(AbstractSession session) {
if (hasCustomSQLArguments()) {
// hold results of setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods
List