How to use Sqlite.Callback in Genie - sqlite

While trying to solve the question How to print a sqlite table content with genie programming language I found out that I could try to call PrintSingleRecipe as a callback from Database.exec. However, it seems that a callback cannot be a regular function, they have some property that I do not seem to find over in the internets.
I am calling it in this way:
else if response is "3" //Show a Recipe
res:string = UserInterface.raw_input("Select a recipe -> ")
sql:string = "SELECT * FROM Recipes WHERE pkID = %res"
db.exec(sql, PrintSingleRecipe, null)
And the function itself looks like:
def PrintSingleRecipe(n_columns:int, values:array of string, column_names:array of string)
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
for i:int = 0 to n_columns
stdout.printf ("%s = %s\n", column_names[i], values[i])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
stdout.printf("%-5s", "%03i" )
However, I get the following error at compilation:
valac --pkg sqlite3 --pkg gee-0.8 cookbook.gs
cookbook.gs:42.26-42.42: error: Argument 2: Cannot convert from `PrintSingleRecipe' to `Sqlite.Callback?'
db.exec(sql, PrintSingleRecipe, null)
^^^^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)
How to properly run the callback in Genie?

The Vala compiler does type checking on a function when a function is passed as a parameter. When a function is used in this way it is called a "delegate". Specifically the Vala compiler will check that the function's signature matches the signature of the delegate type definition. A function's signature is made up of its parameter types and return type. Cannot convert from 'PrintSingleRecipe' to 'Sqlite.Callback?' means the PrintSingleRecipe function's signature doesn't match the Sqlite.Callback delegate definition's signature.
The Sqlite.Callback delegate definition is shown here:
http://valadoc.org/#!api=sqlite3/Sqlite.Callback
You have rightly identified the parameters required are int, array of string, array of string, but you also need to include the return type. In this case it is an int. So your callback should look like:
def PrintSingleRecipe(n_columns:int,
values:array of string,
column_names:array of string
):int
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
for i:int = 0 to n_columns
stdout.printf ("%s = %s\n", column_names[i], values[i])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
stdout.printf("%-5s", "%03i" )
return 0
Returning non-zero will abort the query. See https://www.sqlite.org/capi3ref.html#sqlite3_exec

Related

ELM QueryString parser dont compile

I am really trying to learn a bit of ELM, but my mind collapse at the query parse, my idea was to create a function to get a query string value by name something like: given an query string ?name=Neuber a function like this getParam "name" that would return Neuber
But its failing at most basic example, it doesn't even compile
page comes from here
routeParser comes from here
module Main exposing (..)
-- import Url.Parser exposing (Parser, (</>), (<?>), oneOf, s)
import Url.Parser.Query exposing (int, map, map2, string)
type alias QueryParams =
{ search : Maybe String
, page : Maybe Int
}
routeParser : Url.Parser.Query.Parser QueryParams
routeParser = map2 QueryParams (string "search") (int "page")
page : Url.Parser.Query.Parser Int
page = map (Result.withDefault 1) (int "page")
The error i got
-- TYPE MISMATCH ---------------- /a/long/way/to/project/src/Main.elm
The 2nd argument to `map` is not what I expect:
15| page = map (Result.withDefault 1) (int "page")
^^^^^^^^^^
This `int` call produces:
Url.Parser.Query.Parser (Maybe Int)
But `map` needs the 2nd argument to be:
Url.Parser.Query.Parser (Result x number)
Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!
The immediate problem is that int "page" will return a Maybe Int, but you're trying to use it with Result.withDefault, which, as the error message says, expects a Result. The fix for this is just to use Maybe.withDefault instead.

Is it possible to have a dictionary with a mutable array as the value in Swift

