/* * 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.cassandra; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.resource.ResourceException; import org.teiid.metadata.Column; import org.teiid.metadata.Column.SearchType; import org.teiid.metadata.ExtensionMetadataProperty; 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.cassandra.CassandraExecutionFactory.Event; import com.datastax.driver.core.ColumnMetadata; import com.datastax.driver.core.DataType.Name; import com.datastax.driver.core.IndexMetadata; import com.datastax.driver.core.TableMetadata; public class CassandraMetadataProcessor implements MetadataProcessor<CassandraConnection>{ @ExtensionMetadataProperty(applicable=Table.class, datatype=Boolean.class, display="Allow Filtering", description="This is to avoid the warning from Cassandra when it might not be able to execute the query in an efficient way", required=false) public static final String ALLOWFILTERING = "ALLOWFILTERING"; /** * Creates metadata from all column families in current keyspace. */ public void process(MetadataFactory factory, CassandraConnection connection) throws TranslatorException { try { for (TableMetadata columnFamily : connection.keyspaceInfo().getTables()){ addTable(factory, columnFamily); } } catch (ResourceException e) { throw new TranslatorException(Event.TEIID22000, e, CassandraExecutionFactory.UTIL.gs(Event.TEIID22000)); } } /** * Adds table. * @param columnFamily */ private void addTable(MetadataFactory factory, TableMetadata columnFamily) { Table table = factory.addTable(columnFamily.getName()); addColumnsToTable(factory, table, columnFamily); addPrimaryKey(factory, table, columnFamily); for (IndexMetadata index : columnFamily.getIndexes()) { Column c = table.getColumnByName(index.getTarget()); if (c != null) { c.setSearchType(SearchType.Searchable); factory.addIndex(index.getName(), false, Arrays.asList(index.getTarget()), table); } } table.setSupportsUpdate(true); } /** * Adds a primary key from columnFamily to given table. * @param table Teiid table * @param columnFamily */ private void addPrimaryKey(MetadataFactory factory, Table table, TableMetadata columnFamily) { List<ColumnMetadata> primaryKeys = columnFamily.getPrimaryKey(); List<String> names = new ArrayList<String>(); for (ColumnMetadata columnName : primaryKeys){ names.add(columnName.getName()); table.getColumnByName(columnName.getName()).setSearchType(SearchType.Searchable); } factory.addPrimaryKey("PK_" + columnFamily.getName(), names, table); //$NON-NLS-1$ } /** * Adds all columns of column family. * @param table Teiid table * @param columnFamily Column family */ private void addColumnsToTable(MetadataFactory factory, Table table, TableMetadata columnFamily) { for (ColumnMetadata column : columnFamily.getColumns()){ String type = asTeiidRuntimeType(column.getType().getName()); Column c = factory.addColumn(column.getName(), type, table); c.setUpdatable(true); c.setSearchType(SearchType.Unsearchable); } } private String asTeiidRuntimeType(Name name) { switch(name) { case ASCII: return TypeFacility.RUNTIME_NAMES.STRING; case BIGINT: return TypeFacility.RUNTIME_NAMES.LONG; case BLOB: return TypeFacility.RUNTIME_NAMES.BLOB; case BOOLEAN: return TypeFacility.RUNTIME_NAMES.BOOLEAN; case COUNTER: return TypeFacility.RUNTIME_NAMES.LONG; case DECIMAL: return TypeFacility.RUNTIME_NAMES.BIG_DECIMAL; case DOUBLE: return TypeFacility.RUNTIME_NAMES.DOUBLE; case FLOAT: return TypeFacility.RUNTIME_NAMES.FLOAT; case INET: return TypeFacility.RUNTIME_NAMES.OBJECT; case INT: return TypeFacility.RUNTIME_NAMES.INTEGER; case TEXT: return TypeFacility.RUNTIME_NAMES.STRING; case UUID: return TypeFacility.RUNTIME_NAMES.OBJECT; case VARCHAR: return TypeFacility.RUNTIME_NAMES.STRING; case VARINT: return TypeFacility.RUNTIME_NAMES.BIG_INTEGER; case LIST: return TypeFacility.RUNTIME_NAMES.OBJECT; case SET: return TypeFacility.RUNTIME_NAMES.OBJECT; case MAP: return TypeFacility.RUNTIME_NAMES.OBJECT; case CUSTOM: return TypeFacility.RUNTIME_NAMES.BLOB; case UDT: return TypeFacility.RUNTIME_NAMES.OBJECT; case TUPLE: return TypeFacility.RUNTIME_NAMES.OBJECT; case SMALLINT: return TypeFacility.RUNTIME_NAMES.SHORT; case TINYINT: return TypeFacility.RUNTIME_NAMES.BYTE; case TIMEUUID: return TypeFacility.RUNTIME_NAMES.OBJECT; case TIMESTAMP: return TypeFacility.RUNTIME_NAMES.TIMESTAMP; case DATE: return TypeFacility.RUNTIME_NAMES.DATE; case TIME: return TypeFacility.RUNTIME_NAMES.TIME; default: return TypeFacility.RUNTIME_NAMES.OBJECT; } } }