Is there any support in spring-data-cassandra for updating cassandra counter tables? - spring-data-cassandra

I'm using spring-data-cassandra but I can't find a method in CassandraTemplate that deals with counters.

There is no support for the counter column at this time. Please create a Jira for the enhancement request and we will schedule it in a future release.

Actually you can do this using QueryBuilder. It has special method for this purpose: QueryBuilder.incr("count_col"), here count_col is column with type counter. It produces instance of inner static class Assignment.CounterAssignment.
For example your entire update can be built as:
Update update = QueryBuilder.update("stats_count_table").
with(QueryBuilder.incr("count_col")).
where(eq("key1", key1)).
and(eq("key2", key2));

Related

When updating log4j to 2.x, how to deal with changed Level integers?

I am updating log4j -> log4j2.
In the old version, the integer value of Level.DEBUG is 10000. (log4j doc for Level.DEBUG).
In the new version, the integer value of Level.DEBUG is 500. (log4j2 doc for Level.DEBUG)
I have code that calls Level.DEBUG.toInt() (log4j), which I therefore cannot simply update to Level.DEBUG.intLevel() (log4j2)?
Is there some way to use the old numbers in my existing code, 10000 in this case?
In the code I am updating, Level.DEBUG.toInt() is input to a public method which takes int-level as input, and I'm not sure which other repos depend on this method's functionality.
Should I alter this method to use the new int-level values, and try to hunt down everywhere it might be called?
Or maybe map it's input to the old version's int-level values (extremely hacky)?
Or is there somewhere in the new version that can map to the old int-level values?

Entity Framework Core 3.0: Modify configured Global Query during runtime

I've following requirement:
During the model configuration, I create a QueryFilter for an Entity
var entity = modelBuilder.Entity<TBaseTable>().HasQueryFilter(r => r.UserId == CurrentUserId)
So during runtime in some cases the CurrentUserId changes. But my QueryFilter does not get refreshed. The filter criteria still are working with the old UserId value, which I had during the configuration. How do i modify the my QueryFiler, which was set during the configuration? If I'm right then the whole model is already cached and will not be reinitialized. Any ideas about that?
The trick is to declare CurrentUserId as a property on your DbContext class - the property getter can still return a value from a global class instance.
Global filters can be made dynamic by using properties/methods/fields of the db context. See the TenantId example in Global Query Filters documentation.
(Since I needed to read the comments to find the answer to your question I rephrased the comment as provided by "Ivan Stoev Oct 8 '19 at 15:34" and posted it as an answer)

How to get query string in case CQLStatement,QueryState and QueryOptions is given

Cassandra has org.apache.cassandra.cql3.QueryHandler interface which provide apis to handle external queries from client.
Below api which handles prepared statment:
public ResultMessage processPrepared(CQLStatement statement, QueryState state, QueryOptions options) throws RequestExecutionException, RequestValidationException;
I want to log queryString and value passed to it, in case CQLStatement,QueryState and QueryOptions is given . How can i get it?
I Believe a person who has worked on cassandra code can help me out in this.
This would be very difficult in 2.1. With newer versions where for logging they needed this they just recreate it as well as possible. You can see how in the ReadCommand implementations, theres a name() or toCQLString() used in things like slow query logging. You could backport this and the 2 implementations of appendCQLWhereClause for ability to do similar and then build one for modification statement.
in getPrepared() you can get the rawCQLStatement from the ParsedStatement.Prepared and stash it in the thread local.
You may want to alternatively consider using a custom implementation of tracing (example) or using triggers and building a mutation logger.
Do the following:
create a class that would implement the QueryHandler interface and make Cassandra aware of it
in that class you can maintain a list of the queries (add to this list when prepare method is being called) and the current query that you will get from the list when getPrepared it's called; you can get it from the list using the MD5Digest id
when processPrepared is called you can replace the ? in the query string with the values in the QueryOptions options.getValues().
HTH

How to Inner Join an UDF Function with parameters using SubSonic

I need to query a table using FreeTextTable (because I need ranking), with SubSonic. AFAIK, Subsonic doesn't support FullText, so I ended up creating a simple UDF function (Table Function) which takes 2 params (keywords to search and max number of results).
Now, how can I inner join the main table with this FreeTextTable?
InlineQuery is not an option.
Example:
table ARTICLE with fields Id, ArticleName, Author, ArticleStatus.
The search can be done by one of more of the following fields: ArticleName (fulltext), Author (another FullText but with different search keywords), ArticleStatus (an int).
Actually the query is far more complex and has other joins (depending on user choice).
If SubSonic cannot handle this situation, probably the best solution is good old plain sql (so there would be no need to create an UDF, too).
Thanks for your help
ps: will SubSonic 3.0 handle this situation?
3.0 can do this for you but you'd need to make a template for it since we don't handle functions (yet) out of the box. I'll be working on this in the coming weeks - for now I don't think 2.2 will do this for you.
I realize your question is more complex than this, but you can get results from a table valued function via SubSonic 2.2 with a little massaging.
Copy the .cs file from one of your generated views into a safe folder, and then change all the properties to match the columns returned by your UDF.
Then, on your collection, add a constructor method with your parameters and have it execute an InlineQuery.
public partial class UDFSearchCollection
{
public UDFSearchCollection(){}
public UDFSearchCollection(string keyword, int maxResults)
{
UDFSearchCollection coll = new InlineQuery().ExecuteAsCollection<UDFSearchCollection>("select resultID, resultColumn from dbo.udfSearch(#keyword, #maxResults)",keyword,maxResults);
coll.CopyTo(this);
coll = null;
}
}
public partial class UDFSearch : ReadOnlyRecord<UDFSearch>, IReadOnlyRecord
{
//all the methods for read only record go here
...
}
An inner join would be a little more difficult because the table object doesn't have it's own parameters collection. But it could...

Subsonic Deeploads: Is This Supported?

It could very well be that I'm just missing the correct vernacular in this space, but I'm looking for a particular piece of functionality in SubSonic. In NetTiers it was called a "DeepLoad". A deep load runs to the database and fetches many objects (ie. fetch this OrderDetail and all of it's LineItems) in one database call.
Again, I want to run to the data store once an build up a potentially dense object graph or related items populated by the data store.
How do I do this in SubSonic and what is it called in SubSonic?
You can do this in SubSonic 3.0 (not yet released, but almost there...) using IQueryable with lazy loading:
var db=new NorthwindDB();
var order=db.Orders.Where(x=>.xID==20).SingleOrDefault();
Assert.Equal(3,order.OrderDetails.Count());
if you're not on 3 (which requires .net 3.5) you can do this with Active record as Paul mentions - but it will make two calls.
There is no eager loading, and DeepSave in ActiveRecord only calls Save.
Here is an example with Northwind Order class foreign key method.
[Test]
public void SelectOrderDetails()
{
Order order = new Order(10250);
OrderDetailCollection details = order.OrderDetails();
Assert.IsTrue(details.Count == 3);
}

Resources