/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.translator.hive;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.teiid.core.util.StringUtil;
import org.teiid.metadata.Column;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Table;
import org.teiid.translator.MetadataProcessor;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TranslatorProperty;
import org.teiid.translator.TranslatorProperty.PropertyType;
import org.teiid.translator.TypeFacility;
import org.teiid.translator.jdbc.JDBCMetdataProcessor;
public class HiveMetadataProcessor extends JDBCMetdataProcessor implements MetadataProcessor<Connection>{
private boolean trimColumnNames;
private boolean useDatabaseMetaData;
public HiveMetadataProcessor() {
setImportKeys(false);
setQuoteString("`"); //$NON-NLS-1$
}
@Override
public void process(MetadataFactory metadataFactory, Connection conn) throws TranslatorException {
try {
getConnectorMetadata(conn, metadataFactory);
} catch (SQLException e) {
throw new TranslatorException(e);
}
}
@Override
public void getConnectorMetadata(Connection conn, MetadataFactory metadataFactory)
throws SQLException {
if (useDatabaseMetaData) {
super.getConnectorMetadata(conn, metadataFactory);
return;
}
List<String> tables = getTables(conn);
for (String table:tables) {
if (shouldExclude(table)) {
continue;
}
addTable(table, conn, metadataFactory);
}
}
private List<String> getTables(Connection conn) throws SQLException {
ArrayList<String> tables = new ArrayList<String>();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW TABLES"); //$NON-NLS-1$
while (rs.next()){
tables.add(rs.getString(1));
}
rs.close();
return tables;
}
private String getRuntimeType(String type) {
if (type.equalsIgnoreCase("int")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.INTEGER;
}
else if (type.equalsIgnoreCase("tinyint")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.BYTE;
}
else if (type.equalsIgnoreCase("smallint")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.SHORT;
}
else if (type.equalsIgnoreCase("bigint")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.LONG;
}
else if (type.equalsIgnoreCase("string")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.STRING;
}
else if (type.equalsIgnoreCase("float")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.FLOAT;
}
else if (type.equalsIgnoreCase("double")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.DOUBLE;
}
else if (type.equalsIgnoreCase("boolean")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.BOOLEAN;
}
else if (StringUtil.startsWithIgnoreCase(type, "decimal")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.BIG_DECIMAL;
}
else if (type.equalsIgnoreCase("timestamp")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.TIMESTAMP;
}
else if (type.equalsIgnoreCase("date")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.DATE;
}
else if (type.equalsIgnoreCase("BINARY")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.VARBINARY;
}
else if (type.equalsIgnoreCase("varchar")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.STRING;
}
return TypeFacility.RUNTIME_NAMES.STRING;
}
private void addTable(String tableName, Connection conn, MetadataFactory metadataFactory) throws SQLException {
Table table = addTable(metadataFactory, null, null, tableName, null, tableName);
if (table == null) {
return;
}
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("DESCRIBE "+tableName); //$NON-NLS-1$
while (rs.next()){
String name = rs.getString(1);
if (this.trimColumnNames) {
name = name.trim();
}
String type = rs.getString(2);
if (type != null) {
type = type.trim();
}
String runtimeType = getRuntimeType(type);
Column column = metadataFactory.addColumn(name, runtimeType, table);
column.setNameInSource(name);
column.setUpdatable(true);
}
rs.close();
}
public void setTrimColumnNames(boolean trimColumnNames) {
this.trimColumnNames = trimColumnNames;
}
@TranslatorProperty(display="Trim Columns", category=PropertyType.IMPORT, description="Trim column names read from the database")
public boolean isTrimColumnNames() {
return trimColumnNames;
}
@TranslatorProperty(display="Use DatabaseMetaData", category=PropertyType.IMPORT, description= "Use DatabaseMetaData (typical JDBC logic) for importing")
public boolean isUseDatabaseMetaData() {
return useDatabaseMetaData;
}
public void setUseDatabaseMetaData(boolean useDatabaseMetaData) {
this.useDatabaseMetaData = useDatabaseMetaData;
}
}