More SqlDelight (JSON with PostgreSql)

Support for JSON/JSOB data type in SqlDelight 2.1.0-SNAPSHOT

Example

Store and retrieve JSON/JSONB objects in your database.

Repository

https://github.com/griffio/sqldelight-postgres-json/blob/master/README.md

Schema

CREATE TABLE Recipes (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  recipe JSONB NOT NULL,
  createdAt TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updatedAt TIMESTAMPTZ
);

GIN (Generalized Inverted Index) indexes are specifically designed for searching within JSONB data. SqlDelight allows you to create GIN indexes on your JSONB columns, dramatically improving query performance.

See storage parameters https://www.postgresql.org/docs/current/sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS

CREATE INDEX gin_recipe ON Recipes USING GIN (recipe);

Queries

See operators https://www.postgresql.org/docs/current/functions-json.html

JSONB

jsonb @> jsonb → boolean

jsonb <@ jsonb → boolean

jsonb ? text → boolean

jsonb ?| text[] → boolean

jsonb ?& text[] → boolean

jsonb || jsonb → jsonb

jsonb - text → jsonb

jsonb - text[] → jsonb

jsonb - integer → jsonb

jsonb #- text[] → jsonb

jsonb @? jsonpath → boolean

jsonb @@ jsonpath → boolean
get:
SELECT *
FROM Recipes
WHERE id = ?;

getRecipe:
SELECT *
FROM Recipes
WHERE recipe @> ?;

add:
INSERT INTO Recipes(recipe) VALUES (?) RETURNING *;

update:
UPDATE Recipes
SET recipe = jsonb_insert(recipe, :path, :newValue)
WHERE id = :id RETURNING recipe;

pretty:
SELECT jsonb_pretty(recipe)
FROM Recipes
WHERE id = ?;

prettyV:
SELECT to_jsonb(?);

remove:
UPDATE Recipes SET recipe = recipe #- ? WHERE id = ?;

contains:
SELECT *
FROM Recipes WHERE recipe ?? ?; -- ? operator is escaped with extra ? in jdbc

Application


  val pizza = sample.recipeQueries.add(
    """
    {
      "recipe_name": "Give a slice of Pizza",
      "ingredients": [
        {
          "pizza": {
            "amounts": [
              {
                "amount": 1,
                "unit": "slice"
              }
            ]
          }
        }
      ],
      "steps": [
        {
          "step": "Cut out an equal slice from the whole pizza."
        }
      ]
    }
  """.trimIndent())
  .executeAsOne().also(::println)

  sample.recipeQueries.getRecipe("""{"recipe_name": "Basic Fruit Salad"}""")
  .executeAsOne().also(::println)

  sample.recipeQueries.contains("ingredients")
  .executeAsList().also(::println)