Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add JSON Traversal recipe. #580

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions site/docs/recipes/json-traversal.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import { Types } from './json-traversal/Types'

# JSON Traversal

In the era of data-driven applications, SQL databases such as PostgreSQL, MySQL,
and SQLite have evolved to support JSON traversal. JSON provides a flexible and
dynamic data structure, and these databases now offer native support for storing,
querying, and manipulating JSON data within the SQL framework.

PostgreSQL, MySQL, and SQLite have introduced native JSON data types, along with
functions and operators for extracting values, filtering conditions, aggregating
arrays, and indexing JSON data. This enables developers to leverage the strengths
of SQL and JSON together, combining relational querying with the flexibility of
JSON manipulation.

These capabilities have always fascinated us, and finally we are able to bring
them to Kysely and through some exploration and experimentation, we'll hopefully
land together on a solution that is both elegant, practical, and most importantly,
type-safe.

Each dialect Kysely supports at its core, has a different way of handling JSON
traversal. So this recipe will require choosing a dialect to work with:

<Tabs queryString="dialect">
<TabItem value="postgresql" label="PostgreSQL" default></TabItem>
<TabItem value="mysql" label="MySQL"></TabItem>
<TabItem value="sqlite" label="SQLite"></TabItem>
</Tabs>

## Defining Types

<Types />

## Querying

## Inference
51 changes: 51 additions & 0 deletions site/docs/recipes/json-traversal/Types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import { Dialect } from '@site/docs/getting-started/shared'
import CodeBlock from '@theme/CodeBlock'

export interface TypesProps {
dialect: Dialect
}

export function Types(props: TypesProps) {
return (
<>
<p>
When defining a JSON column's type, it must follow the following rules:
<br />
<br />
<strong>Root column type</strong> - The root select type must be of
object or array type. It can be nullable, but cannot be optional (
<code>jsonColumn?:</code>), just like any other column type definition.
Its insert and update types must be strings, as you'd{' '}
<code>JSON.stringify</code> JSON parameters.
<br />
<br />
<strong>Nested field type</strong> - Nested fields must have a JSON
native type (string, number, boolean, null, object or array). Unlike the
root column, nested fields can be optional (<code>field?:</code>).
<br />
<br />
<strong>
Unknowns, JSON (Discriminated) Unions and other complexities
</strong>{' '}
- Supporting traversal to not-well-defined JSONs or complex types was
not part of phase 1. It could work right now, but we haven't tested it.
We'd appreciate any feedback or real-world examples, as we prepare for
the next phases.
<br />
<hr />
</p>
<CodeBlock language="ts" title="src/types.ts">
{`import { ColumnType, Generated, JSONColumnType } from 'kysely'

export interface Database {
person_metadata: PersonMetadataTable
}

export interface PersonMetadataTable {
profile: JSONColumnType<{ created_at: string }> // short for ColumnType<T, string, string>
}`}
</CodeBlock>
</>
)
}