Skip to content

Commit

Permalink
TEIID-2734 adding native support to cassandra
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Nov 13, 2013
1 parent 6b430de commit 3098952
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 4 deletions.
Expand Up @@ -22,22 +22,29 @@

package org.teiid.translator.cassandra;

import java.util.List;

import javax.resource.cci.ConnectionFactory;

import org.teiid.core.BundleUtil;
import org.teiid.language.Argument;
import org.teiid.language.Call;
import org.teiid.language.Command;
import org.teiid.language.QueryExpression;
import org.teiid.language.Select;
import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.ProcedureExecution;
import org.teiid.translator.ResultSetExecution;
import org.teiid.translator.Translator;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.UpdateExecution;
import org.teiid.translator.cassandra.execution.CassandraDirectQueryExecution;
import org.teiid.translator.cassandra.execution.CassandraQueryExecution;
import org.teiid.translator.cassandra.execution.CassandraUpdateExecution;
import org.teiid.translator.cassandra.metadata.CassandraMetadataProcessor;
Expand Down Expand Up @@ -65,7 +72,26 @@ public UpdateExecution createUpdateExecution(Command command,
ExecutionContext executionContext, RuntimeMetadata metadata,
CassandraConnection connection) throws TranslatorException {
return new CassandraUpdateExecution(command, executionContext, metadata, connection);
}
}

@Override
public ProcedureExecution createProcedureExecution(Call command,
ExecutionContext executionContext, RuntimeMetadata metadata,
CassandraConnection connection) throws TranslatorException {
String nativeQuery = command.getMetadataObject().getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false);
if (nativeQuery != null) {
return new CassandraDirectQueryExecution(nativeQuery, command.getArguments(), command, connection, executionContext);
}
throw new TranslatorException("Missing native-query extension metadata."); //$NON-NLS-1$
}

@Override
public ProcedureExecution createDirectExecution(List<Argument> arguments,
Command command, ExecutionContext executionContext,
RuntimeMetadata metadata, CassandraConnection connection)
throws TranslatorException {
return new CassandraDirectQueryExecution((String) arguments.get(0).getArgumentValue().getValue(), arguments.subList(1, arguments.size()), command, connection, executionContext);
}

@Override
public void getMetadata(MetadataFactory metadataFactory,
Expand Down
@@ -0,0 +1,67 @@
/*
* 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.execution;

import java.util.List;

import org.teiid.language.Argument;
import org.teiid.language.Command;
import org.teiid.language.Literal;
import org.teiid.language.visitor.SQLStringVisitor;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.ProcedureExecution;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.cassandra.CassandraConnection;

public class CassandraDirectQueryExecution extends CassandraQueryExecution implements ProcedureExecution {

private String cql;
private List<Argument> arguments;

public CassandraDirectQueryExecution(String cql, List<Argument> arguments, Command command, CassandraConnection connection, ExecutionContext context){
super(command, connection, context);
this.arguments = arguments;
this.cql = cql;
}

@Override
public void execute() throws TranslatorException {
StringBuilder buffer = new StringBuilder();
SQLStringVisitor.parseNativeQueryParts(cql, arguments, buffer, new SQLStringVisitor.Substitutor() {

@Override
public void substitute(Argument arg, StringBuilder builder, int index) {
Literal argumentValue = arg.getArgumentValue();
builder.append(argumentValue);
}
});
String source_cql = buffer.toString();
execute(source_cql);
}

@Override
public List<?> getOutputParameterValues() throws TranslatorException {
return null;
}

}
Expand Up @@ -26,7 +26,7 @@
import java.util.ArrayList;
import java.util.List;

import org.teiid.language.Select;
import org.teiid.language.Command;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.translator.DataNotAvailableException;
Expand All @@ -41,12 +41,12 @@

public class CassandraQueryExecution implements ResultSetExecution {

private Select query;
private Command query;
private CassandraConnection connection;
private ResultSet resultSet = null;
private ExecutionContext executionContext;

public CassandraQueryExecution(Select query, CassandraConnection connection, ExecutionContext context){
public CassandraQueryExecution(Command query, CassandraConnection connection, ExecutionContext context){
this.query = query;
this.connection = connection;
this.executionContext = context;
Expand All @@ -69,6 +69,10 @@ public void execute() throws TranslatorException {
CassandraSQLVisitor visitor = new CassandraSQLVisitor();
visitor.translateSQL(query);
String cql = visitor.getTranslatedSQL();
execute(cql);
}

protected void execute(String cql) throws TranslatorException {
LogManager.logDetail(LogConstants.CTX_CONNECTOR, "Source-Query:", cql); //$NON-NLS-1$
try {
resultSet = connection.executeQuery(cql);
Expand Down
@@ -0,0 +1,77 @@
/*
* 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 org.junit.Test;
import org.mockito.Mockito;
import org.teiid.cdk.api.TranslationUtility;
import org.teiid.cdk.unittest.FakeTranslationFactory;
import org.teiid.language.Command;
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.translator.Execution;
import org.teiid.translator.ExecutionContext;
import org.teiid.translator.TranslatorException;

@SuppressWarnings("nls")
public class TestNativeCassandra {

@Test public void testDirect() throws TranslatorException {
CassandraExecutionFactory cef = new CassandraExecutionFactory();
cef.setSupportsNativeQueries(true);

String input = "call native('select $1', 'a')";

TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
Command command = util.parseCommand(input);
ExecutionContext ec = Mockito.mock(ExecutionContext.class);
RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
CassandraConnection connection = Mockito.mock(CassandraConnection.class);

Execution execution = cef.createExecution(command, ec, rm, connection);
execution.execute();

Mockito.verify(connection).executeQuery("select 'a'");
}

@Test public void testNativeQuery() throws Exception {
CassandraExecutionFactory cef = new CassandraExecutionFactory();
cef.setSupportsNativeQueries(true);

String input = "call proc('a', 1)";

TransformationMetadata metadata = RealMetadataFactory.fromDDL("create foreign procedure proc (in x string, in y integer) options (\"teiid_rel:native-query\" 'delete from $1 where $2')", "x", "y");
TranslationUtility util = new TranslationUtility(metadata);
Command command = util.parseCommand(input);
ExecutionContext ec = Mockito.mock(ExecutionContext.class);
RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
CassandraConnection connection = Mockito.mock(CassandraConnection.class);

Execution execution = cef.createExecution(command, ec, rm, connection);
execution.execute();

Mockito.verify(connection).executeQuery("delete from 'a' where 1");
}

}

0 comments on commit 3098952

Please sign in to comment.