From 76dc688483d3782292c5927c21d4dcc61625efbf Mon Sep 17 00:00:00 2001 From: inoas Date: Tue, 23 Jul 2024 19:58:40 +0200 Subject: [PATCH] fragment demo --- README.md | 43 +++++++-------- docs/demo-apps/README.md | 3 ++ .../.gitignore | 0 .../.tool-versions | 0 .../README.md | 2 +- .../gleam.toml | 0 .../manifest.toml | 0 .../src/cake_demo_select_and_decode.gleam | 0 .../src/cat.gleam | 0 .../.gitignore | 0 .../.tool-versions | 0 .../README.md | 2 +- .../gleam.toml | 0 .../manifest.toml | 0 .../src/being.gleam | 0 .../src/cake_demo_union_and_decode.gleam | 0 .../{03_demo_insert => 03_insert}/.gitignore | 0 .../.tool-versions | 0 .../{03_demo_insert => 03_insert}/README.md | 2 +- .../{03_demo_insert => 03_insert}/gleam.toml | 0 .../manifest.toml | 0 .../src/cake_demo_insert.gleam | 23 +++----- .../{04_demo_delete => 04_delete}/.gitignore | 0 .../.tool-versions | 0 .../{04_demo_delete => 04_delete}/README.md | 2 +- .../{04_demo_delete => 04_delete}/gleam.toml | 0 .../manifest.toml | 0 .../src/cake_demo_delete.gleam | 0 .../{05_demo_update => 05_update}/.gitignore | 0 .../.tool-versions | 0 docs/demo-apps/demos/05_update/README.md | 19 +++++++ .../{05_demo_update => 05_update}/gleam.toml | 0 .../manifest.toml | 0 .../src/cake_demo_update.gleam | 0 .../.gitignore | 0 .../.tool-versions | 0 .../README.md | 2 +- .../gleam.toml | 2 +- .../manifest.toml | 0 ...cake_demo_insert_on_conflict_update.gleam} | 1 - .../demo-apps/demos/07_select_join/.gitignore | 4 ++ .../demos/07_select_join/.tool-versions | 5 ++ docs/demo-apps/demos/07_select_join/README.md | 20 +++++++ .../demo-apps/demos/07_select_join/gleam.toml | 9 ++++ .../demos/07_select_join/manifest.toml | 23 ++++++++ .../src/cake_demo_select_join.gleam | 34 ++++++++++++ .../demos/08_prepared_fragment/.gitignore | 4 ++ .../demos/08_prepared_fragment/.tool-versions | 4 ++ .../README.md | 4 +- .../demos/08_prepared_fragment/gleam.toml | 9 ++++ .../demos/08_prepared_fragment/manifest.toml | 23 ++++++++ .../src/cake_demo_prepared_fragment.gleam | 37 +++++++++++++ .../helper/src/helper/demo_data.gleam | 3 +- src/cake/fragment.gleam | 54 ++++++++++++++++++- test/cake_test/fragment_test.gleam | 3 +- test/test_support/test_data.gleam | 3 +- 56 files changed, 284 insertions(+), 56 deletions(-) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/.gitignore (100%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/.tool-versions (100%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/README.md (88%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/gleam.toml (100%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/manifest.toml (100%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/src/cake_demo_select_and_decode.gleam (100%) rename docs/demo-apps/demos/{01_demo_select_and_decode => 01_select_and_decode}/src/cat.gleam (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/.gitignore (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/.tool-versions (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/README.md (88%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/gleam.toml (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/manifest.toml (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/src/being.gleam (100%) rename docs/demo-apps/demos/{02_demo_union_and_decode => 02_union_and_decode}/src/cake_demo_union_and_decode.gleam (100%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/.gitignore (100%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/.tool-versions (100%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/README.md (88%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/gleam.toml (100%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/manifest.toml (100%) rename docs/demo-apps/demos/{03_demo_insert => 03_insert}/src/cake_demo_insert.gleam (51%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/.gitignore (100%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/.tool-versions (100%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/README.md (89%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/gleam.toml (100%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/manifest.toml (100%) rename docs/demo-apps/demos/{04_demo_delete => 04_delete}/src/cake_demo_delete.gleam (100%) rename docs/demo-apps/demos/{05_demo_update => 05_update}/.gitignore (100%) rename docs/demo-apps/demos/{05_demo_update => 05_update}/.tool-versions (100%) create mode 100644 docs/demo-apps/demos/05_update/README.md rename docs/demo-apps/demos/{05_demo_update => 05_update}/gleam.toml (100%) rename docs/demo-apps/demos/{05_demo_update => 05_update}/manifest.toml (100%) rename docs/demo-apps/demos/{05_demo_update => 05_update}/src/cake_demo_update.gleam (100%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update => 06_insert_on_conflict_update}/.gitignore (100%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update => 06_insert_on_conflict_update}/.tool-versions (100%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update => 06_insert_on_conflict_update}/README.md (85%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update => 06_insert_on_conflict_update}/gleam.toml (86%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update => 06_insert_on_conflict_update}/manifest.toml (100%) rename docs/demo-apps/demos/{06_cake_demo_insert_on_conflict_update/src/cake_demo_update.gleam => 06_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam} (97%) create mode 100644 docs/demo-apps/demos/07_select_join/.gitignore create mode 100644 docs/demo-apps/demos/07_select_join/.tool-versions create mode 100644 docs/demo-apps/demos/07_select_join/README.md create mode 100644 docs/demo-apps/demos/07_select_join/gleam.toml create mode 100644 docs/demo-apps/demos/07_select_join/manifest.toml create mode 100644 docs/demo-apps/demos/07_select_join/src/cake_demo_select_join.gleam create mode 100644 docs/demo-apps/demos/08_prepared_fragment/.gitignore create mode 100644 docs/demo-apps/demos/08_prepared_fragment/.tool-versions rename docs/demo-apps/demos/{05_demo_update => 08_prepared_fragment}/README.md (75%) create mode 100644 docs/demo-apps/demos/08_prepared_fragment/gleam.toml create mode 100644 docs/demo-apps/demos/08_prepared_fragment/manifest.toml create mode 100644 docs/demo-apps/demos/08_prepared_fragment/src/cake_demo_prepared_fragment.gleam diff --git a/README.md b/README.md index a7da0ba..d7aa2d2 100644 --- a/README.md +++ b/README.md @@ -20,41 +20,34 @@ gleam add cake Further documentation can be found on [hexdocs.pm/cake](https://hexdocs.pm/cake). -## Code examples - -See Cake's [tests](https://github.com/inoas/gleam-cake/tree/main/test/cake_test), especially the _Setup_ sections in each test module. - -You may also compare the tests with the [snapshots](https://github.com/inoas/gleam-cake/tree/main/birdie_snapshots) results. +## Usage -### Demo apps +### Demos See [docs/demo-apps/README.md](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/README.md#available-demos). -## Usage +### Code examples -- SELECT and decoding - - [cake\_demo\_select\_and\_decode.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/01_demo_select_and_decode/src/cake_demo_select_and_decode.gleam) -- UNION and decoding - - [cake\_demo\_union\_and\_decode.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/02_demo_union_and_decode/src/cake_demo_union_and_decode.gleam) -- INSERT - - [cake\_demo\_insert.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/03_demo_insert/src/cake_demo_insert.gleam) -- DELETE - - [cake\_demo\_delete.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/04_demo_delete/src/cake_demo_delete.gleam) -- UPDATE - - [cake\_demo\_update.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/05_demo_update/src/cake_demo_update.gleam) -- INSERT - - [cake\_demo\_insert\_on\_conflict\_update.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/06_demo_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam) -- ... more to come soon! +- [cake\_demo\_select\_and\_decode.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/01_select_and_decode/src/cake_demo_select_and_decode.gleam) +- [cake\_demo\_union\_and\_decode.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/02_union_and_decode/src/cake_demo_union_and_decode.gleam) +- [cake\_demo\_insert.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/03_demo_insert/src/cake_insert.gleam) +- [cake\_demo\_delete.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/04_demo_delete/src/cake_delete.gleam) +- [cake\_demo\_update.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/05_demo_update/src/cake_update.gleam) +- [cake\_demo\_insert\_on\_conflict\_update.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/06_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam) +- [cake\_demo\_select\_join.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/07_select_join/src/cake_demo_select_join.gleam) +- [cake\_demo\_prepared\_fragment.gleam](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/08_prepared_fragment/src/cake_demo_prepared_fragment.gleam) -### Tips +### Unit tests as examples + +See Cake's [tests](https://github.com/inoas/gleam-cake/tree/main/test/cake_test), especially the _Setup_ sections in each test module. + +You may also compare the tests with the [snapshots](https://github.com/inoas/gleam-cake/tree/main/birdie_snapshots) results. + +### Intended aliases Use the following aliases to make the library more ergonomic: diff --git a/docs/demo-apps/README.md b/docs/demo-apps/README.md index b15c1c2..6f959bc 100644 --- a/docs/demo-apps/README.md +++ b/docs/demo-apps/README.md @@ -7,6 +7,9 @@ - [`INSERT`](./demos/03_demo_insert/README.md) - [`DELETE`](./demos/04_demo_delete/README.md) - [`UPDATE`](./demos/05_demo_update/README.md) +- [`INSERT ON CONFLICT UPDATE`](./demos/06_cake_demo_insert_on_conflict_update/README.md) +- [`JOIN`](./demos/07_cake_demo_join/README.md) +- [`prepared fragment`](./demos/08_cake_demo_prepared_fragment/README.md) ## Running local demo apps diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/.gitignore b/docs/demo-apps/demos/01_select_and_decode/.gitignore similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/.gitignore rename to docs/demo-apps/demos/01_select_and_decode/.gitignore diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/.tool-versions b/docs/demo-apps/demos/01_select_and_decode/.tool-versions similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/.tool-versions rename to docs/demo-apps/demos/01_select_and_decode/.tool-versions diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/README.md b/docs/demo-apps/demos/01_select_and_decode/README.md similarity index 88% rename from docs/demo-apps/demos/01_demo_select_and_decode/README.md rename to docs/demo-apps/demos/01_select_and_decode/README.md index e43c2b6..33e29db 100644 --- a/docs/demo-apps/demos/01_demo_select_and_decode/README.md +++ b/docs/demo-apps/demos/01_select_and_decode/README.md @@ -13,7 +13,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/01_demo_select_and_decode/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/01_select_and_decode/src/). --- diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/gleam.toml b/docs/demo-apps/demos/01_select_and_decode/gleam.toml similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/gleam.toml rename to docs/demo-apps/demos/01_select_and_decode/gleam.toml diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/manifest.toml b/docs/demo-apps/demos/01_select_and_decode/manifest.toml similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/manifest.toml rename to docs/demo-apps/demos/01_select_and_decode/manifest.toml diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/src/cake_demo_select_and_decode.gleam b/docs/demo-apps/demos/01_select_and_decode/src/cake_demo_select_and_decode.gleam similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/src/cake_demo_select_and_decode.gleam rename to docs/demo-apps/demos/01_select_and_decode/src/cake_demo_select_and_decode.gleam diff --git a/docs/demo-apps/demos/01_demo_select_and_decode/src/cat.gleam b/docs/demo-apps/demos/01_select_and_decode/src/cat.gleam similarity index 100% rename from docs/demo-apps/demos/01_demo_select_and_decode/src/cat.gleam rename to docs/demo-apps/demos/01_select_and_decode/src/cat.gleam diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/.gitignore b/docs/demo-apps/demos/02_union_and_decode/.gitignore similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/.gitignore rename to docs/demo-apps/demos/02_union_and_decode/.gitignore diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/.tool-versions b/docs/demo-apps/demos/02_union_and_decode/.tool-versions similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/.tool-versions rename to docs/demo-apps/demos/02_union_and_decode/.tool-versions diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/README.md b/docs/demo-apps/demos/02_union_and_decode/README.md similarity index 88% rename from docs/demo-apps/demos/02_demo_union_and_decode/README.md rename to docs/demo-apps/demos/02_union_and_decode/README.md index e551b20..91a1a87 100644 --- a/docs/demo-apps/demos/02_demo_union_and_decode/README.md +++ b/docs/demo-apps/demos/02_union_and_decode/README.md @@ -13,7 +13,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/02_demo_union_and_decode/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/02_union_and_decode/src/). --- diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/gleam.toml b/docs/demo-apps/demos/02_union_and_decode/gleam.toml similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/gleam.toml rename to docs/demo-apps/demos/02_union_and_decode/gleam.toml diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/manifest.toml b/docs/demo-apps/demos/02_union_and_decode/manifest.toml similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/manifest.toml rename to docs/demo-apps/demos/02_union_and_decode/manifest.toml diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/src/being.gleam b/docs/demo-apps/demos/02_union_and_decode/src/being.gleam similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/src/being.gleam rename to docs/demo-apps/demos/02_union_and_decode/src/being.gleam diff --git a/docs/demo-apps/demos/02_demo_union_and_decode/src/cake_demo_union_and_decode.gleam b/docs/demo-apps/demos/02_union_and_decode/src/cake_demo_union_and_decode.gleam similarity index 100% rename from docs/demo-apps/demos/02_demo_union_and_decode/src/cake_demo_union_and_decode.gleam rename to docs/demo-apps/demos/02_union_and_decode/src/cake_demo_union_and_decode.gleam diff --git a/docs/demo-apps/demos/03_demo_insert/.gitignore b/docs/demo-apps/demos/03_insert/.gitignore similarity index 100% rename from docs/demo-apps/demos/03_demo_insert/.gitignore rename to docs/demo-apps/demos/03_insert/.gitignore diff --git a/docs/demo-apps/demos/03_demo_insert/.tool-versions b/docs/demo-apps/demos/03_insert/.tool-versions similarity index 100% rename from docs/demo-apps/demos/03_demo_insert/.tool-versions rename to docs/demo-apps/demos/03_insert/.tool-versions diff --git a/docs/demo-apps/demos/03_demo_insert/README.md b/docs/demo-apps/demos/03_insert/README.md similarity index 88% rename from docs/demo-apps/demos/03_demo_insert/README.md rename to docs/demo-apps/demos/03_insert/README.md index fbcb104..4dfd003 100644 --- a/docs/demo-apps/demos/03_demo_insert/README.md +++ b/docs/demo-apps/demos/03_insert/README.md @@ -12,7 +12,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/03_demo_insert/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/03_insert/src/). --- diff --git a/docs/demo-apps/demos/03_demo_insert/gleam.toml b/docs/demo-apps/demos/03_insert/gleam.toml similarity index 100% rename from docs/demo-apps/demos/03_demo_insert/gleam.toml rename to docs/demo-apps/demos/03_insert/gleam.toml diff --git a/docs/demo-apps/demos/03_demo_insert/manifest.toml b/docs/demo-apps/demos/03_insert/manifest.toml similarity index 100% rename from docs/demo-apps/demos/03_demo_insert/manifest.toml rename to docs/demo-apps/demos/03_insert/manifest.toml diff --git a/docs/demo-apps/demos/03_demo_insert/src/cake_demo_insert.gleam b/docs/demo-apps/demos/03_insert/src/cake_demo_insert.gleam similarity index 51% rename from docs/demo-apps/demos/03_demo_insert/src/cake_demo_insert.gleam rename to docs/demo-apps/demos/03_insert/src/cake_demo_insert.gleam index 3ed9d91..871eb3f 100644 --- a/docs/demo-apps/demos/03_demo_insert/src/cake_demo_insert.gleam +++ b/docs/demo-apps/demos/03_insert/src/cake_demo_insert.gleam @@ -1,29 +1,18 @@ import cake/insert as i -import cake/update as u -import cake/where as w -import helper/demo_data -import helper/postgres import gleam/dynamic import gleam/io +import helper/demo_data +import helper/postgres import pprint -fn update() { - u.new() |> u.sets(["counter" |> u.set_expression("counters.counter + 1")]) -} - fn insert_query() { [ [i.string("Whiskers"), i.int(1)] |> i.row, - [i.string("Karl"), i.int(1)] |> i.row, - [i.string("Clara"), i.int(1)] |> i.row, + [i.string("Karl"), i.int(2)] |> i.row, + [i.string("Clara"), i.int(3)] |> i.row, ] - |> i.from_values(table_name: "counters", columns: ["name", "counter"]) - |> i.on_columns_conflict_update( - columns: ["name"], - where: w.col("counters.is_active") |> w.is_true, - update: update(), - ) - |> i.returning(["name", "counter"]) + |> i.from_values(table_name: "cats", columns: ["name", "age"]) + |> i.returning(["name", "age"]) |> i.to_query } diff --git a/docs/demo-apps/demos/04_demo_delete/.gitignore b/docs/demo-apps/demos/04_delete/.gitignore similarity index 100% rename from docs/demo-apps/demos/04_demo_delete/.gitignore rename to docs/demo-apps/demos/04_delete/.gitignore diff --git a/docs/demo-apps/demos/04_demo_delete/.tool-versions b/docs/demo-apps/demos/04_delete/.tool-versions similarity index 100% rename from docs/demo-apps/demos/04_demo_delete/.tool-versions rename to docs/demo-apps/demos/04_delete/.tool-versions diff --git a/docs/demo-apps/demos/04_demo_delete/README.md b/docs/demo-apps/demos/04_delete/README.md similarity index 89% rename from docs/demo-apps/demos/04_demo_delete/README.md rename to docs/demo-apps/demos/04_delete/README.md index e1520f1..134e8bb 100644 --- a/docs/demo-apps/demos/04_demo_delete/README.md +++ b/docs/demo-apps/demos/04_delete/README.md @@ -12,7 +12,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/04_demo_delete/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/04_delete/src/). --- diff --git a/docs/demo-apps/demos/04_demo_delete/gleam.toml b/docs/demo-apps/demos/04_delete/gleam.toml similarity index 100% rename from docs/demo-apps/demos/04_demo_delete/gleam.toml rename to docs/demo-apps/demos/04_delete/gleam.toml diff --git a/docs/demo-apps/demos/04_demo_delete/manifest.toml b/docs/demo-apps/demos/04_delete/manifest.toml similarity index 100% rename from docs/demo-apps/demos/04_demo_delete/manifest.toml rename to docs/demo-apps/demos/04_delete/manifest.toml diff --git a/docs/demo-apps/demos/04_demo_delete/src/cake_demo_delete.gleam b/docs/demo-apps/demos/04_delete/src/cake_demo_delete.gleam similarity index 100% rename from docs/demo-apps/demos/04_demo_delete/src/cake_demo_delete.gleam rename to docs/demo-apps/demos/04_delete/src/cake_demo_delete.gleam diff --git a/docs/demo-apps/demos/05_demo_update/.gitignore b/docs/demo-apps/demos/05_update/.gitignore similarity index 100% rename from docs/demo-apps/demos/05_demo_update/.gitignore rename to docs/demo-apps/demos/05_update/.gitignore diff --git a/docs/demo-apps/demos/05_demo_update/.tool-versions b/docs/demo-apps/demos/05_update/.tool-versions similarity index 100% rename from docs/demo-apps/demos/05_demo_update/.tool-versions rename to docs/demo-apps/demos/05_update/.tool-versions diff --git a/docs/demo-apps/demos/05_update/README.md b/docs/demo-apps/demos/05_update/README.md new file mode 100644 index 0000000..2a5a962 --- /dev/null +++ b/docs/demo-apps/demos/05_update/README.md @@ -0,0 +1,19 @@ +# Cake demo app: UPDATE + +This demo of Cake shows how to `UPDATE`. + +To start postgres via docker compose, see +[docs/demo-apps/README.md](../../README.md#Installing-prerequisites), then: + +```shell +gleam clean +gleam run +``` + +## Demo source code + +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/05_update/src/). + +--- + +For further demos see [docs/demo-apps/README.md](../../README.md#available-demos). diff --git a/docs/demo-apps/demos/05_demo_update/gleam.toml b/docs/demo-apps/demos/05_update/gleam.toml similarity index 100% rename from docs/demo-apps/demos/05_demo_update/gleam.toml rename to docs/demo-apps/demos/05_update/gleam.toml diff --git a/docs/demo-apps/demos/05_demo_update/manifest.toml b/docs/demo-apps/demos/05_update/manifest.toml similarity index 100% rename from docs/demo-apps/demos/05_demo_update/manifest.toml rename to docs/demo-apps/demos/05_update/manifest.toml diff --git a/docs/demo-apps/demos/05_demo_update/src/cake_demo_update.gleam b/docs/demo-apps/demos/05_update/src/cake_demo_update.gleam similarity index 100% rename from docs/demo-apps/demos/05_demo_update/src/cake_demo_update.gleam rename to docs/demo-apps/demos/05_update/src/cake_demo_update.gleam diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/.gitignore b/docs/demo-apps/demos/06_insert_on_conflict_update/.gitignore similarity index 100% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/.gitignore rename to docs/demo-apps/demos/06_insert_on_conflict_update/.gitignore diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/.tool-versions b/docs/demo-apps/demos/06_insert_on_conflict_update/.tool-versions similarity index 100% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/.tool-versions rename to docs/demo-apps/demos/06_insert_on_conflict_update/.tool-versions diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/README.md b/docs/demo-apps/demos/06_insert_on_conflict_update/README.md similarity index 85% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/README.md rename to docs/demo-apps/demos/06_insert_on_conflict_update/README.md index 1f9ce85..a769c78 100644 --- a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/README.md +++ b/docs/demo-apps/demos/06_insert_on_conflict_update/README.md @@ -12,7 +12,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/06_insert_on_conflict_update/src/). --- diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/gleam.toml b/docs/demo-apps/demos/06_insert_on_conflict_update/gleam.toml similarity index 86% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/gleam.toml rename to docs/demo-apps/demos/06_insert_on_conflict_update/gleam.toml index d060e97..58f2d88 100644 --- a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/gleam.toml +++ b/docs/demo-apps/demos/06_insert_on_conflict_update/gleam.toml @@ -1,4 +1,4 @@ -name = "cake_demo_update" +name = "cake_demo_insert_on_conflict_update" description = "An demo of using Gleam with Cake and Postgres to run INSERT ON CONFLICT UPDATE queries" [dependencies] diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/manifest.toml b/docs/demo-apps/demos/06_insert_on_conflict_update/manifest.toml similarity index 100% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/manifest.toml rename to docs/demo-apps/demos/06_insert_on_conflict_update/manifest.toml diff --git a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/src/cake_demo_update.gleam b/docs/demo-apps/demos/06_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam similarity index 97% rename from docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/src/cake_demo_update.gleam rename to docs/demo-apps/demos/06_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam index 2c82e81..effdfc1 100644 --- a/docs/demo-apps/demos/06_cake_demo_insert_on_conflict_update/src/cake_demo_update.gleam +++ b/docs/demo-apps/demos/06_insert_on_conflict_update/src/cake_demo_insert_on_conflict_update.gleam @@ -1,4 +1,3 @@ -import cake/delete as d import cake/insert as i import cake/update as u import cake/where as w diff --git a/docs/demo-apps/demos/07_select_join/.gitignore b/docs/demo-apps/demos/07_select_join/.gitignore new file mode 100644 index 0000000..599be4e --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/.gitignore @@ -0,0 +1,4 @@ +*.beam +*.ez +/build +erl_crash.dump diff --git a/docs/demo-apps/demos/07_select_join/.tool-versions b/docs/demo-apps/demos/07_select_join/.tool-versions new file mode 100644 index 0000000..d7c17bb --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/.tool-versions @@ -0,0 +1,5 @@ +# erlang 26.2.5.1 +erlang 27.0 +gleam 1.3.2 +# erlang 26.2.5.1 +# gleam nightly diff --git a/docs/demo-apps/demos/07_select_join/README.md b/docs/demo-apps/demos/07_select_join/README.md new file mode 100644 index 0000000..9f22127 --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/README.md @@ -0,0 +1,20 @@ +# Cake demo app: SELECT and decode + +This demo of Cake shows how to `SELECT` and decode returning rows into +Gleam records. + +To start postgres via docker compose, see +[docs/demo-apps/README.md](../../README.md#Installing-prerequisites), then: + +```shell +gleam clean +gleam run +``` + +## Demo source code + +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/07_select_join/src/). + +--- + +For further demos see [docs/demo-apps/README.md](../../README.md#available-demos). diff --git a/docs/demo-apps/demos/07_select_join/gleam.toml b/docs/demo-apps/demos/07_select_join/gleam.toml new file mode 100644 index 0000000..8d2fffc --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/gleam.toml @@ -0,0 +1,9 @@ +name = "cake_demo_select_join" +description = "An demo of using Gleam with Cake and Postgres to run SELECT and JOIN queries and decode returning data into Gleam records" + +[dependencies] +cake = { path = "../../../../" } +helper = { path = "../../helper" } +gleam_pgo = ">= 0.13.0 and < 2.0.0" +gleam_stdlib = ">= 0.39.0 and < 2.0.0" +pprint = ">= 1.0.3 and < 2.0.0" diff --git a/docs/demo-apps/demos/07_select_join/manifest.toml b/docs/demo-apps/demos/07_select_join/manifest.toml new file mode 100644 index 0000000..748ea85 --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/manifest.toml @@ -0,0 +1,23 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "backoff", version = "1.1.6", build_tools = ["rebar3"], requirements = [], otp_app = "backoff", source = "hex", outer_checksum = "CF0CFFF8995FB20562F822E5CC47D8CCF664C5ECDC26A684CBE85C225F9D7C39" }, + { name = "cake", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], source = "local", path = "../../../.." }, + { name = "helper", version = "1.0.0", build_tools = ["gleam"], requirements = ["cake", "gleam_pgo", "gleam_stdlib", "pprint"], source = "local", path = "../../helper" }, + { name = "glam", version = "2.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glam", source = "hex", outer_checksum = "66EC3BCD632E51EED029678F8DF419659C1E57B1A93D874C5131FE220DFAD2B2" }, + { name = "gleam_pgo", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "pgo"], otp_app = "gleam_pgo", source = "hex", outer_checksum = "6A1E7F3E717C077788254871E4EF4A8DFF58FEC07D7FA7C7702C2CCF66095AC8" }, + { name = "gleam_stdlib", version = "0.39.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "2D7DE885A6EA7F1D5015D1698920C9BAF7241102836CE0C3837A4F160128A9C4" }, + { name = "opentelemetry_api", version = "1.3.0", build_tools = ["rebar3", "mix"], requirements = ["opentelemetry_semantic_conventions"], otp_app = "opentelemetry_api", source = "hex", outer_checksum = "B9E5FF775FD064FA098DBA3C398490B77649A352B40B0B730A6B7DC0BDD68858" }, + { name = "opentelemetry_semantic_conventions", version = "0.2.0", build_tools = ["rebar3", "mix"], requirements = [], otp_app = "opentelemetry_semantic_conventions", source = "hex", outer_checksum = "D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895" }, + { name = "pg_types", version = "0.4.0", build_tools = ["rebar3"], requirements = [], otp_app = "pg_types", source = "hex", outer_checksum = "B02EFA785CAECECF9702C681C80A9CA12A39F9161A846CE17B01FB20AEEED7EB" }, + { name = "pgo", version = "0.14.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "71016C22599936E042DC0012EE4589D24C71427D266292F775EBF201D97DF9C9" }, + { name = "pprint", version = "1.0.3", build_tools = ["gleam"], requirements = ["glam", "gleam_stdlib"], otp_app = "pprint", source = "hex", outer_checksum = "76BBB92E23D12D954BD452686543F29EDE8EBEBB7FC0ACCBCA66EEF276EC3A06" }, +] + +[requirements] +cake = { path = "../../../../" } +helper = { path = "../../helper" } +gleam_pgo = { version = ">= 0.13.0 and < 2.0.0" } +gleam_stdlib = { version = ">= 0.39.0 and < 2.0.0" } +pprint = { version = ">= 1.0.3 and < 2.0.0" } diff --git a/docs/demo-apps/demos/07_select_join/src/cake_demo_select_join.gleam b/docs/demo-apps/demos/07_select_join/src/cake_demo_select_join.gleam new file mode 100644 index 0000000..17b492e --- /dev/null +++ b/docs/demo-apps/demos/07_select_join/src/cake_demo_select_join.gleam @@ -0,0 +1,34 @@ +import cake/join as j +import cake/select as s +import cake/where as w +import gleam/dynamic +import gleam/io +import helper/demo_data +import helper/postgres +import pprint + +fn select_join_query() { + s.new() + |> s.selects([s.col("owners.name"), s.col("dogs.name")]) + |> s.from_table("owners") + |> s.join(j.left( + with: j.table("dogs"), + on: w.col("owners.id") |> w.eq(w.col("dogs.owner_id")), + alias: "dogs", + )) + |> s.to_query +} + +pub fn main() { + use conn <- postgres.with_connection + demo_data.create_tables_and_insert_rows(conn) + + // NOTICE: This will crash, if the SQL query fails. + let result = + select_join_query() |> postgres.run_read_query(dynamic.dynamic, conn) + + io.println("Result: ") + + result + |> pprint.debug +} diff --git a/docs/demo-apps/demos/08_prepared_fragment/.gitignore b/docs/demo-apps/demos/08_prepared_fragment/.gitignore new file mode 100644 index 0000000..599be4e --- /dev/null +++ b/docs/demo-apps/demos/08_prepared_fragment/.gitignore @@ -0,0 +1,4 @@ +*.beam +*.ez +/build +erl_crash.dump diff --git a/docs/demo-apps/demos/08_prepared_fragment/.tool-versions b/docs/demo-apps/demos/08_prepared_fragment/.tool-versions new file mode 100644 index 0000000..bdb8ecd --- /dev/null +++ b/docs/demo-apps/demos/08_prepared_fragment/.tool-versions @@ -0,0 +1,4 @@ +# erlang 26.2.5.1 +erlang 27.0 +gleam 1.3.2 +# gleam nightly diff --git a/docs/demo-apps/demos/05_demo_update/README.md b/docs/demo-apps/demos/08_prepared_fragment/README.md similarity index 75% rename from docs/demo-apps/demos/05_demo_update/README.md rename to docs/demo-apps/demos/08_prepared_fragment/README.md index 0ce2152..132ed35 100644 --- a/docs/demo-apps/demos/05_demo_update/README.md +++ b/docs/demo-apps/demos/08_prepared_fragment/README.md @@ -1,6 +1,6 @@ # Cake demo app: INSERT -This demo of Cake shows how to `INSERT`. +This demo of Cake shows how to `INSERT ON CONFLICT UPDATE`. To start postgres via docker compose, see [docs/demo-apps/README.md](../../README.md#Installing-prerequisites), then: @@ -12,7 +12,7 @@ gleam run ## Demo source code -See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/05_demo_update/src/). +See the [src directory](https://github.com/inoas/gleam-cake/blob/main/docs/demo-apps/demos/08_prepared_fragment/src/). --- diff --git a/docs/demo-apps/demos/08_prepared_fragment/gleam.toml b/docs/demo-apps/demos/08_prepared_fragment/gleam.toml new file mode 100644 index 0000000..66cd34d --- /dev/null +++ b/docs/demo-apps/demos/08_prepared_fragment/gleam.toml @@ -0,0 +1,9 @@ +name = "cake_demo_prepared_fragment" +description = "An demo of using Gleam with Cake and Postgres to run queries with fragments including prepared statements" + +[dependencies] +cake = { path = "../../../../" } +helper = { path = "../../helper" } +gleam_pgo = ">= 0.13.0 and < 2.0.0" +gleam_stdlib = ">= 0.39.0 and < 2.0.0" +pprint = ">= 1.0.3 and < 2.0.0" diff --git a/docs/demo-apps/demos/08_prepared_fragment/manifest.toml b/docs/demo-apps/demos/08_prepared_fragment/manifest.toml new file mode 100644 index 0000000..748ea85 --- /dev/null +++ b/docs/demo-apps/demos/08_prepared_fragment/manifest.toml @@ -0,0 +1,23 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "backoff", version = "1.1.6", build_tools = ["rebar3"], requirements = [], otp_app = "backoff", source = "hex", outer_checksum = "CF0CFFF8995FB20562F822E5CC47D8CCF664C5ECDC26A684CBE85C225F9D7C39" }, + { name = "cake", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], source = "local", path = "../../../.." }, + { name = "helper", version = "1.0.0", build_tools = ["gleam"], requirements = ["cake", "gleam_pgo", "gleam_stdlib", "pprint"], source = "local", path = "../../helper" }, + { name = "glam", version = "2.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glam", source = "hex", outer_checksum = "66EC3BCD632E51EED029678F8DF419659C1E57B1A93D874C5131FE220DFAD2B2" }, + { name = "gleam_pgo", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "pgo"], otp_app = "gleam_pgo", source = "hex", outer_checksum = "6A1E7F3E717C077788254871E4EF4A8DFF58FEC07D7FA7C7702C2CCF66095AC8" }, + { name = "gleam_stdlib", version = "0.39.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "2D7DE885A6EA7F1D5015D1698920C9BAF7241102836CE0C3837A4F160128A9C4" }, + { name = "opentelemetry_api", version = "1.3.0", build_tools = ["rebar3", "mix"], requirements = ["opentelemetry_semantic_conventions"], otp_app = "opentelemetry_api", source = "hex", outer_checksum = "B9E5FF775FD064FA098DBA3C398490B77649A352B40B0B730A6B7DC0BDD68858" }, + { name = "opentelemetry_semantic_conventions", version = "0.2.0", build_tools = ["rebar3", "mix"], requirements = [], otp_app = "opentelemetry_semantic_conventions", source = "hex", outer_checksum = "D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895" }, + { name = "pg_types", version = "0.4.0", build_tools = ["rebar3"], requirements = [], otp_app = "pg_types", source = "hex", outer_checksum = "B02EFA785CAECECF9702C681C80A9CA12A39F9161A846CE17B01FB20AEEED7EB" }, + { name = "pgo", version = "0.14.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "71016C22599936E042DC0012EE4589D24C71427D266292F775EBF201D97DF9C9" }, + { name = "pprint", version = "1.0.3", build_tools = ["gleam"], requirements = ["glam", "gleam_stdlib"], otp_app = "pprint", source = "hex", outer_checksum = "76BBB92E23D12D954BD452686543F29EDE8EBEBB7FC0ACCBCA66EEF276EC3A06" }, +] + +[requirements] +cake = { path = "../../../../" } +helper = { path = "../../helper" } +gleam_pgo = { version = ">= 0.13.0 and < 2.0.0" } +gleam_stdlib = { version = ">= 0.39.0 and < 2.0.0" } +pprint = { version = ">= 1.0.3 and < 2.0.0" } diff --git a/docs/demo-apps/demos/08_prepared_fragment/src/cake_demo_prepared_fragment.gleam b/docs/demo-apps/demos/08_prepared_fragment/src/cake_demo_prepared_fragment.gleam new file mode 100644 index 0000000..1672d87 --- /dev/null +++ b/docs/demo-apps/demos/08_prepared_fragment/src/cake_demo_prepared_fragment.gleam @@ -0,0 +1,37 @@ +import cake/fragment as f +import cake/select as s +import cake/where as w +import gleam/dynamic +import gleam/io +import helper/demo_data +import helper/postgres +import pprint + +fn fragment_query() { + s.new() + |> s.from_table("cats") + |> s.where( + w.fragment_value(f.literal("LOWER(cats.name)")) + |> w.eq( + w.fragment_value( + f.prepared("LOWER(" <> f.placeholder <> ")", [f.string("cLaRa")]), + ), + ), + ) + |> s.to_query +} + +pub fn main() { + use conn <- postgres.with_connection + demo_data.create_tables_and_insert_rows(conn) + + // NOTICE: This will crash, if the SQL query fails. + let result = + fragment_query() + |> postgres.run_read_query(dynamic.dynamic, conn) + + io.println("Result: ") + + result + |> pprint.debug +} diff --git a/docs/demo-apps/helper/src/helper/demo_data.gleam b/docs/demo-apps/helper/src/helper/demo_data.gleam index 5badc36..fb2457c 100644 --- a/docs/demo-apps/helper/src/helper/demo_data.gleam +++ b/docs/demo-apps/helper/src/helper/demo_data.gleam @@ -61,7 +61,8 @@ fn insert_owners_rows() { "INSERT INTO owners (id, name, last_name, age) VALUES (1, 'Alice', 'Wibble', 5), (2, 'Bob', 'Wobble', 8), - (3, 'Charlie', 'Wabble', 13) + (3, 'Charlie', 'Wabble', 13), + (4, 'Robot', 'User', 999) ;" } diff --git a/src/cake/fragment.gleam b/src/cake/fragment.gleam index eed996a..2a754a4 100644 --- a/src/cake/fragment.gleam +++ b/src/cake/fragment.gleam @@ -8,7 +8,9 @@ //// import cake/internal/read_query -import cake/param.{type Param} +import cake/param.{ + type Param, BoolParam, FloatParam, IntParam, NullParam, StringParam, +} import gleam/int import gleam/io import gleam/list @@ -21,6 +23,10 @@ import gleam/order pub type Fragment = read_query.Fragment +// ┌───────────────────────────────────────────────────────────────────────────┐ +// │ fragment │ +// └───────────────────────────────────────────────────────────────────────────┘ + /// This placeholder must be used when building fragments with parameters. /// pub const placeholder = read_query.fragment_placeholder_grapheme @@ -102,3 +108,49 @@ pub fn prepared(string str: String, params prms: List(Param)) -> Fragment { pub fn literal(string str: String) -> Fragment { str |> read_query.FragmentLiteral } + +// ┌───────────────────────────────────────────────────────────────────────────┐ +// │ params │ +// └───────────────────────────────────────────────────────────────────────────┘ + +/// Create a new `Param` with a `Bool` value. +/// +pub fn bool(value vl: Bool) -> Param { + vl |> BoolParam +} + +/// Create a new `Param` with a `True` value. +/// +pub fn true() -> Param { + True |> BoolParam +} + +/// Create a new `Param` with a `True` value. +/// +pub fn false() -> Param { + False |> BoolParam +} + +/// Create a new `Param` with a `Float` value. +/// +pub fn float(value vl: Float) -> Param { + vl |> FloatParam +} + +/// Create a new `Param` with an `Int` value. +/// +pub fn int(value vl: Int) -> Param { + vl |> IntParam +} + +/// Create a new `Param` with a `String` value. +/// +pub fn string(value vl: String) -> Param { + vl |> StringParam +} + +/// Create a new `Param` with an SQL `NULL` value. +/// +pub fn null() -> Param { + NullParam +} diff --git a/test/cake_test/fragment_test.gleam b/test/cake_test/fragment_test.gleam index aff9fae..202ba7c 100644 --- a/test/cake_test/fragment_test.gleam +++ b/test/cake_test/fragment_test.gleam @@ -1,6 +1,5 @@ import birdie import cake/fragment as f -import cake/param as p import cake/select as s import cake/where as w import pprint.{format as to_string} @@ -24,7 +23,7 @@ fn fragment_query() { w.fragment_value(f.literal("LOWER(cats.name)")) |> w.eq( w.fragment_value( - f.prepared("LOWER(" <> f.placeholder <> ")", [p.string("Clara")]), + f.prepared("LOWER(" <> f.placeholder <> ")", [f.string("cLaRa")]), ), ), ) diff --git a/test/test_support/test_data.gleam b/test/test_support/test_data.gleam index 45e0bb4..f9eeef0 100644 --- a/test/test_support/test_data.gleam +++ b/test/test_support/test_data.gleam @@ -15,7 +15,8 @@ pub fn insert_owners_rows() { "INSERT INTO owners (id, name, last_name, age) VALUES (1, 'Alice', 'Wibble', 5), (2, 'Bob', 'Wobble', 8), - (3, 'Charlie', 'Wabble', 13) + (3, 'Charlie', 'Wabble', 13), + (4, 'Robot', 'User', 999) ;" }