First attempt to make a package using Todd's composed is a MySQL frob. Using it goes something like:
;me.tmp = $mysql:new(["hostname"->"localhost","username"->"dude","password"->"blah","database"->"ourdb"])
=> ["active" -> 1, "conn" -> #-11, "options" -> ["auto-json" -> "no", "connect_time" -> 1338101382, "convert-types" -> "yes", "database" -> "ourdb", "hostname" -> "localhost", "json-mode" -> "embedded-types", "last_query_time" -> 1338101382, "port" -> "default", "row-type" -> "key-value-pair", "server_version" -> 50158, "username" -> "dude"], "prototype" -> #186]
[used 183 ticks, 0 seconds.]
;me.tmp:query("INSERT INTO ourtable (intValue,stringValue,floatValue,timeValue,MOOValue) VALUES ('%d', '%s', '%f', %t, '%j')",21,"HELLO THERE", 6.66,time(), {"arbitrary", "moo", ["values"->{"are converted into json"}]})
=> "1 rows modified"
The above eval will be converted into the SQL string:
INSERT INTO ourtable (intValue,stringValue,floatValue,timeValue,MOOValue) VALUES ('21', 'HELLO THERE', '6.66', FROM_UNIXTIME(1338101669), '[\"arbitrary\",\"moo\",{\"values\":[\"are converted into json\"]}]')
The subs in :query() mimic sprintf a little bit. Every string in %s will be escaped using mysql_escape_string(), MOO values in %j will be encoded into json. %d values will be tointed(), %f will be tofloated(), etc
Here is an example query using some arbitrary spatial data I have in my DB:
> ;me.tmp:query("SELECT inside,AsText(point),loc,z from coordinates")
=> 3
[used 61 ticks, 0 seconds.]
> ;me.tmp:next()
=> ["AsText(point)" -> "POINT(25 25)", "inside" -> 0, "loc" -> 298, "z" -> 25.0]
[used 47 ticks, 0 seconds.]
> ;me.tmp:next()
=> ["AsText(point)" -> "POINT(0 0)", "inside" -> 0, "loc" -> 298, "z" -> 0.0]
[used 47 ticks, 0 seconds.]
> ;me.tmp:next()
=> ["AsText(point)" -> "POINT(5 5)", "inside" -> 0, "loc" -> 298, "z" -> 5.0]
[used 47 ticks, 0 seconds.]
> ;me.tmp:next()
=> 0
Note: :query returns the number of rows in the result. If your query can returns multiple results, the number returned is the number of rows in the FIRST result. Just call :next() until you get 0 is a safe bet, or use the 'loop_results' or 'list_results' verb. Loop_results puts everything into one dictionary like:
> ;me.tmp:query("SELECT inside,AsText(point),loc,z from coordinates")
=> 3
[used 61 ticks, 0 seconds.]
> ;me.tmp:loop_results()
=> ["AsText(point)" -> {"POINT(25 25)", "POINT(0 0)", "POINT(5 5)"}, "inside" -> {0, 0, 0}, "loc" -> {298, 298, 298}, "z" -> {25.0, 0.0, 5.0}]
[used 292 ticks, 0 seconds.]
list_results just puts each row into a list.
I dunno if this package will even install, actually. But if it doesn't I'll try to fix it.
Obviously you need to use my fork of the stunt server which has MySQL support to utilize this.