Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.jdbc.kernel;
import static java.util.Arrays.asList;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.openjpa.jdbc.meta.MappingRepository;
import org.apache.openjpa.jdbc.meta.QueryResultMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.StoredProcedure;
import org.apache.openjpa.kernel.AbstractStoreQuery;
import org.apache.openjpa.kernel.QueryContext;
import org.apache.openjpa.kernel.QueryOperations;
import org.apache.openjpa.kernel.StoreQuery;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MultiQueryMetaData;
import org.apache.openjpa.meta.QueryMetaData;
import org.apache.openjpa.util.InternalException;
/**
* Executes a stored procedure.
*
* @author ppoddar
*
*/
public class StoredProcedureQuery extends AbstractStoreQuery {
private static final long serialVersionUID = 1L;
private static final Object[] NO_PARAM = new Object[0];
JDBCStore _store;
StoredProcedure _proc;
private MultiQueryMetaData _meta;
public StoredProcedureQuery(JDBCStore store) {
_store = store;
}
public int getOperation() {
return QueryOperations.OP_SELECT;
}
public StoredProcedure getProcedure() {
return _proc;
}
public DBDictionary getDictionary() {
return _store.getDBDictionary();
}
@Override
public boolean setQuery(Object meta) {
if (meta == null || meta instanceof MultiQueryMetaData) {
_meta = (MultiQueryMetaData)meta;
return true;
} else {
throw new InternalException("Unknown " + meta);
}
}
@Override
public Executor newDataStoreExecutor(ClassMetaData meta, boolean subclasses) {
List mappings = null;
List> classes = null;
if (_meta != null) {
List parts = _meta.getComponents();
if (parts != null && !parts.isEmpty()) {
mappings = new ArrayList<>();
classes = new ArrayList<>();
MappingRepository repos = _store.getConfiguration().getMappingRepositoryInstance();
for (QueryMetaData part : parts) {
QueryResultMapping mapping = repos.getQueryResultMapping(ctx.getResultMappingScope(),
part.getResultSetMappingName(),
null, true);
if (mapping != null) {
mappings.add(mapping);
}
if (part.getResultType() != null) {
classes.add(part.getResultType());
}
}
}
}
return new StoredProcedureQueryExecutor(this, mappings, classes);
}
@Override
public boolean supportsParameterDeclarations() {
return false;
}
@Override
public boolean supportsDataStoreExecution() {
return true;
}
@Override
public boolean requiresCandidateType() {
return false;
}
@Override
public boolean requiresParameterDeclarations() {
return false;
}
public class StoredProcedureQueryExecutor extends AbstractExecutor {
private final List> _resultClasses;
private final List _resultMappings;
public StoredProcedureQueryExecutor(StoredProcedureQuery q, List resultMapping,
List> classes) {
QueryContext ctx = q.getContext();
_resultMappings = resultMapping;
_resultClasses = classes;
// Look for the named Stored Procedure in the database
String procName = ctx.getQueryString();
_proc = getStoredProcedure(_store.getConnection(), _store.getDBDictionary(), procName);
if (_proc == null) {
throw new RuntimeException("Can not find stored procedure " + procName);
}
}
StoredProcedure getStoredProcedure(Connection conn, DBDictionary dict, String procedureName) {
try {
StoredProcedure sp = dict.getStoredProcedure(conn.getMetaData(), null, null, procedureName);
if (sp != null) {
return sp;
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
} finally {
try {
conn.close();
} catch (SQLException ex) {
}
}
throw new RuntimeException("Procedure [" + procedureName + "] not found");
}
@Override
public ResultObjectProvider executeQuery(StoreQuery q, Object[] params, Range range) {
try {
DBDictionary dict = _store.getDBDictionary();
Connection conn = _store.getConnection();
CallableStatement stmnt = conn.prepareCall(_proc.getCallSQL());
final StoredProcedureQuery spq = StoredProcedureQuery.class.cast(q);
for (Column c : spq.getProcedure().getInColumns()) {
dict.setUnknown(stmnt, c.getIndex() + 1, params[c.getIndex()], c);
}
for (Column c : spq.getProcedure().getInOutColumns()) {
final int index = c.getIndex() + 1;
stmnt.registerOutParameter(index, c.getType());
dict.setUnknown(stmnt, index, params[index - 1], c);
}
for (Column c : spq.getProcedure().getOutColumns()) {
stmnt.registerOutParameter(c.getIndex() + 1, c.getType());
}
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)q.getContext().getFetchConfiguration();
ResultObjectProvider rop = new XROP(_resultMappings, _resultClasses, _store, fetch, stmnt);
rop.open();
return rop;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Object[] toParameterArray(StoreQuery q, Map, ?> userParams) {
if (userParams == null) return NO_PARAM;
Object[] array = new Object[userParams.size()];
int i = 0;
StoredProcedureQuery storedProcedureQuery = StoredProcedureQuery.class.cast(q);
for (final Column[] columns : asList(
storedProcedureQuery.getProcedure().getInColumns(),
storedProcedureQuery.getProcedure().getInOutColumns())) {
for (Column c : columns) {
array[i] = userParams.get(c.getIdentifier().getName());
if (array[i++] == null) {
userParams.get(c.getIndex());
}
}
}
return array;
}
}
}