blob: 431af18d62b0b07e9e5d6855f7b918bcc2f1713c [file] [log] [blame]
/*
* 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.tuscany.das.rdb.graphbuilder.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import org.apache.log4j.Logger;
import commonj.sdo.DataObject;
/**
*
* A ResultSetProcessor is used to transform the data in a ResultSet into a set of inter-related EDataObjects.
*/
public class ResultSetProcessor {
private static final Logger logger = Logger.getLogger(ResultSetProcessor.class);
private TableRegistry registry;
private GraphBuilderMetadata metadata;
private final DataObjectMaker doMaker;
private final RowObjects tableObjects;
public ResultSetProcessor(DataObject g, GraphBuilderMetadata gbmd) {
this.metadata = gbmd;
if (metadata.getRelationships().size() == 0) {
registry = new SingleTableRegistry();
} else {
registry = new MultiTableRegistry();
}
doMaker = new DataObjectMaker(g);
tableObjects = new RowObjects(metadata, registry);
if (this.logger.isDebugEnabled()) {
this.logger.debug(metadata);
}
}
/**
* Process the ResultSet. For each row in the ResultSet, a
*
* @link ResultSetRow object will be created to represent the row as a set of EDataObjects. Then,
* the relevant relationships will be constructed
* between each object in the
* @link ResultSetRow.
*
* @param start
* @param end
*/
public void processResults(int start, int end) throws SQLException {
Iterator i = metadata.getResultMetadata().iterator();
while (i.hasNext()) {
ResultMetadata resultMetadata = (ResultMetadata) i.next();
ResultSet results = resultMetadata.getResultSet();
processResultSet(results, resultMetadata, start, end);
// TODO These statements HAVE to be closed or we will have major problems
// results.getStatement().close();
results.close();
}
}
private void processResultSet(ResultSet rs, ResultMetadata rsMetadata, int start, int end) throws SQLException {
ResultSetRow rsr = new ResultSetRow(rsMetadata);
if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
while (rs.next() && start < end) {
rsr.processRow(rs);
addRowToGraph(rsr, rsMetadata);
++start;
}
} else {
while (rs.absolute(start) && start < end) {
rsr.processRow(rs);
addRowToGraph(rsr, rsMetadata);
++start;
}
}
}
/**
* @param row
* @param resultMetadata
*/
private void addRowToGraph(ResultSetRow row, ResultMetadata resultMetadata) {
tableObjects.clear();
Iterator tables = row.getAllTableData().iterator();
while (tables.hasNext()) {
TableData rawDataFromRow = (TableData) tables.next();
if (!rawDataFromRow.hasValidPrimaryKey() ||
(rawDataFromRow.hasNullPrimaryKey() && !rawDataFromRow.isTableEmpty())) {//some PK null , but other data present
//continue; - need to throw exception as anyway the result will give a wrong impression
//when any one table in result set misses PK column or has null value in PK column
throw new RuntimeException("Table "+rawDataFromRow.getTableName()+" in query does not include Primary Key "+
"column or has null value in it, can not proceed!");
}
String tableName = rawDataFromRow.getTableName();
DataObject tableObject = registry.get(tableName, rawDataFromRow.getPrimaryKeyValues());
boolean newlyCreated = (tableObject == null);
if (newlyCreated
&& !rawDataFromRow.hasNullPrimaryKey()) {//2nd check for null data in PK,
//as TableData.addData() - hasValidPrimaryKey=false is commented for a reason
//with this, DataObjs with null PK will not be added to registry and tableObjects
tableObject = doMaker.createAndAddDataObject(rawDataFromRow, resultMetadata);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Putting table " + tableName + " with PK "
+ rawDataFromRow.getPrimaryKeyValues() + " into registry");
}
registry.put(tableName, rawDataFromRow.getPrimaryKeyValues(), tableObject);
}
else{
if (this.logger.isDebugEnabled()) {
this.logger.debug("Not Null tableObject or NULL PK");
}
}
if(tableObject != null){
if (this.logger.isDebugEnabled()) {
this.logger.debug("Do not allow any Null tableObject in tableObjects");
}
tableObjects.put(tableName, tableObject, newlyCreated);
}
}
tableObjects.processRelationships();
}
}