slick joins with function inputs - function

How is it possible to use inputs from the function and joins in slick
example
def query (coffeID : int) = DBAction { implicit rs =>
val implicitInnerJoin = for {
c <- coffees
s <- suppliers if ((c.supID === s.id ) && (c.cofID === coffeeID))
} yield (c.name, s.name)
-- edit typo with ====

you need to use ===
def query (coffeID : int) = DBAction { implicit rs =>
val query = for {
c <- coffees
s <- suppliers if (c.supID === s.id) && (c.cofID === coffeeID)
} yield (c.name, s.name)
query.list
}

Related

Programmatic access to SQLModel class attributes

I am trying to plug a SQLModel table onto a dash data table, handling pagination, filtering and page count in the backend, as explained here https://dash.plotly.com/datatable/callbacks
Working code
from sqlmodel import SQLModel
from sqlmodel import select
from sqlmodel import col
from sqlmodel import Session
from typing import Dict
from typing import List
from typing import Tuple
class Foo(SQLModel, table=True):
bara: str
barb: int
filters = {'bara': ('contains ', 'toto'), 'barb': ('>', 1)}
def filter_foos(filters: Dict[str, Tuple[str, str]]):
"""
try to filter foos
"""
query = select(Foo)
if values := filters.get('bara'):
query = query.where(col(Foo.bara).contains(values[1]))
if values := filters.get('barb'):
if values[0] == '>=':
query = query.where(col(Foo.barb) >= values[1])
elif values[0] == '<=':
query = query.where(col(Foo.barb) <= values[1])
elif values[0] == '!=':
query = query.where(col(Foo.barb) != values[1])
elif values[0] == '=':
query = query.where(col(Foo.barb) == values[1])
elif values[0] == '>':
query = query.where(col(Foo.barb) > values[1])
elif values[0] == '<':
query = query.where(col(Foo.barb) < values[1])
return query
def select_relevant_db_lines(
session: Session,
limit: int,
offset: int,
filters: Dict[str, Tuple[str, str]]
) -> List:
"""
Select relevant row lines from Foo.
"""
if limit is not None and offset is not None:
return list(session.exec(filter_foos(filters).offset(offset*limit).limit(limit)))
My issue is that the filter function is awefully ugly, and not modular at all. If I have an new class
class Fooo(SQLModel, table=True):
toto: str
titi: int
tutu: int
I will hand up redoing the same filter_foos boiler plate code
What I would like would be to have a dictionary to access Foo class attributes, something like (pseudo-code, does not wok)
foo_attributes: Dict = {
'bara': Foo.bara
'barb': Foo.barb
}
That way I can dissociate the generic str int datetime and whatnot treatment and then map them on class attributes. Something like (pseudo-code, not working)
def filter_ints(query, model_field: ???, operator: str, value: int):
"""
try to filter ints
"""
if not operator or not value:
return query
if operator == '>=':
query = query.where(col(model_field) >= value)
elif operator == '<=':
query = query.where(col(model_field) <= value)
elif operator == '!=':
query = query.where(col(model_field) != value)
elif operator == '=':
query = query.where(col(model_field) == value)
elif operator == '>':
query = query.where(col(model_field) > value)
elif operator == '<':
query = query.where(col(model_field) < value)
return query
def filter_strs(query, model_field: ???, value: int):
"""
try to filter strs
"""
if not value:
return query
query = query.where(col(model_field).contains(value))
def filter_models(model: Any, filters: Dict[str, Tuple[str, str]]):
"""
try to filter any model
"""
query = select(model)
if not filters:
return query
for key, (operator, value) in filters:
update_query(query, model, key, operator, value)
Is it possible to do such a thing, or will I have to implement one ugly method after another each time I add a new table to show in my dash app?

How set variable with condition with immutable.js

This code in typescript:
const b
if (a == true) {
b = [1]
} else {
b = [2]
}
how to convert above code to immutable.js ?
You have two options:
let b
if (a) {
b = List([1])
} else {
b = List([2])
}
//or
const b = a ? List([1]) : List([2])

Why are these equivalent functions producing a different result?

This is the original method, my intent was to abstract away many of the specifics of the code, to improve readability, by placing the specifics in functions which performed the same action, but with a more readable name.
With this first method I achieve the desired behavior and rows[x] is properly added to lineRows.
def getAllRowsForLine( rows, index ) {
def lineRows = [rows[index]]
def newOperatorNotFound
def x = index + 1
if ( x <= rows.size() - 1 ) {
newOperatorNotFound = true
while ( x <= ( rows.size() - 1 ) && newOperatorNotFound ) {
if ( rows[x].PGM_PROC_OPE.trim() == "" ) {
lineRows << rows[x]
} else if ( rows[x].PGM_PROC_TY == "AN" || rows[x].PGM_PROC_TY == "OR" ) {
lineRows << rows[x]
}
else {
newOperatorNotFound = false
}
x++
}
}
return lineRows
}
Here is the refactored code along with the relative methods for context.
This method is not resulting in the desired behavior, breaking the loop after the first rows[x] is added to lineRows.
def getAllRowsForLine2( rows, index ) {
def lineRows = [rows[index]]
def newOperatorNotFound
def i = index + 1
if ( moreRows( rows, i ) ) {
newOperatorNotFound = true
while ( moreRows( rows, i ) && newOperatorNotFound ) {
if ( operatorEmpty( rows, index ) ) {
lineRows << rows[i]
}
else if ( procTypeAnd( rows, i ) || procTypeOr( rows, i ) ) {
lineRows << rows[i]
} else {
newOperatorNotFound = false
}
i++
}
}
return lineRows
}
def operatorEmpty( rows, index ) {
return rows[index].PGM_PROC_OPE.trim() == ""
}
def procTypeAnd( rows, index ) {
return rows[index].PGM_PROC_TY == "AN"
}
def procTypeOr( rows, index ) {
return rows[index].PGM_PROC_TY == "OR"
}
def moreRows( rows, index ) {
return index <= ( rows.size() - 1 )
}
As far as I can tell these things are equivalent. I ran the below code to attempt testing the equivalency of the functions and it returns true.
println lineProcessor.getAllRowsForLine( rows, 0 ) == lineProcessor.getAllRowsForLine2( rows, 0 )
=> true
Oops, I realized that I had used index in the operatorEmpty function instead of i. If I change index to i the function performs as expected.

Add where clause if not NULL

here is my query:
List<string> kwList = GetFilterKeywords(); // returns NULL none keyword selected
var res = from d in ctx.Books
where (kwList == null || kwList.Contains(d.Name))
select d;
Looks like it is not legit to add where clause if kwList is NULL. So my question is: Is there any way to add more where clauses to the same query in IF/ELSE IF construction?
I mean:
var res = from d in ctx.Books
select d;
if (kwList != null)
{
res.Where(d => kwList.Contains(d.Name);
}
var res = ctx.Books; // no need to write select
if (kwList != null)
res = res.Where(x => kwList.Contains(x.Name));
foreach (d in res) {
...
}
You can use the tertiary operator
var res = kwList == null ? ctx.Books : ctx.Books.Where(x => kwList.Contains(x.Name));
If you want to modify the initial linq query in subsequent case statements, make sure to reassign the initial query to the modified:
var res = ctx.Books;
if (a == b)
{
// reassign here
res = res.Where(x => kwList.Contains(x.Name));
}
else if (a == c)
res = res.Where(x => x.Id == y);

How to return a function in scala

How can I return a function side-effecting lexical closure1 in Scala?
For instance, I was looking at this code sample in Go:
...
// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return b
}
}
...
println(f(), f(), f(), f(), f())
prints
1 2 3 5 8
And I can't figure out how to write the same in Scala.
1. Corrected after Apocalisp comment
Slightly shorter, you don't need the return.
def fib() = {
var a = 0
var b = 1
() => {
val t = a;
a = b
b = t + b
b
}
}
Gah! Mutable variables?!
val fib: Stream[Int] =
1 #:: 1 #:: (fib zip fib.tail map Function.tupled(_+_))
You can return a literal function that gets the nth fib, for example:
val fibAt: Int => Int = fib drop _ head
EDIT: Since you asked for the functional way of "getting a different value each time you call f", here's how you would do that. This uses Scalaz's State monad:
import scalaz._
import Scalaz._
def uncons[A](s: Stream[A]) = (s.tail, s.head)
val f = state(uncons[Int])
The value f is a state transition function. Given a stream, it will return its head, and "mutate" the stream on the side by taking its tail. Note that f is totally oblivious to fib. Here's a REPL session illustrating how this works:
scala> (for { _ <- f; _ <- f; _ <- f; _ <- f; x <- f } yield x)
res29: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1#d53513
scala> (for { _ <- f; _ <- f; _ <- f; x <- f } yield x)
res30: scalaz.State[scala.collection.immutable.Stream[Int],Int] = scalaz.States$$anon$1#1ad0ff8
scala> res29 ! fib
res31: Int = 5
scala> res30 ! fib
res32: Int = 3
Clearly, the value you get out depends on the number of times you call f. But this is all purely functional and therefore modular and composable. For example, we can pass any nonempty Stream, not just fib.
So you see, you can have effects without side-effects.
While we're sharing cool implementations of the fibonacci function that are only tangentially related to the question, here's a memoized version:
val fib: Int => BigInt = {
def fibRec(f: Int => BigInt)(n: Int): BigInt = {
if (n == 0) 1
else if (n == 1) 1
else (f(n-1) + f(n-2))
}
Memoize.Y(fibRec)
}
It uses the memoizing fixed-point combinator implemented as an answer to this question: In Scala 2.8, what type to use to store an in-memory mutable data table?
Incidentally, the implementation of the combinator suggests a slightly more explicit technique for implementing your function side-effecting lexical closure:
def fib(): () => Int = {
var a = 0
var b = 1
def f(): Int = {
val t = a;
a = b
b = t + b
b
}
f
}
Got it!! after some trial and error:
def fib() : () => Int = {
var a = 0
var b = 1
return (()=>{
val t = a;
a = b
b = t + b
b
})
}
Testing:
val f = fib()
println(f(),f(),f(),f())
1 2 3 5 8
You don't need a temp var when using a tuple:
def fib() = {
var t = (1,-1)
() => {
t = (t._1 + t._2, t._1)
t._1
}
}
But in real life you should use Apocalisp's solution.