diff --git a/README.md b/README.md index 18023a0..57b4aec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ PostgresJson ============ -_Kotlin library to request postgres with native SQL queries and return JSON_ +_Kotlin library to request postgres with native SQL queries_ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=postgres-json&metric=alert_status)](https://sonarcloud.io/dashboard?id=postgres-json) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=postgres-json&metric=coverage)](https://sonarcloud.io/dashboard?id=postgres-json) @@ -9,3 +9,14 @@ _Kotlin library to request postgres with native SQL queries and return JSON_ * [Installation](./docs/installation.md) * [Migrations](./docs/migrations/migrations.md) * [Usage](./docs/usage/usage.md) + +--- + +## The best benefits + +* Total control of all Postgresql features and SQL language +* More speed and flexible than an ORM +* [Multi level request](./docs/usage/multi-level.md) +* Queries are written in separate native `.sql` files +* Automatic tested database migration and rollback +* Unit testing of SQL queries \ No newline at end of file diff --git a/docs/usage/multi-level.md b/docs/usage/multi-level.md new file mode 100644 index 0000000..197d867 --- /dev/null +++ b/docs/usage/multi-level.md @@ -0,0 +1,93 @@ +Multi Level Queries +=================== + +## Define schema, query and kotlin object +1. Schema +```postgresql +create table parent ( + id uuid primary key, + name text not null +); + +create table child ( + id uuid primary key, + name text not null, + parent_id uuid not null references parent +) +``` +2. Insert some data for tests +```postgresql +insert into parent (id, name) VALUES ('379e0687-9e4a-4781-b0e9-d94a62e4261f', 'Bernard'); +insert into child (id, name, parent_id) VALUES (uuid_generate_v4(), 'Noé', '379e0687-9e4a-4781-b0e9-d94a62e4261f'); +insert into child (id, name, parent_id) VALUES (uuid_generate_v4(), 'John', '379e0687-9e4a-4781-b0e9-d94a62e4261f'); +``` +3. Define Model +```kotlin +import java.util.UUID + +class Parent(val id: UUID, val name: String, val children: List) +class Child(val id: UUID, val name: String) +``` + +4. Define request function +```postgresql +-- resource/sql/functions/find_parent_by_id.sql +create or replace function find_parent_by_id(in _id uuid, out resource json) language plpgsql as +$$ +begin + select to_json(t) into resource + from ( + select + p.*, + json_agg(to_jsonb(c) - 'parent_id') as children + from parent p + join child c on c.parent_id = p.id + where p.id = _id + group by p.id + ) t; +end; +$$; +``` + +## Execute the function + +You just to use `Requester` and set the sql function name, then pass arguments. + +If you need to return more than one entry, use `.select()` instead of `.selecteOne()` + +See the [Paginated example](./paginated.md) +```kotlin +import fr.postgresjson.connexion.Requester + +val requester: Requester = TODO() +val result: Parent = requester + .getFunction("find_parent_by_id") + .selectOne("id" to "379e0687-9e4a-4781-b0e9-d94a62e4261f") +``` + +The requester create dynamically this request +```postgresql +select * from find_parent_by_id(_id => '379e0687-9e4a-4781-b0e9-d94a62e4261f'); +``` +*Watch the underscore as prefix is added if necessary. +The requester known the parameters because it parses all SQL functions and reads the names of the parameters from them.* + + +And the SQL return is a JSON like follow: +```json +{ + "id": "379e0687-9e4a-4781-b0e9-d94a62e4261f", + "name": "Bernard", + "child": [ + { + "id": "c2d0ec81-7cac-4689-8086-2644a3b309b5", + "name": "Noé" + }, + { + "id": "255d911a-0cbc-4156-bf8c-0204e89494d9", + "name": "John" + } + ] +} +``` +But the requester deserialize the result automatically into a Kotlin object with their children objects. **And do that in only one request**. diff --git a/docs/usage/paginated.md b/docs/usage/paginated.md new file mode 100644 index 0000000..f2df3c2 --- /dev/null +++ b/docs/usage/paginated.md @@ -0,0 +1,19 @@ +Paginated request +================= + +```kotlin +import fr.postgresjson.connexion.Paginated +import fr.postgresjson.connexion.Requester +import java.util.UUID + +class Article(val id: UUID, val name: String) + +val request: Requester = TODO() +val article: Paginated
= requester + .getFunction("find_articles") + .select( + page = 1, + limit = 10, + "id" to "4a04820e-f880-4d80-b1c9-aeacccb24977" + ) +``` \ No newline at end of file diff --git a/docs/usage/usage.md b/docs/usage/usage.md index cd28f73..8064140 100644 --- a/docs/usage/usage.md +++ b/docs/usage/usage.md @@ -2,4 +2,6 @@ 1. [Init connection](./init-connection.md) 2. [Raw request](./raw-request.md) -3. [Stored Procedure](./stored-procedure.md) \ No newline at end of file +3. [Stored Procedure](./stored-procedure.md) +4. [Paginated request](./paginated.md) +5. [Multi level request](./multi-level.md) \ No newline at end of file