How to write isolated function instead of lambda for .filter method - slick

I want to write the content of TableQuery[T].filter method as an isolated function (e.g. .filter(fun)) instead form like .filter(_.id === 3). However when fun is a generic function fun[T], some implicit (conversion?) function is missed and won't pass the compiling.
For example
val s = Some("123")
TableQuery[ Table_Users ].filter(x =>
(if (s.isEmpty) x.device_id.isEmpty else x.device_id === s.get).asInstanceOf[Column[Boolean]])
The code above works, however I want to extract lambda x => (if ...) out to be a function, because it is a little bit long.
Then I have compareNull function
def compareNull[T]( field: Column[Option[T]], value : Option[T])
= (if (value.isEmpty) field.isEmpty else field.get === (value.get)).asInstanceOf[Column[Boolean]]
The code won't compile unless replacing T with another type like String.
I got error value === is not a member of scala.slick.lifted.Column[T].
I guess some implicit functions are missed here. === has an implicit parameter with type OptionMapper2. However I don't know how to fill the "hole".
The table is very simple:
class Table_Users(tag: Tag) extends Table[ Users ]{
def device_id = column[Option[String]]("user_devicde_id",O.Nullable)
def * = (device_id ) <> ( Users.tupled, Users.unapply)
}

Add a second argument list (implicit tt: BaseTypedType[T])

Related

How does groovy's addBatch(map) work for Sql.withBatch?

I'm trying to call groovy.sql.Sql.batch from a statically typed language.
I succeed in calling addBatch on the callback object ps with a parameter of type List. This works well for statements like insert into TABLENAME(a, b, c) values (?, ?, ?).
To cite the documentation:
Named parameters (into maps or domain objects) are also supported:
def updateCounts = sql.withBatch(20, 'insert into TABLENAME(a, b, c) values (:foo, :bar, :baz)') { ps ->
ps.addBatch([foo:10, bar:12, baz:5]) // map
ps.addBatch(foo:7, bar:3, baz:98) // Groovy named args allow outer brackets to be dropped
...
}
So, I thought to also support using batch updates for Maps. The problem is, that the callback parameter of type BatchingPreparedStatementWrapper does not provide a method addBatch(Map), but only overloads addBatch(Object[]), addBatch(List), addBatch(String).
How can Sql.withBatch be used with Map parameters from kotlin or java? And how does it actually work in groovy without throwing NoSuchMethodError, MissingMethodException or whatever?
in groovy following code:
def f(Object[] p){
println p
}
f( a:1, b:2, c:3 )
works fine and prints:
[[a:1, b:2, c:3]]
so, if you have function f(Object[] x), then f(a:123) equals to f( [ [a:123] ] )
this means that from java following should work:
Map params = new HashMap();
params.put("a", 123);
ps.addBatch( new Object[]{ params } );

Python function using If statement

I have created a list of functions and they working fine individually. However other developers have to call these functions individually.
Calling function like this. I would want to simplify more while creating module like user should call using the below line
'type' will be any of the below (mandatory)
a, b, c, d
for each type, relevant function should be called from module
'info' will be input from developer (optional)
'param' will be compulsory list for DBNAME (SQL, ORACLE, TERADATA etc) and optional for rest.
I have created below class for type. However I am unable make proper code to create above functions using IF statement using above types. How might I achieve this?
IIUC. You can use a dict to call the required function.
Ex:
def log_info(info=None):
print('log_info', info)
def log_info_DBCS(info=None):
print('log_info', info)
def log_info_DBName(param, info=None):
print('log_info_DBName', param, info)
def log_info_TableName(info=None):
print('log_info_TableName', info)
def log_info_RecordCount(info=None):
print('log_info_RecordCount', info)
def log_info_Duration(info=None):
print('log_info_Duration', info)
def call_func(func, **kargs):
f = {'log_info': log_info,
'log_info_DBCS': log_info_DBCS,
'log_info_DBName': log_info_DBName,
'log_info_TableName': log_info_TableName,
'log_info_RecordCount': log_info_RecordCount,
'log_info_Duration': log_info_Duration}
return f[func](**kargs)
typ = 'log_info_DBName'
dbname = 'SQL'
call_func(typ, **{"param":dbname})
call_func(typ, **{"param":dbname, 'info': "Hello World"})
First off, I wouldn't name anything type since that is a built-in.
Second, you don't need any if statements; it looks like the only thing that varies is the error string, so you can just stick that into the enum value, and use it as a format string:
from enum import Enum
class LogType(Enum):
Info = "cmd: {}"
DBName = "cmd: Connected to database-({})"
# .. etc.
def log_info(logtype, info):
logger.info(logtype.value.format(info))

Check if string is part of object variables

