Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
VioletBuse committed Jun 26, 2024
0 parents commit d113ff4
Show file tree
Hide file tree
Showing 9 changed files with 670 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: test

on:
push:
branches:
- master
- main
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.2.1"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam deps download
- run: gleam test
- run: gleam format --check src test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
/build
erl_crash.dump
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# feather

[![Package Version](https://img.shields.io/hexpm/v/feather)](https://hex.pm/packages/feather)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/feather/)

```sh
gleam add feather
```
Add the following fields to your gleam.toml file:

```toml
# this can of course be anything you like
migrations_dir = "./priv/migrations"
schemafile = "./schema.sql"
```

Then run the command `gleam run -m feather -- new "Initial schema migration"` and make any changes you like.

Running the command `gleam run -m feather -- schema` will create the file ./schema.sql, (or whatever you set in your gleam.toml) with the schema of your database after all migrations have been applied.

```gleam
import feather
import gleam/result
import gleam/erlang
import sqlight
pub fn main() {
let assert Ok(priv_dir) = erlang.priv_directory("my_module_name")
use migrations <- result.try(feather.get_migrations(priv_dir <> "/migrations"))
use connection <- feather.connect(feather.Config(..feather.default_config(), file: "./database.db"))
feather.migrate(migrations, on: connection)
}
```

Further documentation can be found at <https://hexdocs.pm/feather>.

## Development

```sh
gleam run # Run the project
gleam test # Run the tests
gleam shell # Run an Erlang shell
```
28 changes: 28 additions & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name = "feather"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
description = "A companion library to sqlight"
licences = ["Apache-2.0"]
repository = { type = "github", user = "VioletBuse", repo = "feather" }
# links = [{ title = "Website", href = "https://gleam.run" }]
#
# For a full reference of all the available options, you can have a look at
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
sqlight = ">= 0.9.0 and < 1.0.0"
simplifile = ">= 2.0.0 and < 3.0.0"
filepath = ">= 1.0.0 and < 2.0.0"
justin = ">= 1.0.1 and < 2.0.0"
gloml = ">= 0.1.3 and < 1.0.0"
argv = ">= 1.0.2 and < 2.0.0"
gleam_erlang = ">= 0.25.0 and < 1.0.0"
puddle = ">= 0.5.0 and < 1.0.0"
gleam_otp = ">= 0.10.0 and < 1.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
31 changes: 31 additions & 0 deletions manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
{ name = "esqlite", version = "0.8.8", build_tools = ["rebar3"], requirements = [], otp_app = "esqlite", source = "hex", outer_checksum = "374902457C7D94DC9409C98D3BDD1CA0D50A60DC9F3BDF1FD8EB74C0DCDF02D6" },
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
{ name = "gleam_stdlib", version = "0.38.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "663CF11861179AF415A625307447775C09404E752FF99A24E2057C835319F1BE" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
{ name = "gloml", version = "0.1.3", build_tools = ["gleam"], requirements = ["gleam_stdlib", "toml"], otp_app = "gloml", source = "hex", outer_checksum = "D70229ACD487010B2D1CB57FFCCB0D2BB38CEC885DC9688D51D1020A579AC057" },
{ name = "justin", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "justin", source = "hex", outer_checksum = "7FA0C6DB78640C6DC5FBFD59BF3456009F3F8B485BF6825E97E1EB44E9A1E2CD" },
{ name = "puddle", version = "0.5.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "puddle", source = "hex", outer_checksum = "1D199F61CAB692DA84CE8153C9351DC21C68C62BCE75782AFAAD5EE780144806" },
{ name = "simplifile", version = "2.0.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "95219227A43FCFE62C6E494F413A1D56FF953B68FE420698612E3D89A1EFE029" },
{ name = "sqlight", version = "0.9.0", build_tools = ["gleam"], requirements = ["esqlite", "gleam_stdlib"], otp_app = "sqlight", source = "hex", outer_checksum = "2D9C9BA420A5E7DCE7DB2DAAE4CAB0BE6218BEB48FD1531C583550B3D1316E94" },
{ name = "toml", version = "0.7.0", build_tools = ["mix"], requirements = [], otp_app = "toml", source = "hex", outer_checksum = "0690246A2478C1DEFD100B0C9B89B4EA280A22BE9A7B313A8A058A2408A2FA70" },
]

[requirements]
argv = { version = ">= 1.0.2 and < 2.0.0" }
filepath = { version = ">= 1.0.0 and < 2.0.0" }
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0" }
gleam_otp = { version = ">= 0.10.0 and < 1.0.0"}
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
gloml = { version = ">= 0.1.3 and < 1.0.0" }
justin = { version = ">= 1.0.1 and < 2.0.0" }
puddle = { version = ">= 0.5.0 and < 1.0.0" }
simplifile = { version = ">= 2.0.0 and < 3.0.0" }
sqlight = { version = ">= 0.9.0 and < 1.0.0" }
124 changes: 124 additions & 0 deletions src/feather.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import feather/migrate
import gleam/int
import gleam/option.{type Option, None}
import gleam/result
import sqlight.{type Connection, type Error}

/// Runs the feather cli to generate new migrations and dump the schema
/// you probably don't wanna run this yourself...
/// run `gleam run -m feather` to find out more
pub fn main() {
migrate.main()
}

pub type JournalMode {
JournalDelete
JournalTruncate
JournalPersist
JournalMemory
JournalWal
JournalOff
}

pub type SyncMode {
SyncExtra
SyncFull
SyncNormal
SyncOff
}

pub type TempStore {
TempStoreDefault
TempStoreFile
TempStoreMemory
}

pub type Config {
Config(
file: String,
journal_mode: JournalMode,
synchronous: SyncMode,
temp_store: TempStore,
mmap_size: Option(Int),
page_size: Option(Int),
)
}

pub fn default_config() -> Config {
Config(
"./sqlite.db",
journal_mode: JournalWal,
synchronous: SyncNormal,
temp_store: TempStoreMemory,
mmap_size: None,
page_size: None,
)
}

pub fn connect(config: Config) -> Result(Connection, Error) {
use connection <- result.try(sqlight.open(config.file))

let journal_mode = case config.journal_mode {
JournalOff -> "OFF"
JournalWal -> "WAL"
JournalDelete -> "DELETE"
JournalMemory -> "MEMORY"
JournalTruncate -> "TRUNCATE"
JournalPersist -> "PERSIST"
}

let sync = case config.synchronous {
SyncOff -> "OFF"
SyncFull -> "FULL"
SyncExtra -> "EXTRA"
SyncNormal -> "NORMAL"
}

let temp_store = case config.temp_store {
TempStoreFile -> "FILE"
TempStoreMemory -> "MEMORY"
TempStoreDefault -> "DEFAULT"
}

use _ <- result.try(sqlight.exec(
"PRAGMA journal_mode = " <> journal_mode <> ";",
connection,
))
use _ <- result.try(sqlight.exec(
"PRAGMA synchronous = " <> sync <> ";",
connection,
))
use _ <- result.try(sqlight.exec(
"PRAGMA temp_store = " <> temp_store <> ";",
connection,
))
use _ <- result.try(
option.map(config.mmap_size, int.to_string)
|> option.map(fn(size) {
sqlight.exec("PRAGMA mmap_size = " <> size <> ";", connection)
})
|> option.unwrap(Ok(Nil)),
)

use _ <- result.try(
option.map(config.page_size, int.to_string)
|> option.map(fn(size) {
sqlight.exec("PRAGMA page_size = " <> size <> ";", connection)
})
|> option.unwrap(Ok(Nil)),
)

Ok(connection)
}

/// runs "PRAGMA optimize;" before closing the connection.
/// If the connections are long-lived, then consider running
/// this periodically anyways.
pub fn disconnect(connection: Connection) {
let _ = sqlight.exec("PRAGMA optimize;", connection)
sqlight.close(connection)
}

pub fn optimize(connection: Connection) {
sqlight.exec("PRAGMA optimize;", connection)
}
Loading

0 comments on commit d113ff4

Please sign in to comment.