org.eclipse.persistence.tools.schemaframework.StoredProcedureGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 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
package org.eclipse.persistence.tools.schemaframework;
import java.io.*;
import java.util.*;
import java.sql.Time;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
/**
* Purpose: To generate StoredProcedures from EclipseLink Projects
* Description: This Class was designed to read in a project and produce StoredProcedures.
* It then modifies the descriptors files of the project to use these StoredProcedures.
* NOTE: reads are not supported in Oracle.
*
* Responsibilities:
* -
*
* @since TopLink 2.1
* @author Gordon Yorke
*/
public class StoredProcedureGenerator {
public SchemaManager schemaManager;
/** This hashtable is used to store the storedProcedure referenced by the class name. */
private Hashtable storedProcedures;
/** This hashtable is used to store the storedProcedure referenced by the mapping name. */
private Hashtable mappingStoredProcedures;
private Hashtable intToTypeConverterHash;
private Writer writer;
private String prefix;
private static final String DEFAULT_PREFIX = "";
private Hashtable sequenceProcedures;
private static final int MAX_NAME_SIZE = 30;
public StoredProcedureGenerator(SchemaManager schemaMngr) {
super();
this.schemaManager = schemaMngr;
this.sequenceProcedures = new Hashtable();
this.storedProcedures = new Hashtable();
this.mappingStoredProcedures = new Hashtable();
this.buildIntToTypeConverterHash();
this.prefix = DEFAULT_PREFIX;
this.verify();
}
/**
* INTERNAL: Build all conversions based on JDBC return values.
*/
protected void buildIntToTypeConverterHash() {
this.intToTypeConverterHash = new Hashtable();
this.intToTypeConverterHash.put(Integer.valueOf(8), Double.class);
this.intToTypeConverterHash.put(Integer.valueOf(-7), Boolean.class);
this.intToTypeConverterHash.put(Integer.valueOf(-3), Byte[].class);
this.intToTypeConverterHash.put(Integer.valueOf(-6), Short.class);
this.intToTypeConverterHash.put(Integer.valueOf(5), Short.class);
this.intToTypeConverterHash.put(Integer.valueOf(4), Integer.class);
this.intToTypeConverterHash.put(Integer.valueOf(2), java.math.BigDecimal.class);
this.intToTypeConverterHash.put(Integer.valueOf(6), Float.class);
this.intToTypeConverterHash.put(Integer.valueOf(1), Character.class);
this.intToTypeConverterHash.put(Integer.valueOf(12), String.class);
this.intToTypeConverterHash.put(Integer.valueOf(91), java.sql.Date.class);
this.intToTypeConverterHash.put(Integer.valueOf(93), java.sql.Timestamp.class);
this.intToTypeConverterHash.put(Integer.valueOf(3), java.math.BigDecimal.class);
this.intToTypeConverterHash.put(Integer.valueOf(-5), java.math.BigDecimal.class);
this.intToTypeConverterHash.put(Integer.valueOf(7), Float.class);
this.intToTypeConverterHash.put(Integer.valueOf(-1), String.class);
this.intToTypeConverterHash.put(Integer.valueOf(92), Time.class);
this.intToTypeConverterHash.put(Integer.valueOf(-2), Byte[].class);
this.intToTypeConverterHash.put(Integer.valueOf(-4), Byte[].class);
//this.intToTypeConverterHash.put(Integer.valueOf(0),null.class);
}
/**
* INTERNAL: Given a call, this method produces the stored procedure string
* based on the SQL string inside the call.
*/
protected String buildProcedureString(SQLCall call) {
String stringToModify = call.getSQLString();
String replacementToken = getSession().getPlatform().getStoredProcedureParameterPrefix();
StringWriter stringWriter = new StringWriter();
int startIndex = 0;
int nextParamIndex = 0;
int tokenIndex = stringToModify.indexOf("?");
while (tokenIndex != -1) {
stringWriter.write(stringToModify.substring(startIndex, tokenIndex));
startIndex = tokenIndex + 1;
Object parameter = call.getParameters().get(nextParamIndex);
if (parameter instanceof DatabaseField) {
stringWriter.write(replacementToken);
stringWriter.write(((DatabaseField)parameter).getName());
} else if (parameter instanceof ParameterExpression) {
stringWriter.write(replacementToken);
stringWriter.write(((ParameterExpression)parameter).getField().getName());
} else {
getSession().getPlatform().appendParameter(call, stringWriter, parameter);
}
tokenIndex = stringToModify.indexOf("?", startIndex);
nextParamIndex++;
}
stringWriter.write(stringToModify.substring(startIndex));
return stringWriter.toString();
}
/**
* PUBLIC: Generate an amendment class that will set up the descriptors to use
* these stored procedures.
*/
public void generateAmendmentClass(Writer outputWriter, String packageName, String className) throws ValidationException {
String methodComment = "/**\n * EclipseLink generated method. \n * WARNING: This code was generated by an automated tool.\n * Any changes will be lost when the code is re-generated\n */";
ClassDescriptor descriptor;
Vector storedProcedureVector;
Hashtable mappingHashtable;
StoredProcedureDefinition definition;
Vector storedProcedureDefinitionArguments;
Enumeration argumentEnum;
FieldDefinition fieldDefinition;
try {
outputWriter.write("package ");
outputWriter.write(packageName);
outputWriter.write(";\n\nimport java.util.*;\nimport java.lang.reflect.*;");
outputWriter.write("\nimport org.eclipse.persistence.queries.*;\nimport org.eclipse.persistence.sessions.*;\nimport org.eclipse.persistence.mappings.*;\n\n/**\n * ");
outputWriter.write("This is a EclipseLink generated class to add stored procedure admendments to a project. \n * Any changes to this code will be lost when the class is regenerated \n */\npublic class ");
outputWriter.write(className);
outputWriter.write("{\n");
Enumeration descriptorEnum = this.storedProcedures.keys();
while (descriptorEnum.hasMoreElements()) {
descriptor = (ClassDescriptor)descriptorEnum.nextElement();
if (descriptor.isDescriptorForInterface() || descriptor.isAggregateDescriptor()) {
continue;
}
outputWriter.write(methodComment);
outputWriter.write("\npublic static void amend");
outputWriter.write(Helper.getShortClassName(descriptor.getJavaClass()));
outputWriter.write("ClassDescriptor(ClassDescriptor descriptor){\n\t");
storedProcedureVector = (Vector)this.storedProcedures.get(descriptor);
mappingHashtable = (Hashtable)this.mappingStoredProcedures.get(descriptor);
definition = (StoredProcedureDefinition)storedProcedureVector.elementAt(0);
outputWriter.write("\n\t//INSERT QUERY\n");
outputWriter.write("\tInsertObjectQuery insertQuery = new InsertObjectQuery();\n\tStoredProcedureCall call = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("insertQuery.setCall(call);\n\tdescriptor.getQueryManager().setInsertQuery(insertQuery);\n\t");
definition = (StoredProcedureDefinition)storedProcedureVector.elementAt(1);
if (definition != null) {
outputWriter.write("\n\t//UPDATE QUERY\n");
outputWriter.write("\tUpdateObjectQuery updateQuery = new UpdateObjectQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("updateQuery.setCall(call);\n\tdescriptor.getQueryManager().setUpdateQuery(updateQuery);\n");
}
definition = (StoredProcedureDefinition)storedProcedureVector.elementAt(2);
outputWriter.write("\n\t//DELETE QUERY\n");
outputWriter.write("\tDeleteObjectQuery deleteQuery = new DeleteObjectQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("deleteQuery.setCall(call);\n\tdescriptor.getQueryManager().setDeleteQuery(deleteQuery);\n");
if (storedProcedureVector.size() > 3) {
definition = (StoredProcedureDefinition)storedProcedureVector.elementAt(3);
outputWriter.write("\n\t//READ OBJECT QUERY\n");
outputWriter.write("\tReadObjectQuery readQuery = new ReadObjectQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("readQuery.setCall(call);\n\tdescriptor.getQueryManager().setReadObjectQuery(readQuery);\n");
}
//generate read all stored procs.
if (storedProcedureVector.size() > 4) {
definition = (StoredProcedureDefinition)storedProcedureVector.elementAt(4);
outputWriter.write("\n\t//READ ALL QUERY\n");
outputWriter.write("\tReadAllQuery readAllQuery = new ReadAllQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("readAllQuery.setCall(call);\n\tdescriptor.getQueryManager().setReadAllQuery(readAllQuery);\n");
}
//generate 1:m mapping procedures.
if (mappingHashtable != null) {
outputWriter.write("\n\t//MAPPING QUERIES\n");
//read all
outputWriter.write("\tReadAllQuery mappingQuery; \n");
outputWriter.write("\tDeleteAllQuery deleteMappingQuery; \n");
for (Enumeration e = mappingHashtable.keys(); e.hasMoreElements();) {
String mappingName = (String)e.nextElement();
definition = (StoredProcedureDefinition)((Hashtable)mappingHashtable.get(mappingName)).get("1MREAD");
if (definition != null) {
outputWriter.write("\n\t//MAPPING READALL QUERY FOR " + mappingName + "\n");
outputWriter.write("\tmappingQuery= new ReadAllQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("mappingQuery.setCall(call);\n\t((OneToManyMapping)descriptor.getMappingForAttributeName(\"" + mappingName + "\")).setCustomSelectionQuery(mappingQuery);\n");
}
//DeleteAll Query
definition = (StoredProcedureDefinition)((Hashtable)mappingHashtable.get(mappingName)).get("1MDALL");
if (definition != null) {
outputWriter.write("\n\t//MAPPING DELETEALL QUERY FOR " + mappingName + "\n");
outputWriter.write("\tdeleteMappingQuery= new DeleteAllQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("deleteMappingQuery.setCall(call);\n\t((OneToManyMapping)descriptor.getMappingForAttributeName(\"" + mappingName + "\")).setCustomDeleteAllQuery(deleteMappingQuery);\n");
}
}
}
outputWriter.write("}\n");
}
definition = (StoredProcedureDefinition)sequenceProcedures.get("SELECT");
if (definition != null) {
outputWriter.write("\n\tValueReadQuery seqSelectQuery = new ValueReadQuery();\n\tcall = new StoredProcedureCall();\n");
outputWriter.write("\tcall.setProcedureName(\"");
outputWriter.write(definition.getName());
outputWriter.write("\");\n\t");
storedProcedureDefinitionArguments = definition.getArguments();
argumentEnum = storedProcedureDefinitionArguments.elements();
while (argumentEnum.hasMoreElements()) {
fieldDefinition = (FieldDefinition)argumentEnum.nextElement();
outputWriter.write("call.addNamedArgument(\"");
outputWriter.write(fieldDefinition.getName());
outputWriter.write("\", \"");
outputWriter.write(this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
outputWriter.write("seqSelectQuery.addArgument(\"" + this.getFieldName(fieldDefinition.getName()));
outputWriter.write("\");\n\t");
}
outputWriter.write("seqSelectQuery.setCall(call);\n\tproject.getLogin().setSelectSequenceNumberQuery(seqSelectQuery);\n");
}
outputWriter.write("}\n");
outputWriter.write(methodComment);
outputWriter.write("\npublic static void amendDescriptors(org.eclipse.persistence.sessions.Project project) throws Exception{");
outputWriter.write("\n\tamendSequences(project);");
outputWriter.write("\n\tfor(Iterator enumtr = project.getDescriptors().values().iterator(); enumtr.hasNext();) {");
outputWriter.write("\n\t\tDescriptor descriptor = (ClassDescriptor)enumtr.next();");
outputWriter.write("\n\t\tif(!(descriptor.isAggregateDescriptor() || descriptor.isDescriptorForInterface())) {");
outputWriter.write("\n\t\t\tMethod method = " + className + ".class.getMethod(\"amend\"+org.eclipse.persistence.internal.helper.Helper.getShortClassName(descriptor.getJavaClass())+\"ClassDescriptor\", new Class[] {ClassDescriptor.class});");
outputWriter.write("\n\t\t\tmethod.invoke(null, new Object[] {descriptor});");
outputWriter.write("\n\t\t}");
outputWriter.write("\n\t}");
outputWriter.write("\n}");
outputWriter.write("\n}\n");
outputWriter.flush();
} catch (IOException exception) {
throw ValidationException.fileError(exception);
}
}
/**
* INTERNAL: Generates the delete stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateDeleteStoredProcedure(ClassDescriptor descriptor) {
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setDescriptor(descriptor);
deleteQuery.setModifyRow(new DatabaseRecord());
return this.generateObjectStoredProcedure(deleteQuery, descriptor.getPrimaryKeyFields(), "DEL_");
}
/**
* INTERNAL: Generates the insert stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateInsertStoredProcedure(ClassDescriptor descriptor) {
InsertObjectQuery insertQuery = new InsertObjectQuery();
insertQuery.setDescriptor(descriptor);
insertQuery.setModifyRow(descriptor.getObjectBuilder().buildTemplateInsertRow(getSession()));
return this.generateObjectStoredProcedure(insertQuery, descriptor.getFields(), "INS_");
}
/**
* INTERNAL: Generates the mapping stored procedures for this descriptor.
* currently only 1:1 and 1:M are supported
*/
protected Hashtable generateMappingStoredProcedures(ClassDescriptor descriptor) {
Vector mappings = descriptor.getMappings();
Hashtable mappingSP = new Hashtable();
Hashtable mappingTable;
for (Enumeration enumtr = mappings.elements(); enumtr.hasMoreElements();) {
mappingTable = new Hashtable();
DatabaseMapping mapping = (DatabaseMapping)enumtr.nextElement();
if (mapping.isOneToManyMapping()) {
if (!getSession().getPlatform().isOracle()) {
//reads not supported in oracle
mappingTable.put("1MREAD", generateOneToManyMappingReadProcedure((OneToManyMapping)mapping));
}
if (mapping.isPrivateOwned()) {
//generate delete all for 1:M query
mappingTable.put("1MDALL", generateOneToManyMappingDeleteAllProcedure((OneToManyMapping)mapping));
}
mappingSP.put(mapping.getAttributeName(), mappingTable);
}
}
return mappingSP;
}
/**
* INTERNAL: Generates the object level stored procedure based on the passed in query
*/
protected StoredProcedureDefinition generateObjectStoredProcedure(DatabaseQuery query, List fields, String namePrefix) {
String className = Helper.getShortClassName(query.getDescriptor().getJavaClass());
return generateStoredProcedure(query, fields, getPrefix() + namePrefix + className);
}
/**
* INTERNAL: Generates the delete all stored procedure for this mapping
*/
protected StoredProcedureDefinition generateOneToManyMappingDeleteAllProcedure(OneToManyMapping mapping) {
ClassDescriptor targetDescriptor = mapping.getReferenceDescriptor();
DeleteAllQuery deleteAllQuery = new DeleteAllQuery();
deleteAllQuery.setDescriptor(targetDescriptor);
deleteAllQuery.setReferenceClass(targetDescriptor.getJavaClass());
deleteAllQuery.setSelectionCriteria(mapping.getSelectionCriteria());
return generateOneToManyMappingProcedures(mapping, deleteAllQuery, mapping.getTargetForeignKeyToSourceKeys(), "D_1M_");
}
/**
* INTERNAL: Generates all the stored procedures for this mapping
*/
protected StoredProcedureDefinition generateOneToManyMappingProcedures(OneToManyMapping mapping, DatabaseQuery query, Map fields, String namePrefix) {
String sourceClassName = Helper.getShortClassName(mapping.getDescriptor().getJavaClass());
return generateStoredProcedure(query, new ArrayList(fields.values()), getPrefix() + namePrefix + sourceClassName + "_" + mapping.getAttributeName());
}
/**
* INTERNAL: Generates the read all stored procedure for this mapping
*/
protected StoredProcedureDefinition generateOneToManyMappingReadProcedure(OneToManyMapping mapping) {
ClassDescriptor targetDescriptor = mapping.getReferenceDescriptor();
ReadAllQuery readAllQuery = new ReadAllQuery();
readAllQuery.setDescriptor(targetDescriptor);
readAllQuery.setReferenceClass(targetDescriptor.getJavaClass());
readAllQuery.setSelectionCriteria(mapping.getSelectionCriteria());
return generateOneToManyMappingProcedures(mapping, readAllQuery, mapping.getTargetForeignKeyToSourceKeys(), "R_1M_");
}
/**
* INTERNAL: Generates the read all stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateReadAllStoredProcedure(ClassDescriptor descriptor) {
ReadAllQuery readAllQuery = new ReadAllQuery();
readAllQuery.setDescriptor(descriptor);
readAllQuery.setReferenceClass(descriptor.getJavaClass());
return generateObjectStoredProcedure(readAllQuery, descriptor.getPrimaryKeyFields(), "RALL_");
}
/**
* INTERNAL: Generates the read stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateReadStoredProcedure(ClassDescriptor descriptor) {
ReadObjectQuery readQuery = new ReadObjectQuery();
readQuery.setDescriptor(descriptor);
readQuery.setReferenceClass(descriptor.getJavaClass());
return generateObjectStoredProcedure(readQuery, descriptor.getPrimaryKeyFields(), "READ_");
}
/**
* INTERNAL: Generates the select and update stored procedures for this project.
* no procedures are generated for native sequencing. Note: reads are not supported in Oracle.
*/
protected void generateSequenceStoredProcedures(org.eclipse.persistence.sessions.Project project) {
DatabaseLogin login = (DatabaseLogin)project.getDatasourceLogin();
if (login.shouldUseNativeSequencing()) {
// There is nothing required for native SQL.
return;
}
if (project.usesSequencing()) {
if (!getSession().getPlatform().isOracle()) {
// CR#3934352, updated to support new sequencing and use a single procedure.
StoredProcedureDefinition definition = new StoredProcedureDefinition();
definition.setName(Helper.truncate(project.getName() + "SEQ_SEL", MAX_NAME_SIZE));
definition.addArgument("SEQ_NAME", String.class, 100);
definition.addArgument("PREALLOC_SIZE", java.math.BigDecimal.class, 10);
definition.addStatement("UPDATE " + ((TableSequence)login.getDefaultSequence()).getTableName() + " SET "
+ ((TableSequence)login.getDefaultSequence()).getCounterFieldName() + " = "
+ ((TableSequence)login.getDefaultSequence()).getCounterFieldName() + " + "
+ getSession().getPlatform().getStoredProcedureParameterPrefix() + "PREALLOC_SIZE WHERE "
+ ((TableSequence)login.getDefaultSequence()).getNameFieldName() + " = "
+ getSession().getPlatform().getStoredProcedureParameterPrefix() + "SEQ_NAME");
definition.addStatement("SELECT " + ((TableSequence)login.getDefaultSequence()).getCounterFieldName() + " FROM "
+ ((TableSequence)login.getDefaultSequence()).getTableName() + " WHERE "
+ ((TableSequence)login.getDefaultSequence()).getNameFieldName() + " = "
+ getSession().getPlatform().getStoredProcedureParameterPrefix() + "SEQ_NAME");
sequenceProcedures.put("SELECT", definition);
writeDefinition(definition);
}
}
}
/**
* INTERNAL: Generates the stored procedure for this query. A new row
* will be used for the check prepare.
*/
protected StoredProcedureDefinition generateStoredProcedure(DatabaseQuery query, List fields, String name) {
return generateStoredProcedure(query, fields, new DatabaseRecord(), name);
}
/**
* INTERNAL: Generates the stored procedure for this query using the row
* passed in for the check prepare.
*/
protected StoredProcedureDefinition generateStoredProcedure(DatabaseQuery query, List fields, AbstractRecord rowForPrepare, String name) {
StoredProcedureDefinition definition = new StoredProcedureDefinition();
Vector callVector;
Vector statementVector = new Vector();
query.checkPrepare(getSession(), rowForPrepare, true);
callVector = ((CallQueryMechanism)query.getQueryMechanism()).getCalls();
if (callVector.isEmpty()) {
if (((CallQueryMechanism)query.getQueryMechanism()).getCall() == null) {
// do nothing
} else {
callVector.addElement(((CallQueryMechanism)query.getQueryMechanism()).getCall());
}
}
Enumeration enumtr = callVector.elements();
while (enumtr.hasMoreElements()) {
SQLCall call = (SQLCall)enumtr.nextElement();
statementVector.addElement(this.buildProcedureString(call));
}
definition.setStatements(statementVector);
DatabaseField databaseField;
AbstractRecord dataRow;
Hashtable fieldNames = new Hashtable();
List primaryKeyFields = fields;
for (int index = 0; index < primaryKeyFields.size(); index++) {
databaseField = (DatabaseField)primaryKeyFields.get(index);
fieldNames.put(databaseField.getName(), this.schemaManager.getColumnInfo(null, null, databaseField.getTableName(), databaseField.getName()).firstElement());
}
definition.setName(Helper.truncate(name, MAX_NAME_SIZE));
Enumeration fieldsEnum = fieldNames.keys();
String prefixArgToken;
if (getSession().getPlatform().isOracle()) {
prefixArgToken = getSession().getPlatform().getStoredProcedureParameterPrefix();
} else {
prefixArgToken = "";
}
while (fieldsEnum.hasMoreElements()) {
Number dataType;
dataRow = (AbstractRecord)fieldNames.get(fieldsEnum.nextElement());
dataType = (Number)dataRow.get("DATA_TYPE");
Class type = this.getFieldType(dataType);
String typeName = (String)dataRow.get("TYPE_NAME");
if ((type != null) || (typeName == null) || (typeName.length() == 0)) {
definition.addArgument(prefixArgToken + (String)dataRow.get("COLUMN_NAME"), type, ((Number)dataRow.get("COLUMN_SIZE")).intValue());
} else {
definition.addArgument(prefixArgToken + (String)dataRow.get("COLUMN_NAME"), typeName);
}
}
return definition;
}
/**
* PUBLIC:
* generates all the stored procedures using the schema manager. The schema manager
* may be set to write directly to the database on the a file. See
* outputDDLToWriter(Writer) and outputDDLToDatabase() on SchemaManager
*/
public void generateStoredProcedures() {
// Must turn binding off to ensure literals are printed correctly.
boolean wasBinding = getSession().getLogin().shouldBindAllParameters();
getSession().getLogin().setShouldBindAllParameters(false);
Map descriptors = getSession().getProject().getDescriptors();
Iterator iterator = descriptors.keySet().iterator();
ClassDescriptor desc;
StoredProcedureDefinition definition;
Vector definitionVector;
this.generateSequenceStoredProcedures(getSession().getProject());
while (iterator.hasNext()) {
desc = (ClassDescriptor)descriptors.get(iterator.next());
if (desc.isDescriptorForInterface() || desc.isDescriptorTypeAggregate()) {
continue;
}
definition = this.generateInsertStoredProcedure(desc);
definitionVector = new Vector();
definitionVector.addElement(definition);
this.writeDefinition(definition);
definition = this.generateUpdateStoredProcedure(desc);
definitionVector.addElement(definition);
this.writeDefinition(definition);
definition = this.generateDeleteStoredProcedure(desc);
definitionVector.addElement(definition);
this.writeDefinition(definition);
if (!getSession().getPlatform().isOracle()) {
definition = this.generateReadStoredProcedure(desc);
definitionVector.addElement(definition);
this.writeDefinition(definition);
definition = this.generateReadAllStoredProcedure(desc);
definitionVector.addElement(definition);
this.writeDefinition(definition);
}
Hashtable mappingDefinitions = this.generateMappingStoredProcedures(desc);
for (Enumeration enum2 = mappingDefinitions.elements(); enum2.hasMoreElements();) {
Hashtable table = (Hashtable)enum2.nextElement();
definition = (StoredProcedureDefinition)table.get("1MREAD");
if (definition != null) {
this.writeDefinition(definition);
}
definition = (StoredProcedureDefinition)table.get("1MDALL");
if (definition != null) {
this.writeDefinition(definition);
}
}
this.storedProcedures.put(desc, definitionVector);
if (!mappingDefinitions.isEmpty()) {
this.mappingStoredProcedures.put(desc, mappingDefinitions);
}
}
getSession().getLogin().setShouldBindAllParameters(wasBinding);
}
/**
* PUBLIC:
* generates all the stored procedures to the writer using
* the schema manager outputDDLToWriter(Writer).
*/
public void generateStoredProcedures(Writer writerOrNull) {
this.writer = writerOrNull;
this.schemaManager.outputDDLToWriter(getWriter());
this.generateStoredProcedures();
try {
getWriter().flush();
} catch (IOException exception) {
System.out.println(exception);
exception.printStackTrace();
}
}
/**
* INTERNAL: Generates the update stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateUpdateStoredProcedure(ClassDescriptor descriptor) {
UpdateObjectQuery updateQuery = new UpdateObjectQuery();
updateQuery.setDescriptor(descriptor);
updateQuery.setModifyRow(descriptor.getObjectBuilder().buildTemplateUpdateRow(getSession()));
return this.generateObjectStoredProcedure(updateQuery, descriptor.getFields(), "UPD_");
}
/**
* INTERNAL:
* return the original field name based on the argument name.
*/
protected String getFieldName(String argumentName) {
if (getSession().getPlatform().isOracle()) {
return argumentName.substring(getSession().getPlatform().getStoredProcedureParameterPrefix().length());
} else {
return argumentName;
}
}
/**
* INTERNAL:
* return the class corresponding to the passed in JDBC type.
*/
protected Class getFieldType(Object jdbcDataType) {
Integer key = Integer.valueOf(((Number)jdbcDataType).intValue());
return (Class)intToTypeConverterHash.get(key);
}
public String getPrefix() {
return prefix;
}
public AbstractSession getSession() {
return schemaManager.getSession();
}
public Writer getWriter() {
return writer;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* INTERNAL:
* Verify that this project and descriptors do not have optimistic locking.
*/
protected void verify() throws org.eclipse.persistence.exceptions.ValidationException {
if (getSession().getProject().usesOptimisticLocking()) {
throw org.eclipse.persistence.exceptions.ValidationException.optimisticLockingNotSupportedWithStoredProcedureGeneration();
}
}
public void writeDefinition(StoredProcedureDefinition definition) {
this.schemaManager.replaceObject(definition);
}
}