/*
* 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.prestodb;
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 java.util.regex.Pattern;
import org.teiid.metadata.BaseColumn.NullType;
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.TypeFacility;
import org.teiid.translator.jdbc.JDBCMetdataProcessor;
public class PrestoDBMetadataProcessor extends JDBCMetdataProcessor implements MetadataProcessor<Connection>{
private boolean trimColumnNames;
@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 {
List<String> catalogs = getCatalogs(conn);
for (String catalog:catalogs) {
if (getCatalog() != null && !getCatalog().equalsIgnoreCase(catalog)) {
continue;
}
List<String> schemas = getSchema(conn, catalog);
for (String schema:schemas) {
if (getSchemaPattern() != null && !Pattern.matches(getSchemaPattern(), schema)) {
continue;
}
List<String> tables = getTables(conn, catalog, schema);
for (String table:tables) {
if (shouldExclude(table)) {
continue;
}
addTable(table, conn, catalog, schema, metadataFactory);
}
}
}
}
private List<String> getCatalogs(Connection conn) throws SQLException {
ArrayList<String> catalogs = new ArrayList<String>();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW CATALOGS"); //$NON-NLS-1$
while (rs.next()){
catalogs.add(rs.getString(1));
}
rs.close();
return catalogs;
}
private List<String> getSchema(Connection conn, String catalog) throws SQLException {
ArrayList<String> schemas = new ArrayList<String>();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW SCHEMAS FROM "+catalog); //$NON-NLS-1$
while (rs.next()){
schemas.add(rs.getString(1));
}
rs.close();
return schemas;
}
private List<String> getTables(Connection conn, String catalog, String schema) throws SQLException {
ArrayList<String> tables = new ArrayList<String>();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW TABLES FROM "+catalog+"."+schema); //$NON-NLS-1$ //$NON-NLS-2$
while (rs.next()){
tables.add(rs.getString(1));
}
rs.close();
return tables;
}
private String getRuntimeType(String type) {
if (type.equalsIgnoreCase("boolean")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.BOOLEAN;
}
else if (type.equalsIgnoreCase("bigint")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.LONG;
}
else if (type.equalsIgnoreCase("double")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.DOUBLE;
}
else if (type.equalsIgnoreCase("varchar")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.STRING;
}
else if (type.equalsIgnoreCase("varbinary")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.VARBINARY;
}
else if (type.equalsIgnoreCase("date")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.DATE;
}
else if (type.equalsIgnoreCase("time") || type.equalsIgnoreCase("time with timezone")) { //$NON-NLS-1$ //$NON-NLS-2$
return TypeFacility.RUNTIME_NAMES.TIME;
}
else if (type.equalsIgnoreCase("timestamp") || type.equalsIgnoreCase("timestamp with timezone")) { //$NON-NLS-1$ //$NON-NLS-2$
return TypeFacility.RUNTIME_NAMES.TIMESTAMP;
}
else if (type.equalsIgnoreCase("json")) { //$NON-NLS-1$
return TypeFacility.RUNTIME_NAMES.BLOB;
}
//TODO: Array, MAP, INETERVAL support.
return TypeFacility.RUNTIME_NAMES.OBJECT;
}
private void addTable(String tableName, Connection conn, String catalog, String schema, MetadataFactory metadataFactory) throws SQLException {
Table table = addTable(metadataFactory, null, null, tableName, null, tableName);
if (table == null) {
return;
}
String nis = catalog+"."+schema+"."+tableName; //$NON-NLS-1$ //$NON-NLS-2$
table.setNameInSource(nis);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW COLUMNS FROM "+nis); //$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);
NullType nt = Boolean.valueOf(rs.getString(3))?NullType.Nullable:NullType.No_Nulls;
Column column = metadataFactory.addColumn(name, runtimeType, table);
column.setNameInSource(name);
column.setUpdatable(true);
column.setNullType(nt);
}
rs.close();
}
}