org.compass.gps.device.jdbc.mapping.TableToResourceMapping Maven / Gradle / Ivy
/*
* Copyright 2004-2009 the original author or authors.
*
* Licensed 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.compass.gps.device.jdbc.mapping;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import javax.sql.DataSource;
import org.compass.gps.device.jdbc.JdbcGpsDeviceException;
import org.compass.gps.device.jdbc.JdbcUtils;
/**
* A specialized form of
* {@link org.compass.gps.device.jdbc.mapping.ResultSetToResourceMapping},
* mapping a specfic database table to a resource.
*
* Since the mapping works against a table, most of the parameters can be
* automatically generated. The required mappings are the alias name and the
* table name. The settings that can be generated are the id mappings
* (based on the table primary keys), the select query (based on the table
* name), and the version query (based on the table name and the version column
* mappings).
*
* If no data column mappings are provided, the
* indexUnMappedColumns
from
* {@link org.compass.gps.device.jdbc.mapping.ResultSetToResourceMapping} can be
* user to auto map all the table columns as data columns.
*
* For real time mirroring, at least one version column mapping ({@link org.compass.gps.device.jdbc.mapping.VersionColumnMapping})
* is required. And the version query can be auto generated.
*
* Note that the mapping will auto generate only settings that have not been
* set. If, for example, the select query was set, it will not be generated.
*
* @author kimchy
*/
public class TableToResourceMapping extends ResultSetToResourceMapping implements AutoGenerateMapping {
private String tableName;
/**
* Creates a new table to Resource
mapping. Must set the
* alias, and the table name.
*
* Indexing of unmapped columns is diasabled by default.
*
*/
public TableToResourceMapping() {
}
/**
* Creates a new table to {@link org.compass.core.Resource} mapping with the given
* table name and alias.
*
* Indexing of unmapped columns is disabled by default.
*
* @param tableName The table name
* @param alias The {@link org.compass.core.Resource} alias
*/
public TableToResourceMapping(String tableName, String alias) {
setAlias(alias);
this.tableName = tableName;
}
/**
* Generates the unset mappings.
*
* Generates the id mappings based on the table primary keys if no id column
* mappings are set.
*
* Generates the select query based on the table name if no select query is
* set.
*
* Generates the version query based on the table name and the version
* column mappings if no version query is set and at least one version
* column mapping is set.
*/
public void generateMappings(DataSource dataSource) throws JdbcGpsDeviceException {
if (idMappingsSize() == 0) {
generateIdMappings(dataSource);
}
if (getSelectQuery() == null) {
generateSelectQuery(dataSource);
}
if (getVersionQuery() == null && supportsVersioning()) {
generateVersionQuery(dataSource);
}
}
private void generateIdMappings(DataSource dataSource) throws JdbcGpsDeviceException {
Connection con = JdbcUtils.getConnection(dataSource);
ResultSet pks = null;
try {
DatabaseMetaData metaData = con.getMetaData();
pks = metaData.getPrimaryKeys(null, null, getTableName());
while (pks.next()) {
String pkColumnName = pks.getString("COLUMN_NAME");
addIdMapping(new IdColumnToPropertyMapping(pkColumnName, pkColumnName));
}
} catch (SQLException e) {
throw new JdbcGpsDeviceException("Failed to fetch primary keys for table [" + getTableName() + "]", e);
} finally {
JdbcUtils.closeResultSet(pks);
JdbcUtils.closeConnection(con);
}
}
private void generateSelectQuery(DataSource dataSource) {
if (isIndexUnMappedColumns()) {
setSelectQuery("select * from " + getTableName());
} else {
StringBuffer sb = new StringBuffer();
sb.append("select ");
boolean first = true;
for (Iterator idIt = idMappingsIt(); idIt.hasNext();) {
ColumnToPropertyMapping idMapping = (ColumnToPropertyMapping) idIt.next();
if (first) {
first = false;
} else {
sb.append(", ");
}
if (idMapping.isUsingColumnIndex()) {
throw new IllegalArgumentException(
"When mapping and not using the indexUnMappedColumns, must specify id column name and not column index");
}
sb.append(idMapping.getColumnName());
}
for (Iterator dataIt = dataMappingsIt(); dataIt.hasNext();) {
ColumnToPropertyMapping dataMapping = (ColumnToPropertyMapping) dataIt.next();
sb.append(", ");
if (dataMapping.isUsingColumnIndex()) {
throw new IllegalArgumentException(
"When mapping and not using the indexUnMappedColumns, must specify id column name and not column index");
}
sb.append(dataMapping.getColumnName());
}
for (Iterator verIt = versionMappingsIt(); verIt.hasNext();) {
VersionColumnMapping verMapping = (VersionColumnMapping) verIt.next();
sb.append(", ");
if (verMapping.isUsingColumnIndex()) {
throw new IllegalArgumentException(
"When mapping version column to a table, must specify version column name and not column index");
}
sb.append(verMapping.getColumnName());
}
sb.append(" from ");
sb.append(getTableName());
setSelectQuery(sb.toString());
}
}
private void generateVersionQuery(DataSource dataSource) {
StringBuffer sb = new StringBuffer();
sb.append("select ");
boolean first = true;
for (Iterator idIt = idMappingsIt(); idIt.hasNext();) {
IdColumnToPropertyMapping idMapping = (IdColumnToPropertyMapping) idIt.next();
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(idMapping.getColumnNameForVersion());
}
for (Iterator verIt = versionMappingsIt(); verIt.hasNext();) {
VersionColumnMapping verMapping = (VersionColumnMapping) verIt.next();
sb.append(", ");
if (verMapping.isUsingColumnIndex()) {
throw new IllegalArgumentException(
"When mapping version column to a table, must specify version column name and not column index");
}
sb.append(verMapping.getColumnName());
}
sb.append(" from ");
sb.append(getTableName());
setVersionQuery(sb.toString());
}
/**
* Returns the table name that the mappings maps to.
*/
public String getTableName() {
return tableName;
}
/**
* Sets the table name that the mappings maps to.
*/
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String toString() {
return "Table[" + tableName + "] " + super.toString();
}
}