I am trying to do this:
var dictArray = [String:[String]]()
dictArray["test"] = [String]()
dictArray["test"]! += "hello"
But I am getting the weird error NSString is not a subtype of 'DictionaryIndex<String, [(String)]>'.
I just want to be able to add objects to an array inside a dictionary.
Update: Looks like Apple considers this a "known issue" in Swift, implying it will work as expected eventually. From the Xcode 6 Beta 4 release notes:
...Similarly, you cannot modify the underlying value of a mutable
optional value, either conditionally or within a force-unwrap:
tableView.sortDescriptors! += NSSortDescriptor(key: "creditName", ascending: true)
Workaround: Test the optional value explicitly and then assign the
result back:
if let window = NSApplication.sharedApplication.mainWindow {
window.title = "Currently experiencing problems"
}
tableView.sortDescriptors = tableView.sortDescriptors!
You can only do this
var dictArray = [String:[String]]()
dictArray["test"] = [String]()
var arr = dictArray["test"]!;
arr += "hello"
dictArray["test"] = arr
because dictArray["test"] give you Optional<[String]> which is immutable
6> var test : [String]? = [String]()
test: [String]? = 0 values
7> test += "hello"
<REPL>:7:1: error: '[String]?' is not identical to 'UInt8'
append also won't work due to the same reason, Optional is immutable
3> dictArray["test"]!.append("hello")
<REPL>:3:18: error: '(String, [(String)])' does not have a member named 'append'
dictArray["test"]!.append("hello")
^ ~~~~~~
BTW the error message is horrible...
You may use NSMutableArray instead of [String] as a value type for your dictionary:
var dictArray: [String: NSMutableArray] = [:]
dictArray["test"] = NSMutableArray()
dictArray["test"]!.addObject("hello")
This is still an issue in Swift 3. At least I was able to create method that can handle it for you.
func appendOrCreate(newValue: Any, toArrayAt key: String, in existingDictionary: inout [AnyHashable:Any]) {
var mutableArray = [Any]()
if let array = existingDictionary[key] as? [Any]{
//include existing values in mutableArray before adding new value
for existingValue in array {
mutableArray.append(existingValue)
}
}
//append new value
mutableArray.append(newValue)
//save updated array in original dictionary
existingDictionary[key] = mutableArray
}
The problem is that we want class semantics here but have to use structs. If you put class objects into the dictionary, you get what you want!
So, if you have¹ to have mutable values, you can wrap them in a class and perform updates with a closure:
class MutableWrapper<T> {
var rawValue: T
init(_ val: T) {
self.rawValue = val
}
func update(_ with: (inout T) -> Void) {
with(&self.rawValue)
}
}
Example:
func foo() {
var dict = [String: MutableWrapper<[String]>]()
dict["bar"] = MutableWrapper(["rum"])
dict["bar"]?.update({$0.append("gin")})
print(dict["bar"]!.rawValue)
// > ["rum", "gin"]
}
For what it's worth, I do not see a way to keep caller and wrapper in sync. Even if we declare init(_ val: inout T) we will end up with a copy in rawValue.
Performance is not necessarily an issue since the compiler optimizes structs heavily. I'd benchmark any mutable solution against what looks like lots of copy-updates in the code.
Since Swift 4.1 you can provide a default value to the subscript which allows you to solve this quite naturally now:
dictArray["test", default: []].append("hello")

Assign value to optional dictionary in Swift

I'm finding some surprising behavior with optional dictionaries in Swift.
var foo:Dictionary<String, String>?
if (foo == nil) {
foo = ["bar": "baz"]
}
else {
// Following line errors with "'Dictionary<String, String>?' does
// not have a member named 'subscript'"
foo["qux"] = "quux"
}
I've played with this a lot, trying to figure out what I might be missing, but nothing seems to make this code work as expected short of making the dictionary not optional. What am I missing?
The closest I can get is the following, but of course it's ridiculous.
var foo:Dictionary<String, String>?
if (foo == nil) {
foo = ["bar": "baz"]
}
else if var foofoo = foo {
foofoo["qux"] = "quux"
foo = foofoo
}
The lightbulb moment is when you realize that an Optional dictionary is not a Dictionary. An Optional anything is not that thing! It is an Optional!! And that's all it is. Optional is itself a type. An Optional is just an enum, wrapping the possible cases nil and some value. The wrapped value is a completely different object, stored inside.
So an Optional anything does not act like the type of that thing. It is not that thing! It is just an Optional. The only way to get at the thing is to unwrap it.
The same is true of an implicitly unwrapped Optional; the difference is just that the implicitly unwrapped Optional is willing to produce (expose) the wrapped value "automatically". But it is still, in fact, wrapped. And, as Bryan Chen has observed, it is wrapped immutably; the Optional is just holding it for you - it is not giving you a place to play with it.
you can use this code
if var foofoo = foo {
foofoo["qux"] = "quux"
foo = foofoo
} else {
foo = ["bar": "baz"]
}
with this code
var foo:Dictionary<String, String>? = Dictionary()
foo[""]=""
error: 'Dictionary<String, String>?' does not have a member named 'subscript'
foo[""]=""
^
the error message makes sense to me that Dictionary<String, String>? does not implement subscript method, so you need to unwrap it before able to use subscript.
one way to call method on optional is use ! i.e. foo![""], but...
var foo:Dictionary<String, String>? = Dictionary()
foo![""]=""
error: could not find member 'subscript'
foo![""]=""
~~~~~~~~^~~
whereas
var foo:Dictionary<String, String>? = Dictionary()
foo![""]
works
it is interesting these code failed to compile
var foo:Dictionary<String, String>! = Dictionary() // Implicitly unwrapped optional
foo[""]=""
error: could not find an overload for 'subscript' that accepts the supplied arguments
foo[""]=""
~~~~~~~^~~
var foo:Dictionary<String, String>! = Dictionary() // Implicitly unwrapped optional
foo.updateValue("", forKey: "")
immutable value of type 'Dictionary<String, String>' only has mutating members named 'updateValue'
foo.updateValue("", forKey: "")
^ ~~~~~~~~~~~
the last error message is most interesting, it is saying the Dictionary is immutable, so updateValue(forKey:) (mutating method) can't be called on it
so what happened is probably that the Optional<> store the Dictionary as immutable object (with let). So even Optional<> it is mutable, you can't modify the underlying Dictionary object directly (without reassign the Optional object)
and this code works
class MyDict
{
var dict:Dictionary<String, String> = [:]
subscript(s: String) -> String? {
get {
return dict[s]
}
set {
dict[s] = newValue
}
}
}
var foo:MyDict? = MyDict()
foo!["a"] = "b" // this is how to call subscript of optional object
and this lead me to another question, why Array and Dictionary are value type (struct)? opposite to NSArray and NSDictionary which are reference type (class)
This is because your Dictionary is optional. If it's nil, you won't add an entry to it.
You can do this way:
var dict: [String : String]?
if let dict = dict {
dict["key"] = "value" // add a value to an existing dictionary
} else {
dict = ["key" : "value"] // create a dictionary with this value in it
}
Or, if you are given an optional dictionary, for example HTTPHeaders - which in AlamoFire is a [String : String] dictionary - and you want to either add a value if it's non-nil, or create it with this value if it's nil, you could do like so:
let headers: HTTPHeaders? // this is an input parameter in a function for example
var customHeaders: HTTPHeaders = headers ?? [:] // nil coalescing
customHeaders["key"] = "value"
I tried this for Swift 3.1 and it worked:
if (myDict?[key] = value) == nil {
myDict = [key: value]
}

