Skip to content

Commit

Permalink
test: Add end-to-end tests and examples (#29)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kyleconroy authored Nov 1, 2023
1 parent 8b3fe83 commit 62fb9cb
Show file tree
Hide file tree
Showing 78 changed files with 2,239 additions and 9 deletions.
12 changes: 9 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
name: make
name: go
on:
push:
branches:
- main
pull_request:
jobs:
build:
test:
name: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: '1.21.0'
go-version: '1.21'
- uses: sqlc-dev/setup-sqlc@v4
with:
sqlc-version: '1.23.0'
- run: make
- run: make test
- run: sqlc diff
working-directory: examples
44 changes: 44 additions & 0 deletions .github/workflows/db.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: db
on:
push:
branches:
- main
pull_request:
jobs:

build:
name: test
runs-on: ubuntu-latest

services:
postgres:
image: postgres:11
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install python dependencies
working-directory: ./examples
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: Test python code
working-directory: ./examples
env:
PG_USER: postgres
PG_HOST: localhost
PG_DATABASE: postgres
PG_PASSWORD: postgres
PG_PORT: ${{ job.services.postgres.ports['5432'] }}
run: |
pytest src/tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin
22 changes: 16 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
all: sqlc-gen-python sqlc-gen-python.wasm
.PHONY: build test

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

sqlc-gen-python.wasm:
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o sqlc-gen-python.wasm main.go
openssl sha256 plugin/sqlc-gen-python.wasm
test: bin/sqlc-gen-python.wasm
go test ./...

all: bin/sqlc-gen-python bin/sqlc-gen-python.wasm

bin/sqlc-gen-python: bin go.mod go.sum $(wildcard **/*.go)
cd plugin && go build -o ../bin/sqlc-gen-python ./main.go

bin/sqlc-gen-python.wasm: bin/sqlc-gen-python
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o ../bin/sqlc-gen-python.wasm main.go

bin:
mkdir -p bin
5 changes: 5 additions & 0 deletions examples/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pytest~=6.2.2
pytest-asyncio~=0.14.0
psycopg2-binary~=2.8.6
asyncpg~=0.21.0
sqlalchemy==1.4.0
48 changes: 48 additions & 0 deletions examples/sqlc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: '2'
plugins:
- name: py
wasm:
url: https://downloads.sqlc.dev/plugin/sqlc-gen-python_1.1.0.wasm
sha256: ef58f143a8c116781091441770c7166caaf361dd645f62b8f05f462e9f95c3b2
sql:
- schema: "src/authors/schema.sql"
queries: "src/authors/query.sql"
engine: postgresql
codegen:
- out: src/authors
plugin: py
options:
package: authors
emit_sync_querier: true
emit_async_querier: true
query_parameter_limit: 5
- schema: "src/booktest/schema.sql"
queries: "src/booktest/query.sql"
engine: postgresql
codegen:
- out: src/booktest
plugin: py
options:
package: booktest
emit_async_querier: true
query_parameter_limit: 5
- schema: "src/jets/schema.sql"
queries: "src/jets/query-building.sql"
engine: postgresql
codegen:
- out: src/jets
plugin: py
options:
package: jets
emit_async_querier: true
query_parameter_limit: 5
- schema: "src/ondeck/schema"
queries: "src/ondeck/query"
engine: postgresql
codegen:
- out: src/ondeck
plugin: py
options:
package: ondeck
emit_async_querier: true
query_parameter_limit: 5
Empty file.
12 changes: 12 additions & 0 deletions examples/src/authors/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.23.0
import dataclasses
from typing import Optional


@dataclasses.dataclass()
class Author:
id: int
name: str
bio: Optional[str]
112 changes: 112 additions & 0 deletions examples/src/authors/query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.23.0
# source: query.sql
from typing import AsyncIterator, Iterator, Optional

import sqlalchemy
import sqlalchemy.ext.asyncio

from authors import models


CREATE_AUTHOR = """-- name: create_author \\:one
INSERT INTO authors (
name, bio
) VALUES (
:p1, :p2
)
RETURNING id, name, bio
"""


DELETE_AUTHOR = """-- name: delete_author \\:exec
DELETE FROM authors
WHERE id = :p1
"""


GET_AUTHOR = """-- name: get_author \\:one
SELECT id, name, bio FROM authors
WHERE id = :p1 LIMIT 1
"""


LIST_AUTHORS = """-- name: list_authors \\:many
SELECT id, name, bio FROM authors
ORDER BY name
"""


class Querier:
def __init__(self, conn: sqlalchemy.engine.Connection):
self._conn = conn

def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
row = self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio}).first()
if row is None:
return None
return models.Author(
id=row[0],
name=row[1],
bio=row[2],
)

def delete_author(self, *, id: int) -> None:
self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})

def get_author(self, *, id: int) -> Optional[models.Author]:
row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first()
if row is None:
return None
return models.Author(
id=row[0],
name=row[1],
bio=row[2],
)

def list_authors(self) -> Iterator[models.Author]:
result = self._conn.execute(sqlalchemy.text(LIST_AUTHORS))
for row in result:
yield models.Author(
id=row[0],
name=row[1],
bio=row[2],
)


class AsyncQuerier:
def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
self._conn = conn

async def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
row = (await self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio})).first()
if row is None:
return None
return models.Author(
id=row[0],
name=row[1],
bio=row[2],
)

async def delete_author(self, *, id: int) -> None:
await self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})

async def get_author(self, *, id: int) -> Optional[models.Author]:
row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first()
if row is None:
return None
return models.Author(
id=row[0],
name=row[1],
bio=row[2],
)

async def list_authors(self) -> AsyncIterator[models.Author]:
result = await self._conn.stream(sqlalchemy.text(LIST_AUTHORS))
async for row in result:
yield models.Author(
id=row[0],
name=row[1],
bio=row[2],
)
19 changes: 19 additions & 0 deletions examples/src/authors/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;

-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;

-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
)
RETURNING *;

-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1;
5 changes: 5 additions & 0 deletions examples/src/authors/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE authors (
id BIGSERIAL PRIMARY KEY,
name text NOT NULL,
bio text
);
Empty file.
30 changes: 30 additions & 0 deletions examples/src/booktest/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Code generated by sqlc. DO NOT EDIT.
# versions:
# sqlc v1.23.0
import dataclasses
import datetime
import enum
from typing import List


class BookType(str, enum.Enum):
FICTION = "FICTION"
NONFICTION = "NONFICTION"


@dataclasses.dataclass()
class Author:
author_id: int
name: str


@dataclasses.dataclass()
class Book:
book_id: int
author_id: int
isbn: str
book_type: BookType
title: str
year: int
available: datetime.datetime
tags: List[str]
Loading

0 comments on commit 62fb9cb

Please sign in to comment.