diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py b/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py index 47bd6a9..9cf3f72 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py +++ b/internal/endtoend/testdata/query_parameter_limit_zero/python/query.py @@ -3,6 +3,7 @@ # sqlc v1.28.0 # source: query.sql import dataclasses +from typing import Optional import sqlalchemy import sqlalchemy.ext.asyncio @@ -10,6 +11,16 @@ from querytest import models +COUNT_BARS = """-- name: count_bars \\:one +SELECT count(*) FROM bar +""" + + +@dataclasses.dataclass() +class CountBarsParams: + pass + + DELETE_BAR_BY_ID = """-- name: delete_bar_by_id \\:execrows DELETE FROM bar WHERE id = :p1 """ @@ -35,6 +46,12 @@ class Querier: def __init__(self, conn: sqlalchemy.engine.Connection): self._conn = conn + def count_bars(self, arg: CountBarsParams) -> Optional[int]: + row = self._conn.execute(sqlalchemy.text(COUNT_BARS), {}).first() + if row is None: + return None + return row[0] + def delete_bar_by_id(self, arg: DeleteBarByIDParams) -> int: result = self._conn.execute(sqlalchemy.text(DELETE_BAR_BY_ID), {"p1": arg.id}) return result.rowcount @@ -48,6 +65,12 @@ class AsyncQuerier: def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection): self._conn = conn + async def count_bars(self, arg: CountBarsParams) -> Optional[int]: + row = (await self._conn.execute(sqlalchemy.text(COUNT_BARS), {})).first() + if row is None: + return None + return row[0] + async def delete_bar_by_id(self, arg: DeleteBarByIDParams) -> int: result = await self._conn.execute(sqlalchemy.text(DELETE_BAR_BY_ID), {"p1": arg.id}) return result.rowcount diff --git a/internal/endtoend/testdata/query_parameter_limit_zero/query.sql b/internal/endtoend/testdata/query_parameter_limit_zero/query.sql index b96c66b..62ff800 100644 --- a/internal/endtoend/testdata/query_parameter_limit_zero/query.sql +++ b/internal/endtoend/testdata/query_parameter_limit_zero/query.sql @@ -3,3 +3,6 @@ DELETE FROM bar WHERE id = $1; -- name: DeleteBarByIDAndName :execrows DELETE FROM bar WHERE id = $1 AND name = $2; + +-- name: CountBars :one +SELECT count(*) FROM bar; diff --git a/internal/printer/printer.go b/internal/printer/printer.go index 0660c6a..2d93dc4 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -238,6 +238,11 @@ func (w *writer) printClassDef(cd *ast.ClassDef, indent int32) { w.print(")") } w.print(":\n") + if len(cd.Body) == 0 { + w.printIndent(indent + 1) + w.print("pass\n") + return + } for i, node := range cd.Body { if i != 0 { if _, ok := node.Node.(*ast.Node_FunctionDef); ok { diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go index 21823f9..bb49500 100644 --- a/internal/printer/printer_test.go +++ b/internal/printer/printer_test.go @@ -68,7 +68,10 @@ func TestPrinter(t *testing.T) { }, }, }, - Expected: `class Foo(str, enum.Enum):`, + Expected: ` +class Foo(str, enum.Enum): + pass +`, }, "dataclass": { Node: &ast.Node{ @@ -125,6 +128,29 @@ func TestPrinter(t *testing.T) { class Foo: bar: int bat: Optional[int] +`, + }, + "empty-dataclass": { + Node: &ast.Node{ + Node: &ast.Node_ClassDef{ + ClassDef: &ast.ClassDef{ + Name: "Foo", + DecoratorList: []*ast.Node{ + { + Node: &ast.Node_Name{ + Name: &ast.Name{ + Id: "dataclass", + }, + }, + }, + }, + }, + }, + }, + Expected: ` +@dataclass +class Foo: + pass `, }, "call": {