I want to pass a string to a method/class function which resolves the correct attribute to modify. I'm pretty sure i've done this before, but I seem to have forgotten how to.
class A:
def __init__(self):
self.word = B.getWord()
self.phrase = "Some default string"
def set_dynamically(self, attribute, value):
self[attribute] = value
This would let me do something like A.set_dynamically('word', C.getWord())
I've tried searching for a question and answer for this but I'm having a hard time defining what this is called, so I didn't really find anything.
Python objects have a built-in method called __setattr__(self, name, value) that does this. You can invoke this method by calling setattr() with an object as the argument:
A = A()
setattr(A, 'word', C.getWord())
There's no reason to do this when you could just do something like A.word = C.getWord() (which, in fact, resolves down to calling __setattr__() the same way as the built-in setattr() function does), but if the property you're setting is named dynamically, then this is how you get around that limitation.
If you want to customize the behavior of how your class acts when you try to call setattr() on it (or when you try to set an attribute normally), you can override the __setattr__(self, name, value) method in much the same way as you're overriding __init__(). Be careful if you do this, because it's really easy to accidentally produce an infinite recursion error - to avoid this you can use object.__setattr__(self, name_value) inside your overridden __setattr__(self, name, value).
Just wanted to add my own solution as well. I created a mapping object;
def _mapper(self, attr, object):
m = { "funcA" : object.funcA,
"funcB" : object.funcB,
... : ...,
}
return m.get(attr)
def call_specific_func_(self, attr):
--do stuff--
for a in some-list:
attr = a.get_attr()
retvals = self._mapper(attr, a)
-- etc --

How can I make objects with functions? (Turning a string into a object name)

I've just started learning Python recently and the first project I'm making is a text based adventure game however I've run into a problem. I need a function that makes more objects using the class Goblin that are named after a string.
def spawn(name):
title = name
exec("{0} = {1}".format('title', Goblin))
return title, 'spawn'
Essentially, another function calls this function to create another Goblin (a class) using the input name(a string) as the name of the new Goblin.
What I don't under stand though is that when I run the code(using "bill" as the argument), it gives me this error.
bill = <class '__main__.Goblin'>
^
SyntaxError: invalid syntax
Shouldn't my function be equivalent to:
bill = Goblin
When you do this:
exec("{0} = {1}".format('title', Goblin))
format method converts Goblin class by calling default __str__ method which yields <class '__main__.Goblin'>
Do this instead:
exec("{0} = {1}".format('title', 'Goblin'))
Wait! don't to this, just do:
title = Goblin
as it's strictly equivalent (without any security issues :)).
But that will just alias Goblin class to title. No real interest to all this after all (unless you want to create an instance?: title = Goblin())
With your comment: "I want a Goblin that is named after the string which title represents" I get it: you need
exec("{0} = {1}".format(title, 'Goblin()'))
(no quotes for the first arg so the name you're passing is used, and () on the second to create an instance)
Again: this is really a clumsy way of doing it. What if you want to iterate through all your goblins?
It would be much better to create a dictionary:
goblins_dict = dict()
goblins_dict["my_goblin"] = Goblin()
goblins_dict["my_goblin_2"] = Goblin()
and so on...

Is there a way to call a class method inside an eval?

I'm writing Groovy scripts that are pasted into a web-based system to be run. There is a
class available to scripts run in this environment which I'll call BrokenClass. It has a
bug where it will only accept a string literal as its first parameter, but not a variable
with a string in it. So, this will work (it returns a list):
BrokenClass.reflist('something', 'name')
However, if I try to use a variable as the first parameter I get an error:
list_name = 'something'
BrokenClass.reflist(list_name, 'name')
This produces the message Metadata RefList[something] cannot be accessed.
I don't have any control over BrokenClass (aside from filing a bug on it). I tried to work
around the problem with something like this:
list_name = "foo"
list_call = "BrokenClass.reflist(${list_name}, 'name')"
list_values = Eval.me(list_call)
However, that produces an error:
groovy.lang.MissingPropertyException: No such property: BrokenClass for class: Script1
I tried adding an import to my string, but then I get unable to resolve class BrokenClass.
Is there a way to use BrokenClass inside the eval'd string? Or some other way I haven't
considered to work around the bug in BrokenClass.reflist? A really long switch block
is out, because the possible list names change.
The method signature for BrokenClass.reflist is:
public static List<Object> reflist(String reflistName, String field);
I have a suspicion that BrokenClass.reflist() is directly or indirectly doing an improper String comparison by using the == operator rather than String.equals(). See this article for an explanation of the difference.
The problem
Here's a demonstration of the problem:
def a = 'whatever'
def b = 'what' + 'ever'
assert doSomething('whatever') == 'OK'
assert doSomething(a) == 'OK'
assert doSomething(b) == 'ERROR'
def doSomething(String value) {
if(value.is('whatever')) { // In Java this would be: value == "whatever"
'OK'
} else {
'ERROR'
}
}
Because it's using reference equality, which in Groovy is done by the Object.is(Object) method, BrokenClass.reflist() was inadvertently coded to work only with String literals: all String literals with the same value refer to the same String instance, resulting in an evaluation of True. A String composed at run time with the same value of a literal does not refer to the same String instance.
Work around
Obviously BrokenClass.reflist() should be fixed. But you can work around the problem by using an interned String.
def b = 'what' + 'ever'
assert doSomething(b.intern()) == 'OK'
def doSomething(String value) {
if(value.is('whatever')) {
'OK'
} else {
'ERROR'
}
}
If the variable's value matches that of a String literal, then variable.intern() will return the same String instance as the matching literal. This would allow the Java == operator to work as you need it to.

Resources