How can I determine end-of-cursor in Rust using sqlite3 Select?

I'm just starting to evaluate Rust. Using Rust and the sqlite3 repo on Github, I'm attempting to determine EOF for a Cursor. I'm not sure how to do that "correctly", I think it may be via the "match" statement.
The 2nd line in the following 2 lines is how I'm currently determining EOF, but this is obviously not the "correct" way:
let oNextResult:sqlite::types::ResultCode = oDbCursor.step();
tDone = (fmt!("%?", oNextResult) == ~"SQLITE_DONE");
The following is the unfinished function containing the above 2 lines. Please excuse the lack of Rust naming-convention, but I will look at implementing that.
/********************
**** Update Data ****
*********************/
fn fUpdateData(oDb1:&sqlite::database::Database, iUpdateMax:int) -> bool {
println(fmt!("Updating %d Rows .......", iUpdateMax));
let sSql:~str = fmt!("Select ikey, sname, iborn, dbal from test LIMIT %d",
iUpdateMax);
let oDbExec = oDb1.exec(sSql);
if oDbExec.is_err() {
println(fmt!("Select Failed! : %?, sql=%s", oDbExec, sSql));
return false;
}
println("Select succeeded. Processing select list .....");
let mut iUpdateCount: int = 0;
let oDbCursor:sqlite::cursor::Cursor = oDb1.prepare(sSql, &None).unwrap();
let mut tDone:bool = false;
while !tDone {
let oNextResult:sqlite::types::ResultCode = oDbCursor.step();
tDone = (fmt!("%?", oNextResult) == ~"SQLITE_DONE");
if !tDone {
let sKey = oDbCursor.get_text(0);
let sName = oDbCursor.get_text(1);
let sBorn = oDbCursor.get_text(2);
let sBal = oDbCursor.get_text(3);
println(fmt!("skey = %s, sname = %s, sBorn = %s, sBal = %s", sKey,
sName, sBorn, sBal));
iUpdateCount += 1;
}
}
println(fmt!("Update succeeded, items updated = %d", iUpdateCount));
return true;
}
I don't know if there is a correct way at the moment but you can also the result codes from the types module:
use sqlite::types::ResultCode;
and then do something like this so there's no need for using fmt!
while cursor.step() == SQLITE_ROW {...}
or this:
while cursor.get_column_count() != 0 {...; cursor.step()}
Function get_column_count returns an int. If there's no data it will return 0. It calls int sqlite3_data_count(sqlite3_stmt *pStmt); under the hood and here's what sqlite docs say about it:
The sqlite3_data_count(P) interface returns the number of columns in
the current row of the result set of prepared statement P. If prepared
statement P does not have results ready to return (via calls to the
sqlite3_column_*() of interfaces) then sqlite3_data_count(P) returns
0. The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. The sqlite3_data_count(P) routine returns 0 if the previous
call to sqlite3_step(P) returned SQLITE_DONE. The
sqlite3_data_count(P) will return non-zero if previous call to
sqlite3_step(P) returned SQLITE_ROW, except in the case of the PRAGMA
incremental_vacuum where it always returns zero since each step of
that multi-step pragma returns 0 columns of data.
As it's mentioned on the readme file rustsqlite interface is not finalized, watch out for changes.

