Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/light-parents-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"rescript-bun": patch
---

Improve Sqlite bindings
18 changes: 9 additions & 9 deletions src/BunSqlite.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,33 @@ module Statement = {

/** Runs a query and returns an array of JSON objects for the results. */
@send
external all: (t, {..}) => array<JSON.t> = "all"
external all: (t, ~params: {..}=?) => array<JSON.t> = "all"

/** Runs a query and returns raw JSON for the results. */
@send
external allJson: (t, {..}) => JSON.t = "all"
external allJson: (t, ~params: {..}=?) => JSON.t = "all"

/** Runs a query and returns raw JSON, using a dictionary for the parameters to make it easy to assemble parameters dynamically. */
@send
external allDictJson: (t, Dict.t<JSON.t>) => JSON.t = "all"

/** Runs a query and returns a JSON object for the results. */
@send
external get: (t, {..}) => Nullable.t<JSON.t> = "get"
external get: (t, ~params: {..}=?) => Nullable.t<JSON.t> = "get"

/** Runs a query and returns a JSON object for the results, using a dictionary for the parameters to make it easy to assemble parameters dynamically. */
@send
external getDict: (t, Dict.t<JSON.t>) => Nullable.t<JSON.t> = "get"

type runResult = {lastInsertRowid: int, changes: int}

/** Runs a query, expecting no results. */
@send
external run: (t, {..}) => unit = "run"
external run: (t, ~params: {..}=?) => runResult = "run"

/** Runs a query and returns an iterator over the results as raw JSON. */
@send
external iterate: (t, {..}) => Iterator.t<JSON.t> = "iterate"
external iterate: (t, ~params: {..}=?) => Iterator.t<JSON.t> = "iterate"

/** Destroys the statement, freeing up resources. */
@send
Expand All @@ -44,8 +46,7 @@ module Database = {
type dbOptions = {readonly?: bool, create?: bool, strict?: bool}

/** Creates a new database. */
@module("bun:sqlite")
@new
@module("bun:sqlite") @new
external make: (string, ~options: dbOptions=?) => t = "Database"

/**
Expand All @@ -57,8 +58,7 @@ module Database = {
let db = Database.makeInMemory()
```
*/
@module("bun:sqlite")
@new
@module("bun:sqlite") @new
external makeInMemory: (@as(":memory:") _, ~options: dbOptions=?) => t = "Database"

/**
Expand Down
37 changes: 37 additions & 0 deletions test/BunSqlite.test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions test/BunSqlite.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
open Test

describe("BunSqlite", () => {
test("basic commands work", () => {
open BunSqlite
let db = Database.makeInMemory()

let resOne = db->Database.query("SELECT 1")->Statement.all
expect(resOne)->Expect.toEqual([
JSON.Object(
dict{
"1": JSON.Number((1 :> float)),
},
),
])

db
->Database.query("
CREATE TABLE IF NOT EXISTS pokemon (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
);
")
->Statement.run
->ignore

let insertResult =
db
->Database.query("INSERT INTO pokemon (name) VALUES (@name)")
->Statement.run(
~params={
"@name": "Pikachu",
},
)

expect(insertResult.lastInsertRowid)->Expect.toBe(1)
expect(insertResult.changes)->Expect.toBe(1)

db
->Database.query("INSERT INTO pokemon (name) VALUES (@name)")
->Statement.run(
~params={
"@name": "Raichu",
},
)
->ignore

let allPokemons = db->Database.query("SELECT * FROM pokemon ORDER BY id")->Statement.all
expect(allPokemons)->Expect.toEqual([
JSON.Object(
dict{
"id": JSON.Number((1 :> float)),
"name": JSON.String("Pikachu"),
},
),
JSON.Object(
dict{
"id": JSON.Number((2 :> float)),
"name": JSON.String("Raichu"),
},
),
])

db->Database.close
})
})