diff options
Diffstat (limited to 'das-java/trunk/rdb/src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultSetProcessor.java')
-rw-r--r-- | das-java/trunk/rdb/src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultSetProcessor.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/das-java/trunk/rdb/src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultSetProcessor.java b/das-java/trunk/rdb/src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultSetProcessor.java new file mode 100644 index 0000000000..fa17ebb098 --- /dev/null +++ b/das-java/trunk/rdb/src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultSetProcessor.java @@ -0,0 +1,180 @@ +/* + * 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 java.util.Set; + +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); + int rootRowsCreated = addRowToGraph(rsr, rsMetadata); + start += rootRowsCreated; + } + } else { + int position = start; + while (rs.absolute(position) && start < end) { + rsr.processRow(rs); + int rootRowsCreated = addRowToGraph(rsr, rsMetadata); + start += rootRowsCreated; + ++position; + } + } + } + + /** + * @param row + * @param resultMetadata + * @return the number of root rows created + */ + private int addRowToGraph(ResultSetRow row, ResultMetadata resultMetadata) throws SQLException { + int rootRowsCreated = 0; + int objectsCreated = 0; + boolean recursive = row.isRecursive(); + Set rootTableNames = metadata.getConfigWrapper().getRootTableNames(); + 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); + // check whether row is a new root row + if (newlyCreated) { + objectsCreated++; + // increment root row count + // in case of recursive table, assuming that first table occurrence is the root + if (rootTableNames.contains(tableName) && rawDataFromRow.getIndex() == 0) rootRowsCreated++; + // get whole table data + // (only for non-recursive statements; recursive statements already have the whole table data) + if (!recursive) rawDataFromRow = row.processRowForTable(tableName); + // create data object + 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"); + } + } + + if(tableObject != null){ + if (this.logger.isDebugEnabled()) { + this.logger.debug("Do not allow any Null tableObject in tableObjects"); + } + tableObjects.put(tableName, tableObject, newlyCreated); + } + } + + if (objectsCreated == 0) { + // duplicated row + if (this.logger.isDebugEnabled()) { + this.logger.debug("Found duplicated row"); + } + } else { + tableObjects.processRelationships(); + } + + return rootRowsCreated; + + } + +} |