# Design: SQL Verbs
**Author**: @worstell
<!-- Status of the document - draft, in-review, etc. - is conveyed via HackMD labels -->
## Description
Convert database schemas and queries into FTL types (queries as `Verb` and models as `Data`), integrating SQL into the FTL type system.
## Motivation
Ensuring type safety, reducing boilerplate, and simplifying development against DBs. This feature also lays the groundwork for enforcing redaction and encryption policies throughout the FTL ecosystem.
## Goals
* Provide ergonomic, type-safe interaction with DBs
* Integrate DB operations with the FTL type system
### Non-Goals
* Implementation of redaction, encryption, and other policies is out-of-scope
## Design
### 1. User Configuration
SQL schema and query files are supplied in known directories. Users can optionally specify their root paths, relative to the module root, in `ftl.toml`:
```toml
module = "echo"
language = "go"
db-schema-dir = "sql/schema"
db-query-dir = "sql/query"
```
If not specified, the default relative paths `sql/schema` and `sql/query` are used.
### 2. Build Engine
The build engine identifies when directories are present at the provided SQL paths and, if they are, invokes `sqlc generate ...` using our custom plugin.
Prior to executing the plugin, we'll scaffold a per-build sqlc config into the user's build directory:
```yaml
version: '2'
plugins:
- name: sqlc-gen-ftl
wasm:
url: https://github.com/TBD54566975/ftl/releases/download/ **<release-version>** /sqlc-gen-ftl.wasm
sha256: <calculated-sha256>
sql:
- schema: schema.sql
queries: queries.sql
engine: postgresql
codegen:
- out: **<build-directory>**
plugin: sqlc-gen-ftl
options:
module: **<module-name>**
```
*(more on the WASM plugin below)*
The plugin converts SQL to FTL schema protos and writes the result to the module build directory. The schema is then read and validated before being sent to a new `GenerateQueries` API on the language plugin.
The language plugin forwards this request to the runtime service.
### 3. Runtime Service
The runtime service generates language-specific types (e.g. Go structs, Python classes) from the schema proto and provides them in `queries.ftl.go` in the root module directory.
---
### sqlc-gen-ftl Plugin Implementation
sqlc supports [custom plugins](https://docs.sqlc.dev/en/stable/guides/plugins.html#) that can process its intermediate representation (IR) to generate files. Plugins can be:
**Process-based**: Standalone executables that interact with sqlc via proto over stdin/stdout.
**WASM-based**: Sandboxed plugins written in languages that compile to WebAssembly.
We can host the plugin as WASM using GH Releases. WASM plugins are more portable compared with process-based plugins, which require managing and distributing platform-specific binaries.
Suggested type mappings:
| **SQL** | **FTL** |
|------------------|--------------|
| `INTEGER` | `Int` |
| `BIGINT` | `Int` |
| `SMALLINT` | `Int` |
| `SERIAL` | `Int` |
| `BIGSERIAL` | `Int` |
| `REAL` | `Float` |
| `FLOAT` | `Float` |
| `DOUBLE` | `Float` |
| `NUMERIC` | `Float` |
| `DECIMAL` | `Float` |
| `TEXT` | `String` |
| `VARCHAR` | `String` |
| `CHAR` | `String` |
| `UUID` | `String` |
| `BOOLEAN` | `Bool` |
| `TIMESTAMP` | `Time` |
| `DATE` | `Time` |
| `TIME` | `Time` |
| `JSON` | `Any` |
| `JSONB` | `Any` |
| `BYTEA` | `Bytes` |
| `BLOB` | `Bytes` |
*-should JSON be bytes or Any?*