Setting QueryOptions on a string CQL query in Spring data cassandra 2.0.7.RELEASE - spring-data-cassandra

I will have to set query options on the string CQL query in spring-data-cassandra-2.0.7.RELEASE
CassandraOperations cOps = new CassandraTemplate(session);
String cqlQuery = "insert into......."
cOps.getCqlOperations().execute(cqlQuery);
Is there a way to apply QueryOptions to the string input query? Also I dont want to convert to statement and then apply the options. As the use case is the input cqlQuery can be any statement.
Appreciate the response.

TL;DR
There's no support for QueryOptions through CqlTemplate. QueryOptions are only usable with CassandraTemplate (AsyncCassandraTemplate, ReactiveCassandraTemplate).
Explanation
CqlTemplate is a CQL-only API abstraction that aligns with Spring Framework's JdbcTemplate. You can configure some options on CqlTemplate-level, such as ConsistencyLevel, FetchSize, and RetryPolicy.
If you want to control query options, use Datastax' Statement objects (such as SimpleStatement):
SimpleStatement statement = new SimpleStatement("INSERT INTO …");
statement.setFetchSize(1234);
statement.setRetryPolicy(FallthroughRetryPolicy.INSTANCE);
// probably more …
execute(statement);

Related

Cassandra update with Lightweight Transactions

I want to implement the lightweight transaction for update statement with SpringBoot Cassandra.
Ex:
UPDATE cyclist_id SET id = 15a116fc-b833-4da6-ab9a-4a3775750239 where lastname = 'WELTEN' and firstname = 'Bram' IF age = 18;
Is there any API available with CassandraTemplate to achieve the above?
I tried using
UpdateOptions updateOptions = UpdateOptions.builder().consistencyLevel(ConsistencyLevel.QUORUM).build(); But not sure how to set the If condition with value (like age = 18)
I figured out the solution to implement lightweight transaction through SpringBoot Caasandra.
Create CqlSession using com.datastax.oss.driver.api.core.CqlSession builder.
Use PreparedStatement - for query. In query use IF condition. and set the parameter to the query using BoundStatement.

Is this type of query safe from sql injection?

let tableName = req.body.tableName
let colName = req.body.col1+","+req.body.col2
sqlString = INSERT INTO ${tableName}(${colName}) VALUES ($1,$2) RETURNING *
No, you are using user's input as is inside a SQL query.
Use some kind of query builder like knex, which has a built in way of escaping user's input properly.

jOOQ Query OrderBy as String

I'm getting the order by clause as a String from the application configuration.
Example
String orderByString = "NAME DESC, NUMBER ASC";
Now I want to use this order by in jOOQ query:
Result<KampagneRecord> records = repository.dsl()
.selectFrom(KAMPAGNE)
.orderBy(orderByString)
.fetch();
Unfortunately orderBy does not accept a String.
Is there a way to add the order by clause to the query?
You could use the fact that jOOQ does not validate your plain SQL templating, and just wrap your string in a DSL.field(String):
Result<KampagneRecord> records = repository.dsl()
.selectFrom(KAMPAGNE)
.orderBy(field(orderByString))
.fetch();
Of course, you will have to make sure that syntactical correctness is guaranteed, and SQL injection is prevented.
Some edge cases that rely on jOOQ being able to transform your SQL's ORDER BY clause might stop working, but in your simple query example, this would not apply.
An alternative solution, in very simple cases, is to preprocess your string. It seems as though this would work:
String orderByString = "NAME DESC, NUMBER ASC";
List<SortField<?>> list =
Stream.of(orderByString.split(","))
.map(String::trim)
.map(s -> s.split(" +"))
.map(s -> {
Field<?> field = field(s[0]);
return s.length == 1
? field.sortDefault()
: field.sort("DESC".equalsIgnoreCase(s[1])
? SortOrder.DESC
: SortOrder.ASC
);
})
.collect(Collectors.toList());
System.out.println(list);
This list can now be passed to the orderBy() clause.

In Azure DocumentDb, how do I write an "IN" statement using LINQ to SQL

I want to retrieve about 50 - 100 documents by their ID from DocumentDb. I have the list of IDs in a List<string>. How do I use LINQ to SQL to retrieve those documents. I don't want to write the actual SQL query as a string, as in:
IQueryable<Family> results = client.CreateDocumentQuery<Family>(collectionUri, "SELECT * FROM family WHERE State IN ('TX', 'NY')", DefaultOptions);
I want to be able to use lambda expressions to create the query, because I don't want to hard-code the names of the fields as string.
It seems that you do not want to generate and pass query string SELECT * FROM family WHERE State IN ('TX', 'NY') to query documents, you could try the following code.
List<string> ids = new List<string>() { "TX", "NY" };
client.CreateDocumentQuery<Family>(collectionUri).Where(d => ids.Contains(d.id));

RDD joinWithCassandraTable

Can anyone please help me on the below query.
I have an RDD with 5 columns. I want to join with a table in Cassandra.
I knew that there is a way to do that by using "joinWithCassandraTable"
I see somewhere a syntax to use it.
Syntax:
RDD.joinWithCassandraTable(KEYSPACE, tablename, SomeColumns("cola","colb"))
.on(SomeColumns("colc"))
Can anyone please send me the correct syntax??
I would like to actually know where to mention the column name of a table which is a key to join.
JoinWithCassandraTable works by pulling only the partition keys which match your RDD entries from C* so it only works on partition keys.
The documentation is here
https://github.com/datastax/spark-cassandra-connector/blob/master/doc/2_loading.md#using-joinwithcassandratable
and API Doc is here
http://datastax.github.io/spark-cassandra-connector/ApiDocs/1.6.0-M2/spark-cassandra-connector/#com.datastax.spark.connector.RDDFunctions
The jWCT table method can be used without the fluent api by specifying all the arguments in the method
def joinWithCassandraTable[R](
keyspaceName: String,
tableName: String,
selectedColumns: ColumnSelector = AllColumns,
joinColumns: ColumnSelector = PartitionKeyColumns)
But the fluent api can also be used
joinWithCassandraTable[R](keyspace, tableName).select(AllColumns).on(PartitionKeyColumns)
These two calls are equivalent
Your example
RDD.joinWithCassandraTable(KEYSPACE, tablename, SomeColumns("cola","colb")) .on(SomeColumns("colc"))
Uses the Object from RDD to join against colc of tablename and only returns cola and colb as join results.
Use below syntax for join in cassandra
joinedData = rdd.joinWithCassandraTable(keyspace,table).on(partitionKeyName).select(Column Names)
It will look something like this,
joinedData = rdd.joinWithCassandraTable(keyspace,table).on('emp_id').select('emp_name', 'emp_city')

Resources