https://github.com/fdietze/sqlc-gen-from-template
sqlc plugin to generate type-safe code for SQL queries using a template.
https://github.com/fdietze/sqlc-gen-from-template
sql sqlc
Last synced: 11 months ago
JSON representation
sqlc plugin to generate type-safe code for SQL queries using a template.
- Host: GitHub
- URL: https://github.com/fdietze/sqlc-gen-from-template
- Owner: fdietze
- License: mit
- Created: 2024-08-03T22:08:46.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-04T13:06:00.000Z (12 months ago)
- Last Synced: 2025-04-04T22:45:36.755Z (11 months ago)
- Topics: sql, sqlc
- Language: Go
- Homepage:
- Size: 30.3 KB
- Stars: 16
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# sqlc-gen-from-template
[sqlc](https://sqlc.dev/) plugin to generate type-safe code for SQL queries using a template. More specifically, it provides the [protobuf data structures provided by sqlc](https://github.com/sqlc-dev/sqlc/blob/main/protos/plugin/codegen.proto) to a [go template](https://pkg.go.dev/text/template) to turn [every query in a SQL file](https://docs.sqlc.dev/en/stable/tutorials/getting-started-sqlite.html#schema-and-queries) into a function and return type data structure of your preferred programming language and database library.
## Installation
I recommend using [devbox](https://www.jetpack.io/devbox) and installing this plugin into your project using a [nix flake](https://zero-to-nix.com/concepts/flakes):
```bash
# replace with the latest commit hash from this repo
devbox add sqlc github:fdietze/sqlc-gen-from-template/
```
Alternatively, you can build a binary yourself and put it into your `PATH`:
```bash
go build
```
Afterwards you can generate code with:
```bash
sqlc generate
```
## Contributions
Don't hesitate to ask any questions or present your ideas in the issues. Contributions are welcome!
## Language Support
See the [templates](./templates) directory for supported languages and database library combinations.
## Usage
Example usage for [Scala](https://www.scala-lang.org/) with the [magnum](https://github.com/AugustNagro/magnum) database library:
`sqlc.yml`
```yml
version: "2"
plugins:
- name: sqlc-gen-from-template
process:
cmd: sqlc-gen-from-template # https://github.com/fdietze/sqlc-gen-from-template
sql:
- engine: "sqlite"
queries: "queries.sql"
schema: "schema.sql"
codegen:
- out: backend/src/backend/queries
plugin: sqlc-gen-from-template
options:
template: "query_template.go.tmpl"
filename: "Queries.scala"
# optional formatter command to format generated code
formatter_cmd: ".devbox/nix/profile/default/bin/scalafmt --stdin"
```
`schema.sql`
```sql
create table post(
id integer primary key autoincrement -- rowid
, parent_id integer
) strict;
```
`queries.sql`
```sql
-- name: getReplyIds :many
select id
from post
where parent_id = ?;
```
`query_template.go.tmpl`
```tmpl
{{- /*
https://pkg.go.dev/text/template
https://github.com/sqlc-dev/sqlc/blob/main/protos/plugin/codegen.proto
https://github.com/AugustNagro/magnum?tab=readme-ov-file
*/ -}}
{{- define "ScalaType" -}}
{{- $scalaType := .Type.Name -}}
{{- if eq .Type.Name "INTEGER"}}{{ $scalaType = "Long" }}
{{- else if eq .Type.Name "TEXT"}}{{ $scalaType = "String" }}
{{- end -}}
{{- $scalaType }}
{{- end -}}
package backend.queries
import com.augustnagro.magnum
import com.augustnagro.magnum.*
{{- range .Queries }}
{{range .Comments}}// {{.}}
{{end}}
{{$rowType := printf "Row_%s" .Name -}}
{{- if or (eq .Cmd ":many") (eq .Cmd ":one") }}
{{- if gt (len .Columns) 1 -}}
case class {{ $rowType }}({{- range .Columns}}
{{.Name}}:
{{- if not .NotNull }}Option[{{end}}
{{- template "ScalaType" .}}
{{- if not .NotNull }}]{{end}},
{{- end}}
)
{{- else -}}
type {{ $rowType }} =
{{- if not (index .Columns 0).NotNull }}Option[{{end}}
{{- template "ScalaType" (index .Columns 0) }}
{{- if not (index .Columns 0).NotNull }}]{{end}}
{{- end}}
{{end}}
{{- $returnType := "__DEFAULT__" -}}
{{- if eq .Cmd ":exec" }}
{{- $returnType = "Unit" -}}
{{- else if eq .Cmd ":many" }}
{{- $returnType = printf "Vector[%s]" $rowType -}}
{{- else if eq .Cmd ":one" }}
{{- $returnType = $rowType -}}
{{- else -}}
{{- $returnType = "__UNKNOWN_QUERY_ANNOTATION__" -}}
{{- end -}}
def {{.Name}}({{range .Params}}
{{.Column.Name}}:{{template "ScalaType" .Column}},
{{- end}}
)(using con: DbCon): {{ $returnType }} = {
Frag("""
{{ .Text }}
""", params = IArray({{range .Params}}
{{.Column.Name}},
{{end}}))
{{- if eq .Cmd ":exec" }}.update.run(){{end}}
{{- if eq .Cmd ":many" }}.query[{{ $rowType }}].run(){{end}}
{{- if eq .Cmd ":one" }}.query[{{ $rowType }}].run().head{{end}}
}
{{- end -}}
```
Running `sqlc generate` generates:
`Queries.scala`
```scala
package backend.queries
import com.augustnagro.magnum
import com.augustnagro.magnum.*
type Row_getReplyIds = Long
def getReplyIds(
parent_id: Long
)(using con: DbCon): Vector[Row_getReplyIds] = {
Frag(
"""
select id
from post
where parent_id = ?
""",
params = IArray(
parent_id
),
).query[Row_getReplyIds].run()
}
```
# Related Projects
- [cornerman/scala-db-codegen](https://github.com/cornerman/scala-db-codegen)