Rill v0.13 Reference

Standard library · Databases

db/oxisql

Imported as import "db/oxisql" as oxisql, its names are then oxisql.…. Every signature below is the one the checker infers.

Functions

fn sql_connect(host: Str, port: Int) -> Result(Int, Str)

# not run
import "db/oxisql"
fd = sql_connect("127.0.0.1", 7411)?

fn sql_hang_up(fd: Int) -> Unit

# not run
import "db/oxisql"
sql_hang_up(fd)

fn sql_request(fields: List(Field)) -> Json

import "db/oxisql"
sql_request(Cons(Field("sql", JStr("SELECT 1")), Nil))   # => JObj(Cons(Field(engine, JStr(sql)), Cons(Field(cmd, JStr(sql)), Cons(Field(sql, JStr(SELECT 1)), Nil))))

fn sql_cmd(name: Str, fields: List(Field)) -> Json

import "db/oxisql"
sql_cmd("backup", Nil)   # => JObj(Cons(Field(engine, JStr(sql)), Cons(Field(cmd, JStr(backup)), Nil)))

fn sql_prepare(fd: Int, text: Str) -> Result(Int, Str)

# not run
import "db/oxisql"
id = sql_prepare(fd, "SELECT * FROM people WHERE age > ?")?
sql_exec(fd, id, Cons(JInt(30), Nil))
sql_close(fd, id)

fn sql_exec(fd: Int, id: Int, params: List(Json)) -> Result(Json, Str)

# not run
import "db/oxisql"
sql_exec(fd, id, Cons(JInt(30), Nil))   # the prepared statement, with its parameters

fn sql_close(fd: Int, id: Int) -> Result(Json, Str)

# not run
import "db/oxisql"
sql_close(fd, id)

fn sql_run(fd: Int, text: Str) -> Result(Json, Str)

# not run
import "db/oxisql"
sql_run(fd, "SELECT 1; SELECT 2")   # Ok(one result per statement)

fn sql_run_with(fd: Int, text: Str, params: List(Json)) -> Result(Json, Str)

? in the text takes the next value from params, which is how a value reaches the engine without being written into the statement.

# not run
import "db/oxisql"
sql_run_with(fd, "SELECT * FROM people WHERE name = ?", Cons(JStr("ada"), Nil))

fn sql_backup(fd: Int, path: Str) -> Result(Json, Str)

Admin-only, and gated as such before the request reaches the engine.

# not run
import "db/oxisql"
sql_backup(fd, "/backups/today.tar")

fn sql_restore(fd: Int, archive: Str, target: Str) -> Result(Json, Str)

# not run
import "db/oxisql"
sql_restore(fd, "/backups/today.tar", "/data")

fn sql_results(answer: Json) -> List(Json)

One result per statement sent.

import "db/oxisql"
len(sql_results(JArr(Cons(JObj(Nil), Cons(JObj(Nil), Nil)))))   # => 2

fn sql_first(answer: Json) -> Json

The common case is one statement, and a caller that sent one should not have to say so twice.

import "db/oxisql"
sql_first(JArr(Cons(JObj(Cons(Field("affected", JInt(1)), Nil)), Nil)))   # => JObj(Cons(Field(affected, JInt(1)), Nil))
sql_first(JArr(Nil))                                                        # => JNull

fn sql_columns(result: Json) -> List(Str)

import "db/oxisql"
sql_columns(JObj(Cons(Field("columns", JArr(Cons(JStr("name"), Cons(JStr("age"), Nil)))), Nil)))   # => Cons(name, Cons(age, Nil))

fn sql_types(result: Json) -> List(Str)

A column's declared type — INT, TEXT, DOUBLE — or the empty string where the engine had none to give, as for a bare NULL in a select list.

import "db/oxisql"
sql_types(JObj(Cons(Field("types", JArr(Cons(JStr("TEXT"), Nil))), Nil)))   # => Cons(TEXT, Nil)

fn sql_rows(result: Json) -> List(Json)

import "db/oxisql"
sql_rows(JObj(Cons(Field("rows", JArr(Cons(JArr(Cons(JInt(1), Nil)), Nil))), Nil)))   # => Cons(JArr(Cons(JInt(1), Nil)), Nil)

fn sql_affected(result: Json) -> Int

import "db/oxisql"
sql_affected(JObj(Cons(Field("affected", JInt(2)), Nil)))   # => 2

fn sql_is_ddl(result: Json) -> Bool

import "db/oxisql"
sql_is_ddl(JObj(Cons(Field("ddl", JBool(true)), Nil)))   # => true
sql_is_ddl(JObj(Nil))                                     # => false

fn sql_at(result: Json, name: Str) -> Int

Where a named column sits in every row of this result, or -1. Worth holding on to across a loop rather than asking per row.

import "db/oxisql"
r = JObj(Cons(Field("columns", JArr(Cons(JStr("name"), Cons(JStr("age"), Nil)))), Nil))
sql_at(r, "age")    # => 1
sql_at(r, "nope")   # => -1

fn sql_cell(row: Json, i: Int) -> Json

import "db/oxisql"
sql_cell(JArr(Cons(JStr("ada"), Cons(JInt(36), Nil))), 1)   # => JInt(36)
sql_cell(JArr(Nil), -1)                                   # => JNull

fn sql_value(result: Json, row: Json, name: Str) -> Json

The value of a named column in one row. Fine for a handful; for a table use sql_at once and sql_cell per row.

import "db/oxisql"
r = JObj(Cons(Field("columns", JArr(Cons(JStr("name"), Cons(JStr("age"), Nil)))), Nil))
sql_value(r, JArr(Cons(JStr("ada"), Cons(JInt(36), Nil))), "name")   # => JStr(ada)