Skip to content

Commit

Permalink
chore: Move glibsql to glibsql/http for organization
Browse files Browse the repository at this point in the history
  • Loading branch information
custompro98 committed Jul 11, 2024
1 parent 8d5a681 commit 6aba493
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 179 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

Glibsql is a library for interacting with a hosted libSQL database such as [Turso](https://turso.tech).

Glibsql helps construct a `gleam/http/request` for use with the [Hrana over HTTP](https://docs.turso.tech/sdk/http/reference) variant of libSQL,
## glibsql/http

`glibsql/http` helps construct a `gleam/http/request` for use with the [Hrana over HTTP](https://docs.turso.tech/sdk/http/reference) variant of libSQL,
simply pass the constructed HTTP request into your http client of choice.

```sh
Expand All @@ -14,7 +16,7 @@ gleam add glibsql
```gleam
import gleam/httpc
import gleam/result
import glibsql
import glibsql/http as glibsql
pub fn main() {
// The first request does not have to include a `CloseStatement`,
Expand Down Expand Up @@ -52,7 +54,7 @@ pub fn main() {
}
fn base_request() {
glibsql.new_http_request()
glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "glibsql"
version = "0.2.0"
version = "0.3.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
Expand Down
52 changes: 26 additions & 26 deletions src/glibsql.gleam → src/glibsql/http.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ pub type Statement {
CloseStatement
}

/// HttpRequest encapsulates everything needed to execute
/// Request encapsulates everything needed to execute
/// a Hrana over HTTP libSQL request.
///
/// see `new_http_request()` to construct this record.
pub opaque type HttpRequest {
HttpRequest(
/// see `new_request()` to construct this record.
pub opaque type Request {
Request(
database: String,
organization: String,
host: String,
Expand All @@ -45,8 +45,8 @@ pub opaque type HttpRequest {
/// Create a new Hrana over HTTP libSQL request.
///
/// Uses the builder pattern to construct everything necessary to send a request.
pub fn new_http_request() -> HttpRequest {
HttpRequest(
pub fn new_request() -> Request {
Request(
database: "",
organization: "",
host: "turso.io",
Expand All @@ -62,8 +62,8 @@ pub fn new_http_request() -> HttpRequest {
///
/// Given a Turso databse URL like libsql://example-database-myorganization.turso.io
/// The database name is "example-database"
pub fn with_database(request: HttpRequest, database: String) -> HttpRequest {
HttpRequest(..request, database: database)
pub fn with_database(request: Request, database: String) -> Request {
Request(..request, database: database)
}

/// Set the target database organization.
Expand All @@ -72,10 +72,10 @@ pub fn with_database(request: HttpRequest, database: String) -> HttpRequest {
/// Given a Turso databse URL like libsql://example-database-myorganization.turso.io
/// The database name is "myorganization"
pub fn with_organization(
request: HttpRequest,
request: Request,
organization: String,
) -> HttpRequest {
HttpRequest(..request, organization: organization)
) -> Request {
Request(..request, organization: organization)
}

/// Set the target database host.
Expand All @@ -84,43 +84,43 @@ pub fn with_organization(
///
/// Given a Turso databse URL like libsql://example-database-myorganization.turso.io
/// The host name is "turso.io"
pub fn with_host(request: HttpRequest, host: String) -> HttpRequest {
HttpRequest(..request, host: host)
pub fn with_host(request: Request, host: String) -> Request {
Request(..request, host: host)
}

/// Set the target database path on the host.
/// NOTE: this defaults to Turso's /v2/pipeline
/// Calling this function multiple times will override the previous value.
pub fn with_path(request: HttpRequest, path: String) -> HttpRequest {
HttpRequest(..request, path: path)
pub fn with_path(request: Request, path: String) -> Request {
Request(..request, path: path)
}

/// Set the Bearer token to access the database. Do not include `Bearer `.
/// Calling this function multiple times will override the previous value.
pub fn with_token(request: HttpRequest, token: String) -> HttpRequest {
HttpRequest(..request, token: token)
pub fn with_token(request: Request, token: String) -> Request {
Request(..request, token: token)
}

/// Set a statement on the request.
/// This function may be called multiple times, additional statements will be
/// executed in order.
pub fn with_statement(request: HttpRequest, statement: Statement) -> HttpRequest {
HttpRequest(..request, statements: [statement, ..request.statements])
pub fn with_statement(request: Request, statement: Statement) -> Request {
Request(..request, statements: [statement, ..request.statements])
}

/// Clear all statements from the request.
pub fn clear_statements(request: HttpRequest) -> HttpRequest {
HttpRequest(..request, statements: [])
pub fn clear_statements(request: Request) -> Request {
Request(..request, statements: [])
}

/// Set the baton from a previous connection to be reused.
pub fn with_baton(request: HttpRequest, baton: String) -> HttpRequest {
HttpRequest(..request, baton: Some(baton))
pub fn with_baton(request: Request, baton: String) -> Request {
Request(..request, baton: Some(baton))
}

/// Build the request using the previously provided values.
/// Returns a gleam/http request suitable to be used in your HTTP client of choice.
pub fn build(request: HttpRequest) -> http_request.Request(String) {
pub fn build(request: Request) -> http_request.Request(String) {
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
Expand All @@ -134,11 +134,11 @@ pub fn build(request: HttpRequest) -> http_request.Request(String) {
)
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.2.0")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body(build_json(request))
}

fn build_json(req: HttpRequest) {
fn build_json(req: Request) {
let statements =
list.reverse(req.statements)
|> list.map(fn(stmt) {
Expand Down
149 changes: 149 additions & 0 deletions test/glibsql/http_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import gleam/http
import gleam/http/request as http_request
import gleeunit/should
import glibsql/http as glibsql

pub fn builder_custom_host_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.example.com")
|> http_request.set_path("/v1/acme")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body("{\"baton\":null,\"requests\":[]}")

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_host("example.com")
|> glibsql.with_path("/v1/acme")
|> glibsql.with_token("token")
|> glibsql.build
|> should.equal(expected)
}

pub fn builder_no_statements_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.turso.io")
|> http_request.set_path("/v2/pipeline")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body("{\"baton\":null,\"requests\":[]}")

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
|> glibsql.build
|> should.equal(expected)
}

pub fn builder_single_statement_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.turso.io")
|> http_request.set_path("/v2/pipeline")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body(
"{\"baton\":null,\"requests\":[{\"type\":\"execute\",\"stmt\":{\"sql\":\"SELECT * FROM users\"}},{\"type\":\"close\"}]}",
)

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
|> glibsql.with_statement(glibsql.ExecuteStatement(sql: "SELECT * FROM users"))
|> glibsql.with_statement(glibsql.CloseStatement)
|> glibsql.build
|> should.equal(expected)
}

pub fn builder_many_statement_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.turso.io")
|> http_request.set_path("/v2/pipeline")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body(
"{\"baton\":null,\"requests\":[{\"type\":\"execute\",\"stmt\":{\"sql\":\"SELECT * FROM users\"}},{\"type\":\"execute\",\"stmt\":{\"sql\":\"SELECT * FROM posts\"}},{\"type\":\"close\"}]}",
)

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
|> glibsql.with_statement(glibsql.ExecuteStatement(sql: "SELECT * FROM users"))
|> glibsql.with_statement(glibsql.ExecuteStatement(sql: "SELECT * FROM posts"))
|> glibsql.with_statement(glibsql.CloseStatement)
|> glibsql.build
|> should.equal(expected)
}

pub fn builder_clear_statements_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.turso.io")
|> http_request.set_path("/v2/pipeline")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body("{\"baton\":null,\"requests\":[]}")

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
|> glibsql.with_statement(glibsql.ExecuteStatement(sql: "SELECT * FROM users"))
|> glibsql.with_statement(glibsql.ExecuteStatement(sql: "SELECT * FROM posts"))
|> glibsql.with_statement(glibsql.CloseStatement)
|> glibsql.clear_statements
|> glibsql.build
|> should.equal(expected)
}

pub fn builder_baton_test() {
let expected =
http_request.new()
|> http_request.set_method(http.Post)
|> http_request.set_scheme(http.Https)
|> http_request.set_host("database-organization.turso.io")
|> http_request.set_path("/v2/pipeline")
|> http_request.set_header("Authorization", "Bearer token")
|> http_request.set_header("Content-Type", "application/json")
|> http_request.set_header("Accept", "application/json")
|> http_request.set_header("User-Agent", "glibsql/0.3.0")
|> http_request.set_body(
"{\"baton\":\"baton\",\"requests\":[{\"type\":\"close\"}]}",
)

glibsql.new_request()
|> glibsql.with_database("database")
|> glibsql.with_organization("organization")
|> glibsql.with_token("token")
|> glibsql.with_statement(glibsql.CloseStatement)
|> glibsql.with_baton("baton")
|> glibsql.build
|> should.equal(expected)
}
Loading

0 comments on commit 6aba493

Please sign in to comment.