F# Pattern-matching & recursion vs looping & if..then's for parsing nested structures

I'm using a 3rd party vendor's API in F#. On initialization the API returns a C# object that is nested msg container. It is populated with status messages and may include errors message. The vendor provides a C# sample parsing routine which I have ported F#.
The code sample loops through a nested msg container extracting fatal and nonfatal errors, and then return a List of tuples of type BBResponseType * string
Response Enum:
type BBResponseType =
| Status = 0
| Data = 1
| Error = 2
| FatalError = -1
My port to F# looks like this:
member private this.ProcessStatusMsg(eventObj: Blpapi.Event) =
let responseLst = List<(BBResponseType * string)>()
for msg in eventObj do
if msg.MessageType.Equals(SUBSTARTED) then
if msg.GetElement(EXCEPTIONS).NumValues > 0 then // <- check for errors/exceptions
let e = msg.GetElement(EXCEPTIONS)
for i in 0..e.NumValues-1 do
let error = e.GetValueAsElement(i)
let field = error.GetElementAsString(FieldID)
let reason = error.GetElement(REASON)
let message = sprintf "Subscription Started w/errors( Field: %s \n Reason: %s)" field (reason.GetElementAsString(DESCRIPTION))
responseLst.Add(BBResponseType.Error, message)
else
let message = sprintf "Subscription Started"
responseLst.Add(BBResponseType.Status, message)
if msg.MessageType.Equals(SUBSCFAILURE) then // <- check for subscriptions failure
if msg.HasElement(REASON) then
let reason = msg.GetElement(REASON)
let desc = reason.GetElementAsString(DESCRIPTION)
let message = sprintf "Real-time Subscription Failure: %s" desc
responseLst.Add(BBResponseType.FatalError, message)
else
let message = sprintf "Subscription Failure: (reason unknown) "
responseLst.Add(BBResponseType.FatalError, message)
responseLst
After I finished it, I looked at it and thought, "Wow, that's about as non-functional as you can get and still code in F#."
It does seem a lot clearer and succinct than the C# version, but I was thinking that there must be a better way to do all this without using so many loops and if/then's.
How can I do a better job of parsing these nested structures using pattern matching and recursion?
Few pointers:
Instead of returning a List of tuple return a seq of tuple - using the seq { } computation expression for creating sequence.
Extract the if/else parts as a function of type Message -> (BBResponseType * string) and use this function inside the seq expression
Inside this new function (which transforms the Message to tuple) use pattern matching to figure out what kind of (BBResponseType * string) to return.
To complement #Ankur's answer:
member private this.ProcessStatusMsg(eventObj: Blpapi.Event) =
// 0. Define a parameterized active pattern to turn if/else into pattern matching
let (|Element|_|) e msg =
if msg.HasElement(e) then
Some <| msg.GetElement(e)
else None
// 1. Wrapping the whole method body in a sequence expression
seq {
for msg in eventObj do
// 2. Extracting if/else part and using it in sequence expression
match msg.MessageType with
// 3. Using pattern matching to figure out what kind (BBResponseType * string) to return
| SUBSTARTED ->
match msg with
// 4. Use active pattern to pattern match on message directly
| Element EXCEPTIONS e when e.NumValues > 0 ->
for i in 0..e.NumValues-1 do
let error = e.GetValueAsElement(i)
let field = error.GetElementAsString(FieldID)
let reason = error.GetElement(REASON)
let message = sprintf "Subscription Started w/errors( Field: %s \n Reason: %s)" field (reason.GetElementAsString(DESCRIPTION))
yield (BBResponseType.Error, message)
| _ ->
let message = sprintf "Subscription Started"
yield (BBResponseType.Status, message)
| SUBSCFAILURE ->
match msg with
| Element REASON reason ->
let desc = reason.GetElementAsString(DESCRIPTION)
let message = sprintf "Real-time Subscription Failure: %s" desc
yield (BBResponseType.FatalError, message)
| _ ->
let message = sprintf "Subscription Failure: (reason unknown) "
yield (BBResponseType.FatalError, message)
// There are probably more cases, processing them here
| _ -> ()
}
Point 1, 2 and 3 in comments are from the other answer. I added point 0 and 4 to use active patterns for easy pattern matching.

Resources