Repository: metamodel Updated Branches: refs/heads/master fe3aebe86 -> 423676852
METAMODEL-1122: Fixed Fixes #130 Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/42367685 Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/42367685 Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/42367685 Branch: refs/heads/master Commit: 423676852d8f147905b12ba0203d15771aff87ae Parents: fe3aebe Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Authored: Sat Oct 8 23:57:36 2016 -0700 Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Committed: Sat Oct 8 23:57:36 2016 -0700 ---------------------------------------------------------------------- CHANGES.md | 1 + cassandra/.gitignore | 1 + .../cassandra/CassandraDataContext.java | 74 +++++++++++++++++--- .../cassandra/CassandraDataContextTest.java | 18 ++++- 4 files changed, 84 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metamodel/blob/42367685/CHANGES.md ---------------------------------------------------------------------- diff --git a/CHANGES.md b/CHANGES.md index bda2372..5c0b893 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ * [METAMODEL-1118] - Fixed bug pertaining to cloning of FilterItem.LogicalOperator in compiled queries. * [METAMODEL-1111] - Added WHERE rewrite for Oracle when empty strings are considered as NULL. + * [METAMODEL-1122] - Optimized the way the Cassandra module executes primary key lookup queries. * [METAMODEL-1109] - Fixed diacritics/encoding issue with Fixed Width reader. * [METAMODEL-1115] - Added support for passing your own PartnerConnection object to the Salesforce.com connector. * [METAMODEL-1113] - Fixed support for ColumnNamingStrategy in CSV connector. http://git-wip-us.apache.org/repos/asf/metamodel/blob/42367685/cassandra/.gitignore ---------------------------------------------------------------------- diff --git a/cassandra/.gitignore b/cassandra/.gitignore index 4e247ee..212512c 100644 --- a/cassandra/.gitignore +++ b/cassandra/.gitignore @@ -2,3 +2,4 @@ /target /.classpath /.project +/.toDelete http://git-wip-us.apache.org/repos/asf/metamodel/blob/42367685/cassandra/src/main/java/org/apache/metamodel/cassandra/CassandraDataContext.java ---------------------------------------------------------------------- diff --git a/cassandra/src/main/java/org/apache/metamodel/cassandra/CassandraDataContext.java b/cassandra/src/main/java/org/apache/metamodel/cassandra/CassandraDataContext.java index e99570b..3a1684e 100644 --- a/cassandra/src/main/java/org/apache/metamodel/cassandra/CassandraDataContext.java +++ b/cassandra/src/main/java/org/apache/metamodel/cassandra/CassandraDataContext.java @@ -18,23 +18,41 @@ */ package org.apache.metamodel.cassandra; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.datastax.driver.core.querybuilder.Select; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; import org.apache.metamodel.DataContext; import org.apache.metamodel.MetaModelException; import org.apache.metamodel.QueryPostprocessDataContext; import org.apache.metamodel.data.DataSet; +import org.apache.metamodel.data.SimpleDataSetHeader; import org.apache.metamodel.query.FilterItem; -import org.apache.metamodel.schema.*; +import org.apache.metamodel.query.SelectItem; +import org.apache.metamodel.schema.Column; +import org.apache.metamodel.schema.ColumnType; +import org.apache.metamodel.schema.MutableColumn; +import org.apache.metamodel.schema.MutableSchema; +import org.apache.metamodel.schema.MutableTable; +import org.apache.metamodel.schema.Schema; +import org.apache.metamodel.schema.Table; import org.apache.metamodel.util.SimpleTableDef; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ColumnMetadata; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Statement; +import com.datastax.driver.core.TableMetadata; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.querybuilder.Select.Selection; /** * DataContext implementation for Apache Cassandra database. @@ -145,6 +163,20 @@ public class CassandraDataContext extends QueryPostprocessDataContext implements final MutableSchema theSchema = new MutableSchema(getMainSchemaName()); for (final SimpleTableDef tableDef : tableDefs) { final MutableTable table = tableDef.toTable().setSchema(theSchema); + + final TableMetadata cassandraTable = cassandraCluster.getMetadata().getKeyspace(keySpaceName).getTable(table + .getName()); + if (cassandraTable != null) { + final List<ColumnMetadata> primaryKeys = cassandraTable.getPrimaryKey(); + for (ColumnMetadata primaryKey : primaryKeys) { + final MutableColumn column = (MutableColumn) table.getColumnByName(primaryKey.getName()); + if (column != null) { + column.setPrimaryKey(true); + } + column.setNativeType(primaryKey.getType().getName().name()); + } + } + theSchema.addTable(table); } return theSchema; @@ -162,7 +194,7 @@ public class CassandraDataContext extends QueryPostprocessDataContext implements query.limit(maxRows); } final ResultSet resultSet = cassandraCluster.connect().execute(query); - + final Iterator<Row> response = resultSet.iterator(); return new CassandraDataSet(response, columns); } @@ -172,10 +204,34 @@ public class CassandraDataContext extends QueryPostprocessDataContext implements } @Override + protected org.apache.metamodel.data.Row executePrimaryKeyLookupQuery(Table table, List<SelectItem> selectItems, + Column primaryKeyColumn, Object keyValue) { + + if (primaryKeyColumn.getType() == ColumnType.UUID && keyValue instanceof String) { + keyValue = UUID.fromString(keyValue.toString()); + } + + Selection select = QueryBuilder.select(); + for (SelectItem selectItem : selectItems) { + final Column column = selectItem.getColumn(); + assert column != null; + select = select.column(column.getName()); + } + + final Statement statement = select.from(keySpaceName, table.getName()).where(QueryBuilder.eq(primaryKeyColumn + .getName(), keyValue)); + + final Row row = cassandraCluster.connect().execute(statement).one(); + + return CassandraUtils.toRow(row, new SimpleDataSetHeader(selectItems)); + } + + @Override protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) { if (!whereItems.isEmpty()) { // not supported - will have to be done by counting client-side - logger.debug("Not able to execute count query natively - resorting to query post-processing, which may be expensive"); + logger.debug( + "Not able to execute count query natively - resorting to query post-processing, which may be expensive"); return null; } final Statement statement = QueryBuilder.select().countAll().from(keySpaceName, table.getName()); http://git-wip-us.apache.org/repos/asf/metamodel/blob/42367685/cassandra/src/test/java/org/apache/metamodel/cassandra/CassandraDataContextTest.java ---------------------------------------------------------------------- diff --git a/cassandra/src/test/java/org/apache/metamodel/cassandra/CassandraDataContextTest.java b/cassandra/src/test/java/org/apache/metamodel/cassandra/CassandraDataContextTest.java index 4921639..a9d9605 100644 --- a/cassandra/src/test/java/org/apache/metamodel/cassandra/CassandraDataContextTest.java +++ b/cassandra/src/test/java/org/apache/metamodel/cassandra/CassandraDataContextTest.java @@ -32,6 +32,7 @@ import javax.swing.table.TableModel; import org.apache.metamodel.data.DataSet; import org.apache.metamodel.data.DataSetTableModel; import org.apache.metamodel.data.FilteredDataSet; +import org.apache.metamodel.data.InMemoryDataSet; import org.apache.metamodel.query.Query; import org.apache.metamodel.query.parser.QueryParserException; import org.apache.metamodel.schema.ColumnType; @@ -113,7 +114,7 @@ public class CassandraDataContextTest { @Test public void testWhereColumnEqualsValues() throws Exception { - DataSet ds = dc.query().from(testTableName).select("id").and("title").where("id").isEquals(firstRowId) + DataSet ds = dc.query().from(testTableName).select("id").and("title").where("title").isEquals(firstRowTitle) .execute(); assertEquals(FilteredDataSet.class, ds.getClass()); @@ -125,6 +126,21 @@ public class CassandraDataContextTest { ds.close(); } } + + @Test + public void testPrimaryKeyLookup() throws Exception { + DataSet ds = dc.query().from(testTableName).select("id").and("title").where("id").isEquals(firstRowId) + .execute(); + + assertEquals(InMemoryDataSet.class, ds.getClass()); + try { + assertTrue(ds.next()); + assertEquals("Row[values=[" + firstRowId + ", " + firstRowTitle + "]]", ds.getRow().toString()); + assertFalse(ds.next()); + } finally { + ds.close(); + } + } @Test public void testWhereColumnInValues() throws Exception {