Slide 33 of 37

SQL

type User { id: Int, name: Str }

query findUser(name: Str): User[dyn] {
	SELECT id, name FROM users WHERE name = {name}
}

proc main(): void {
	pooled := hive.sql.pool(hive.sql.DatabaseDriver.SQLite(), "file::memory:?cache=shared", 1, 1)
	if pooled is Result.Ok(db) {
		using db run raw "CREATE TABLE users (id INTEGER, name TEXT)"
		using db run raw "INSERT INTO users (id, name) VALUES (1, 'ada')"

		found := using db run findUser("ada")
		if found is Result.Ok(users) {
			echo users
		}
		hive.sql.close(db)
	} else if pooled is Result.Error(err) {
		echo "could not open the database: {err.message}"
	}
}
A query declaration is a func whose body is inline SQL and whose return type describes its rows. Columns are matched to fields by name, not position, so reordering a SELECT can never silently remap them, and values are always bound as parameters — never spliced into the text — so nothing a caller supplies can change what the statement means. connect opens a single connection and pool a whole pool of them, both answering with a Result<SqlConnection, SqlError>; close lets one go. SQL assembled at run time, rather than declared as a query, goes through run raw instead — untyped by construction, and easy to grep for.