Skip to content

Commit 62fb9cb

Browse files
authored
test: Add end-to-end tests and examples (#29)
These tests and examples were pulled from the sqlc directory. We'll continue to make sure to run these tests are part of the build on the main repository to make sure we don't break anything.
1 parent 8b3fe83 commit 62fb9cb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2239
-9
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
name: make
1+
name: go
22
on:
33
push:
44
branches:
55
- main
66
pull_request:
77
jobs:
8-
build:
8+
test:
99
name: test
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@v4
1313
- uses: actions/setup-go@v4
1414
with:
15-
go-version: '1.21.0'
15+
go-version: '1.21'
16+
- uses: sqlc-dev/setup-sqlc@v4
17+
with:
18+
sqlc-version: '1.23.0'
1619
- run: make
20+
- run: make test
21+
- run: sqlc diff
22+
working-directory: examples

.github/workflows/db.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: db
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
jobs:
8+
9+
build:
10+
name: test
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
postgres:
15+
image: postgres:11
16+
env:
17+
POSTGRES_USER: postgres
18+
POSTGRES_PASSWORD: postgres
19+
POSTGRES_DB: postgres
20+
ports:
21+
- 5432:5432
22+
# needed because the postgres container does not provide a healthcheck
23+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: actions/setup-python@v4
28+
with:
29+
python-version: 3.9
30+
- name: Install python dependencies
31+
working-directory: ./examples
32+
run: |
33+
python -m pip install --upgrade pip
34+
python -m pip install -r requirements.txt
35+
- name: Test python code
36+
working-directory: ./examples
37+
env:
38+
PG_USER: postgres
39+
PG_HOST: localhost
40+
PG_DATABASE: postgres
41+
PG_PASSWORD: postgres
42+
PG_PORT: ${{ job.services.postgres.ports['5432'] }}
43+
run: |
44+
pytest src/tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bin

Makefile

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
all: sqlc-gen-python sqlc-gen-python.wasm
1+
.PHONY: build test
22

3-
sqlc-gen-python:
4-
cd plugin && go build -o ~/bin/sqlc-gen-python ./main.go
3+
build:
4+
go build ./...
55

6-
sqlc-gen-python.wasm:
7-
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o sqlc-gen-python.wasm main.go
8-
openssl sha256 plugin/sqlc-gen-python.wasm
6+
test: bin/sqlc-gen-python.wasm
7+
go test ./...
8+
9+
all: bin/sqlc-gen-python bin/sqlc-gen-python.wasm
10+
11+
bin/sqlc-gen-python: bin go.mod go.sum $(wildcard **/*.go)
12+
cd plugin && go build -o ../bin/sqlc-gen-python ./main.go
13+
14+
bin/sqlc-gen-python.wasm: bin/sqlc-gen-python
15+
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o ../bin/sqlc-gen-python.wasm main.go
16+
17+
bin:
18+
mkdir -p bin

examples/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pytest~=6.2.2
2+
pytest-asyncio~=0.14.0
3+
psycopg2-binary~=2.8.6
4+
asyncpg~=0.21.0
5+
sqlalchemy==1.4.0

examples/sqlc.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
version: '2'
2+
plugins:
3+
- name: py
4+
wasm:
5+
url: https://downloads.sqlc.dev/plugin/sqlc-gen-python_1.1.0.wasm
6+
sha256: ef58f143a8c116781091441770c7166caaf361dd645f62b8f05f462e9f95c3b2
7+
sql:
8+
- schema: "src/authors/schema.sql"
9+
queries: "src/authors/query.sql"
10+
engine: postgresql
11+
codegen:
12+
- out: src/authors
13+
plugin: py
14+
options:
15+
package: authors
16+
emit_sync_querier: true
17+
emit_async_querier: true
18+
query_parameter_limit: 5
19+
- schema: "src/booktest/schema.sql"
20+
queries: "src/booktest/query.sql"
21+
engine: postgresql
22+
codegen:
23+
- out: src/booktest
24+
plugin: py
25+
options:
26+
package: booktest
27+
emit_async_querier: true
28+
query_parameter_limit: 5
29+
- schema: "src/jets/schema.sql"
30+
queries: "src/jets/query-building.sql"
31+
engine: postgresql
32+
codegen:
33+
- out: src/jets
34+
plugin: py
35+
options:
36+
package: jets
37+
emit_async_querier: true
38+
query_parameter_limit: 5
39+
- schema: "src/ondeck/schema"
40+
queries: "src/ondeck/query"
41+
engine: postgresql
42+
codegen:
43+
- out: src/ondeck
44+
plugin: py
45+
options:
46+
package: ondeck
47+
emit_async_querier: true
48+
query_parameter_limit: 5

examples/src/authors/__init__.py

Whitespace-only changes.

examples/src/authors/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
from typing import Optional
6+
7+
8+
@dataclasses.dataclass()
9+
class Author:
10+
id: int
11+
name: str
12+
bio: Optional[str]

examples/src/authors/query.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
# source: query.sql
5+
from typing import AsyncIterator, Iterator, Optional
6+
7+
import sqlalchemy
8+
import sqlalchemy.ext.asyncio
9+
10+
from authors import models
11+
12+
13+
CREATE_AUTHOR = """-- name: create_author \\:one
14+
INSERT INTO authors (
15+
name, bio
16+
) VALUES (
17+
:p1, :p2
18+
)
19+
RETURNING id, name, bio
20+
"""
21+
22+
23+
DELETE_AUTHOR = """-- name: delete_author \\:exec
24+
DELETE FROM authors
25+
WHERE id = :p1
26+
"""
27+
28+
29+
GET_AUTHOR = """-- name: get_author \\:one
30+
SELECT id, name, bio FROM authors
31+
WHERE id = :p1 LIMIT 1
32+
"""
33+
34+
35+
LIST_AUTHORS = """-- name: list_authors \\:many
36+
SELECT id, name, bio FROM authors
37+
ORDER BY name
38+
"""
39+
40+
41+
class Querier:
42+
def __init__(self, conn: sqlalchemy.engine.Connection):
43+
self._conn = conn
44+
45+
def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
46+
row = self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio}).first()
47+
if row is None:
48+
return None
49+
return models.Author(
50+
id=row[0],
51+
name=row[1],
52+
bio=row[2],
53+
)
54+
55+
def delete_author(self, *, id: int) -> None:
56+
self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
57+
58+
def get_author(self, *, id: int) -> Optional[models.Author]:
59+
row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first()
60+
if row is None:
61+
return None
62+
return models.Author(
63+
id=row[0],
64+
name=row[1],
65+
bio=row[2],
66+
)
67+
68+
def list_authors(self) -> Iterator[models.Author]:
69+
result = self._conn.execute(sqlalchemy.text(LIST_AUTHORS))
70+
for row in result:
71+
yield models.Author(
72+
id=row[0],
73+
name=row[1],
74+
bio=row[2],
75+
)
76+
77+
78+
class AsyncQuerier:
79+
def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
80+
self._conn = conn
81+
82+
async def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
83+
row = (await self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio})).first()
84+
if row is None:
85+
return None
86+
return models.Author(
87+
id=row[0],
88+
name=row[1],
89+
bio=row[2],
90+
)
91+
92+
async def delete_author(self, *, id: int) -> None:
93+
await self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
94+
95+
async def get_author(self, *, id: int) -> Optional[models.Author]:
96+
row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first()
97+
if row is None:
98+
return None
99+
return models.Author(
100+
id=row[0],
101+
name=row[1],
102+
bio=row[2],
103+
)
104+
105+
async def list_authors(self) -> AsyncIterator[models.Author]:
106+
result = await self._conn.stream(sqlalchemy.text(LIST_AUTHORS))
107+
async for row in result:
108+
yield models.Author(
109+
id=row[0],
110+
name=row[1],
111+
bio=row[2],
112+
)

examples/src/authors/query.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- name: GetAuthor :one
2+
SELECT * FROM authors
3+
WHERE id = $1 LIMIT 1;
4+
5+
-- name: ListAuthors :many
6+
SELECT * FROM authors
7+
ORDER BY name;
8+
9+
-- name: CreateAuthor :one
10+
INSERT INTO authors (
11+
name, bio
12+
) VALUES (
13+
$1, $2
14+
)
15+
RETURNING *;
16+
17+
-- name: DeleteAuthor :exec
18+
DELETE FROM authors
19+
WHERE id = $1;

examples/src/authors/schema.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE authors (
2+
id BIGSERIAL PRIMARY KEY,
3+
name text NOT NULL,
4+
bio text
5+
);

examples/src/booktest/__init__.py

Whitespace-only changes.

examples/src/booktest/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
import datetime
6+
import enum
7+
from typing import List
8+
9+
10+
class BookType(str, enum.Enum):
11+
FICTION = "FICTION"
12+
NONFICTION = "NONFICTION"
13+
14+
15+
@dataclasses.dataclass()
16+
class Author:
17+
author_id: int
18+
name: str
19+
20+
21+
@dataclasses.dataclass()
22+
class Book:
23+
book_id: int
24+
author_id: int
25+
isbn: str
26+
book_type: BookType
27+
title: str
28+
year: int
29+
available: datetime.datetime
30+
tags: List[str]

0 commit comments

Comments
 (0)