How to Dynamically assemble SQL queries with haskell based on route parameters - haskell

I've got a scotty web app that I am trying to implement a dynamic search interface over and keep hitting a wall on how I should implement it. The Basic premise is the following:
Given a list of URL parameters: let params = [Param]
where param: type Param = (Text, Text)
I would like to be able to
Lets say I have a table in my database where:
Users
| user_id | username | email | first_name | last_name | created_at |
|---------|----------|-------|------------|-----------|------------|
| Int | Text | Text | Text | Text | timestamp |
My base SQL query might look like this:
baseQuery :: Query
baseQuery :: [sql| SELECT user_id, username, email, first_name, last_name, created_at FROM users |]
In the case of receiving url parameters I would want to be able to apply them to the WHERE clause, ORDER BY clause, etc.
What would be the best strategy to transform the following url:
arbitraryhost:/users?order_by_max=user_id&first_name=emg184&last_name=stackoverflow&limit=20
which would result in the following parameters list:
let params = [("order_by_max","user_id"), ("first_name","emg184"), ("last_name","stackoverflow"), ("limit", "20")]
How would i generate the follwing query:
"SELECT user_id, username, email, first_name, last_name, created_at
FROM users
WHERE first_name = ? AND last_name = ?
ORDER BY user_id
LIMIT ?"
("emg184", "stackoverflow", 20)
(I really like the way that the query builder knexjs works which allows for ad hoc fragments of queries to be generated and applied as a higher order function to some base query http://knexjs.org/)
Im wondering what a strategy or implementation of this might be as I have not been successful in building anything that I find to be very fitting for this.

Related

Fetch Last Login Details using Summarize by Time Stamp in KQL

I am trying to get last login details of user in Kusto database using KQL query language. However I am not getting exact result with below query.
GlobalID - Unique GUID Value which will be created every time user logged in
UserId - Logged in UserId value
LastSuccessFullLoginTimeStamp - Max Timestamp value
//Fetch Last Logged in userID details
let window = 2h;
Events
| where Timestamp >= ago(window)
| extend UserId = tostring(Properties.UserId)
| where UserId in ('12345','56789','24680')
//| summarize LastSuccessFullLoginTimeStamp = max(Timestamp), count() by
GlobalId,UserId
|project GlobalID,UserId,TimeStamp
But I am failed to get output as like below from above sample data. Fetch latest GlobalID based on userId and last logged in time. Where I am doing wrong? I tried with summarize, make_set but in vain.
You should use the arg_max() function:
let window = 2h;
Events
| where Timestamp >= ago(window)
| extend UserId = tostring(Properties.UserId)
| where UserId in ('12345','56789','24680')
| summarize arg_max(Timestamp, *) by UserId

How to run CQL in Zeppelin by taking input in user input format?

I was trying to run CQL query by taking in user input format in Zeppelin tool:-
%cassandra
SELECT ${Select Fields Type=uuid ,uuid | created_by | email_verify| username} FROM
${Select Table=keyspace.table_name}
${WHERE email_verify="true" } ${ORDER BY='updated_date' }LIMIT ${limit = 10};
while running this query I was getting this error:
line 4:0 mismatched input 'true' expecting EOF
(SELECT uuid FROM keyspace.table_name ["true"]...)
You need to move WHERE and ORDER BY out of the dynamic form declaration.
The input field declaration is looks as following: ${field_name=default_value}. In your case, instead of WHERE ..., you've got the field name of WHERE email_verify.
It should be as following (didn't tested):
%cassandra
SELECT ${Select Fields Type=uuid ,uuid | created_by | email_verify| username} FROM
${Select Table=keyspace.table_name}
WHERE ${where_cond=email_verify='true'} ORDER BY ${order_by='updated_date'} LIMIT ${limit = 10};
Update:
here is the working example for table with following structure:
CREATE TABLE test.scala_test2 (
id int,
c int,
t text,
tm timestamp,
PRIMARY KEY (id, c)
) WITH CLUSTERING ORDER BY (c ASC)

Invalid type error when using Datastax Cassandra Driver

I have a case class which represents partition key values.
case class UserKeys (bucket:Int,
email: String)
I create query Clauses as follows:
def conditions(id: UserKeys):List[Clauses] = List(
QueryBuilder.eq("bucket", id.bucket), //TODOM - pick table description from config/env file.
QueryBuilder.eq("email", id.email)
)
And use the query as follows
val selectStmt =
select()
.from(tablename)
.where(QueryBuilder.eq(partitionKeyColumns(0), whereClauseList(0))).and(QueryBuilder.eq(partitionKeyColumns(1), whereClauseList(1)))
.limit(1)
I am getting following error.
com.datastax.driver.core.exceptions.InvalidTypeException: Value 0 of type class com.datastax.driver.core.querybuilder.Clause$SimpleClause does not correspond to any CQL3 type
Question 1 - What am I doing wrong?
The query works on cqlsh
The table I am querying is
CREATE TABLE users (
bucket int,
email text,
firstname text,
lastname text,
authprovider text,
password text,
PRIMARY KEY ((bucket, email), firstname, lastname)
Question 2 - Is there a way to print the List which contains the query clauses? I tried it but I get this incomprehensible text.
List(com.datastax.driver.core.querybuilder.Clause$SimpleClause#2389b3ee, com.datastax.driver.core.querybuilder.Clause$SimpleClause#927f81)
My bad, I was using the query clauses incorrectly. Rather than
.where(QueryBuilder.eq(partitionKeyColumns(0), whereClauseList(0))).and(QueryBuilder.eq(partitionKeyColumns(1), whereClauseList(1)))
I needed to do
.where(whereClauseList(0)).and(whereClauseList(1))
because the List already has QueryBuilder.eq("bucket", id.bucket) part

Creating new model with association but without parent instance

I have these model.
var User = this.sequelize.define('user', {name: String})
var Account = this.sequelize.define('account', {account: String})
User.hasMany(Account);
Account.belongsTo(User);
Now, assume that in TABLE User, i already have:
| id | name |
|----|--------|
| 1 | Maat |
| 2 | MatieL |
Now, i want to create an account but i only want to use User ID not user instance.
Account.create({name: 'MyAccount', userid: 1});
But after that, the row show in TABLE Account is:
| id | account |userId|
|----|-------------|------|
| 1 | MyAccount | NULL |
I don't know why it doesn't work. Please suggest me if you know the answer.
Thank you.
PS:
I know that i can create account instance by another way by firstly finding userinstance by userid then after create account then call userinstance.addAccount(account), but i don't want to use that way because it cost more queries.
PS2: The solution is userId with i capital, not userid
Hi The default foregin key is user_id and not userid
Refer http://docs.sequelizejs.com/en/1.7.0/docs/associations/#foreign-keys

Cassandra + Fetch the last records using in query

I am new in this cassandra database using with nodejs.
I have user_activity table. In this table data will insert based on user activity.
Also I have some user list. I need to fetch the data in that particular users and last record.
I don't interest to put the query in for loop. Have any other idea to achieve this?
Example Code:
var userlist = ["12", "34", "56"];
var query = 'SELECT * FROM user_activity WHERE userid IN ?';
server.user.execute(query, [userlist], {
prepare : true
}, function(err, result) {
console.log(results);
});
How to get the user lists for last one ?
Example:
user id = 12 - need to get last record;
user id = 34 - need to get last record;
user id = 56 - need to get last record;
I need to get these 3 records.
Table Schema:
CREATE TABLE test.user_activity (
userid text,
ts timestamp,
clientid text,
clientip text,
status text,
PRIMARY KEY (userid, ts)
)
It is not possible if you use the IN filter.
If it is a single user_id filter you can apply order by. Of course you need a column for inserted/updated time. So query will be like this:
SELECT * FROM user_activity WHERE user_id = 12 ORDER BY updated_at LIMIT 1;
You can put N value to get number of records
SELECT * FROM user_activity WHERE userid IN ? ORDER BY id DESC LIMIT N

Resources