Scala Postgres IN Operator - postgresql

I'm developing a web application based on Activator and Postgres.
I am trying to perform the following SQL query:
SELECT *
FROM table t_0
WHERE t_0.category IN (?)
then to populate the query I am using the following Scala code
val readQuery = """ SELECT * FROM table t_0 WHERE t_0.category IN (?) """
val categories = Array("free time", "living")
val insertValues = Array(categories)
val queryResult = await { connection.sendPreparedStatement(readQuery, insertValues) }
Even though there are some records in the database I always get an empty set, I have already tried with some forms of Array[Byte], but I have never managed to get results.
Does anybody have some tips or trick that I can use?
Thanks!

Related

Scala, Quill - how to compare values with case-insensitive?

I created a quill query, which should find some data in database by given parameter:
val toFind = "SomeName"
val query = query.find(value => infix"$value = ${lift(toFind)}".as[Boolean])
It works fine when for example I have data in database "SomeName", but if I want to have same results by passing there "somename" I found nothing. The problem is with data case-sensitive.
Is it possible to always find values with case-insensitive way? In quill docs I have not found anything about it.
Ok, I found a solution. It is enough to add LOWER() sql function to infix:
val query = query.find(value => infix"LOWER($value) = ${lift(toFind.toLowerCase)}".as[Boolean])

OrientDB select record count from all graph classes

Any way to get record count for each graph class (V, E and their subclasses)?
I tried to build query in SQL format for current case:
SELECT #class, count(*) FROM V GROUP BY #class
SELECT #class, count(*) FROM E GROUP BY #class
But using count() + GROUP BY is extrimply slow combination.
While console command list classes works fast and return values for count of records in each class (field RECORDS), how to extract this counts via SQL query (or via OrientJS API)?
The main idea is find a way to:
Get list of all classes if database
Get count of records that stored in each class
Technical details
In OrientDB functions you have access to orient variable that have .getDatabase() method. And this method return JAVA ODatabaseDocumentTx class instance. This class provides the method .countClass(className) that returns the number of the records of the class className (method documentation) and it works realy fast.
Solution
Create function in OrientDB Studio with name "getClassCounts", language "javascript", idempotent: true:
var db = orient.getDatabase();
var classesRawInfo = db.getMetadata().getImmutableSchemaSnapshot().getClasses().toArray();
var classesList = {};
var i = classesRawInfo.length;
while(--i) {
var className = classesRawInfo[i].name;
classesList[className] = db.countClass(className);
}
return classesList;
Executing:
via SQL: SELECT getClassCounts()
I think it's not possible, also because it wouldn't so fast as in the console

Pagination with native query in slick

I am using Slick to connect to Postgres Database in our application. I have a generic filtering logic, where a Filter object will be passed from the UI, and it should return results with pagination. The Filter object should be generic so that it can be re-used.
Pseudo code of filter object is given below:
Filter = {
type: table
prop: List_of_conditions
page : 1
size : 10
}
Currently, I am building a native SQL from the Filter object and executing it. However, I am not able to use take and drop before the query is actually getting executed. It is currently getting all the results, and then dropping the unnecessary records.
I know how to do it with the slick queries, but not sure how to use pagination with the native queries?
val res = StaticQuery.queryNA[Entity](queryStr).list.drop((filter.pageNo- 1) * filter.pageSize).take(filter.pageSize)
I am using Slick 2.1
When you are using plain sql, you can't use the collection operators to build a query. You have to do it all in SQL:
val limit = filter.pageSize
val offset = (filter.pageNo- 1) * filter.pageSize
val res = StaticQuery.queryNA[Entity](queryStr ++ s" LIMIT $limit OFFSET $offset").list
I haven't tested it but i would suggest you to try to move .list call to the end
val res = StaticQuery.queryNA[Entity](queryStr).drop((filter.pageNo- 1) * filter.pageSize).take(filter.pageSize).list

Dynamic Auto Sharding support for Scala Slick

This post is related to the issue already raised at Dynamically changing the database shard that I am connecting too.
Pointers to code that should be changed to implement this feature is given at https://github.com/slick/slick/issues/703
Am a newbie to Scala and Slick , Can I get some help ? , as to how to proceed implementing this feature. Is there any slick/scala pattern to do this at application level.
My problem is "I have pool of connections of different shards of MySQL, when I write a query/queries involving ID's (sharding keys), slick should dynamically run that particular query on the respective database shard"
For Example: If I write a query like this
val q = for ( user <- users.filter(_.name === "cat")
post <- posts.filter(_.postedBy === user.id)
comment <- comments.filter(_.postId === post.id)
} yield comment.content
q.run
a trivial case should be like one below.
users += User(id = 1, name = "cat", email = "cat#mat.com") => hits shard no 1
Even if the User ID, Post ID, Comment ID are dynamically produced, slick should hit the correct database shard using some sharding criteria ( key (ID) % 3 ) and everything should happen at the background just like single database query.
To implement the feature at application level
Is there any way to read Query object state dynamically so that I can write a function like
def func(q: Query[Something], shards: Map[Int, Database], num: Int): Unit = {
shards(q.getId % num).withSession{ implicit session => {
q.run
}
}
Usage:
val q = users.insert(User(id = 1, name = "cat", email = "cat#cat.com"))
func(q, shards, 10) => q executes on one of the 10 shards.
Thanks.

How can I limit my query by date using ScalaQuery

I'm using Scalaquery and have run into a problem when I attempt to limit my query based on a date field. I'm using Scala 2.9.2, ScalaQuery 2.9.1:0.10.0-M1 Consider the code below:
case class MyCase (opr_date: Date)
object MyClass extends BasicTable[MyCase]("MYTABLE") {
def opr_date = column[Date]("OPR_DATE")
def * = opr_date <> (MyCase, MyCase.unapply _)
def test(date: Date) = db.withSession {
logDebug("test date: " + date)
val qry = for {
d <- MyClass if (d.opr_date === date)
} yield d.opr_date
logDebug(qry.selectStatement)
qry.list
}
}
This query never returns any rows. Here is the calling code:
"The data" should {
"be available " in {
val testDate = CommonFormat.parseDate("2012-10-27", CommonFormat.EURO_SHORT).getTime
val records = MyClass.test2(new java.sql.Date(testDate))
records.size must be_>(0)
}
}
The query returns 0 rows and produces the following SQL when I print the select:
SELECT "t1"."OPR_DATE" FROM "MYTABLE" "t1" WHERE ("t1"."OPR_DATE"={d '2012-10-27'})
I have data available for the test date. If I paste the SQL into a SQL editor and edit the date so that its not the JDBC template format ('27-Oct-2012') the query returns the expected rows. Can anyone tell me what I'm doing wrong? Shouldn't this work?
I found out this morning that this was a data problem. The query works fine. It turns out I was connecting to the wrong server. We have a confusing setup of multiple environments and back-up systems that share the same database name. After connecting to the correct server the query works as expected. I saw different results between my code and the editor-tool because they were pointing at different servers (same database name ugh).Thank you to all who took time to look into this for me. I appreciate your efforts.