Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kerams/fable.sqljs
Fable bindings for sql.js
https://github.com/kerams/fable.sqljs
fable fable-bindings fsharp sql sqlite
Last synced: 15 days ago
JSON representation
Fable bindings for sql.js
- Host: GitHub
- URL: https://github.com/kerams/fable.sqljs
- Owner: kerams
- License: mit
- Created: 2022-09-12T13:53:12.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2022-10-08T09:05:02.000Z (about 2 years ago)
- Last Synced: 2024-10-12T13:39:27.056Z (about 1 month ago)
- Topics: fable, fable-bindings, fsharp, sql, sqlite
- Language: F#
- Homepage:
- Size: 9.77 KB
- Stars: 11
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Fable.SqlJs
Fable bindings for the SQLite library in JS [sql.js](https://github.com/sql-js/sql.js) ([NPM package](https://www.npmjs.com/package/sql.js)) version ^1.8.0. Web worker bits are not covered.
## Nuget package
[![Nuget](https://img.shields.io/nuget/v/Fable.SqlJs.svg?colorB=green)](https://www.nuget.org/packages/Fable.SqlJs)## Installation with [Femto](https://github.com/Zaid-Ajaj/Femto)
```
femto install Fable.SqlJs
```## Standard installation
Nuget package
```
paket add Fable.SqlJs -p YourProject.fsproj
```NPM package
```
npm install [email protected]
```## Usage
The sql.js library consists of a JS part and a WebAssembly part. Both need to be distributed with your application. If you're using Webpack 5, calling `initSqlJsWebpack5` should do most of the work. Otherwise you will use `initSqlJs` and point the library to the `sql-wasm.wasm` file.
```fsharp
open Fable.SqlJs
open Fable.Core.JsInterop
open Fable.Core// Type annotation for `x` is required, otherwise we would get wrong type matches.
let valueToString (x: SqlValue option) =
match x with
| None -> "null" // null values
| Some (U3.Case1 x) -> x.ToString () // numbers
| Some (U3.Case3 x) -> $"[{x}]" // binary data
| Some (U3.Case2 x) -> x // strings// Load the WASM file locally in Webpack 5. It will be automatically copied by Webpack as an asset.
// You might also have to add the following to module.exports in the Webpack config file:
//
// resolve: {
// fallback: {
// "crypto": false,
// "fs": false,
// "path": false
// }
// },
let sqlJs = initSqlJsWebpack5 ()// Load the WASM file from /sql-wasm.wasm. You will need to make sure to deploy this file to the web server.
//let db = initSqlJs (jsOptions(fun x -> x.locateFile <- fun f -> f))
// or
//let db = initSqlJs JS.undefined// Load the WASM file from a CDN. Make sure to reference the matching version.
//let db = initSqlJs (jsOptions(fun x -> x.locateFile <- fun f -> $"https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/{f}"))// Do stuff once the initialization promise resolves. In an Elmish application you will typically want to pass `sqlJs` to `Cmd.OfPromise.either`.
sqlJs.``then``(fun x ->
// Create an empty database. To open an existing one, pass in the byte array as the parameter instead.
let db = x.CreateDatabase ()// Execute a command, discarding any return values.
db.run "CREATE TABLE thing(id integer, name text, picture binary)"// Execute a command, discarding any return values.
// Parameters are passed in in an array and are applied positionally.
// !^ applies erased casts to make parameter passing a bit easier since the JS API is very dynamic.
db.run ("INSERT INTO thing VALUES (1, $name1, null), ($id2, 'car', null), (3, $name3, $picture3)", !^[| !^"ball"; !^2.; !!null; !^[| 222uy; 223uy |] |])
// Execute 2 commands, which will gives us an array with 2 elements with the rows returned by each command.
// This time we have decided to pass the parameters in as a JS object, which we are constructing using an anonymous record.
// Now the parameters are matched by name, not positionally.
let resultSets = db.exec ("SELECT sqlite_version(); SELECT id, picture, name FROM thing WHERE id > $id", !^{| ``$id`` = 1 |})// Print the DB version using the first column in the first row of the first result set.
printfn $"SQLite version: {resultSets.[0].values.[0].[0]}"// Iterate over the second result set, printing the values in each row.
// The order of values in the `columns` and `values` matches, and is the same as the order in the SELECT clause.
for columnValuesInRow in resultSets.[1].values do
for i, column in Array.indexed resultSets.[1].columns do
printfn $"{column}: {valueToString columnValuesInRow.[i]}"printfn ""
// Export (back up) the database as a byte array to store it somewhere.
let dbData = db.export ()// Close the database when done to free the resources.
db.close ()
) |> ignore
```The following should be printed in the console.
![vivaldi_jJ4eBFBBPo](https://user-images.githubusercontent.com/5063478/189690952-e5ce4f67-c8aa-40d9-88ff-a7e3fce355e0.png)