diff --git a/example/db/query.postgres.sql b/example/db/query.postgres.sql index 1e72b34..b69a9a6 100644 --- a/example/db/query.postgres.sql +++ b/example/db/query.postgres.sql @@ -58,7 +58,7 @@ VALUES ($1, $2); -- INSERT INTO book_tags ("book_id", "tag_id") VALUES (unnest($1::bigint[]), unnest($2::bigint[])) -- @bulk-for AddBookTag INSERT INTO book_tags ("book_id", "tag_id") -VALUES (unnest($1::bigint[]), unnest($2::bigint[])); +VALUES (unnest(sqlc.arg(book_ids)::bigint[]), unnest(sqlc.arg(tag_ids)::bigint[])); -- name: GetBookTags :many -- SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = $1 diff --git a/example/go.mod b/example/go.mod index f787bbe..ea8f094 100644 --- a/example/go.mod +++ b/example/go.mod @@ -1,12 +1,13 @@ module github.com/kalbasit/sqlc-multi-db/example -go 1.25.5 +go 1.25.7 tool github.com/kalbasit/sqlc-multi-db require ( github.com/go-sql-driver/mysql v1.9.2 github.com/jackc/pgx/v5 v5.7.4 + github.com/lib/pq v1.12.0 github.com/mattn/go-sqlite3 v1.14.28 ) diff --git a/example/go.sum b/example/go.sum index d56e9f6..05efbd9 100644 --- a/example/go.sum +++ b/example/go.sum @@ -23,6 +23,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= +github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/example/pkg/database/database.go b/example/pkg/database/database.go index 41899a2..5c80ebd 100644 --- a/example/pkg/database/database.go +++ b/example/pkg/database/database.go @@ -1,3 +1,4 @@ +//go:generate go tool sqlc-multi-db --engine sqlite:sqlitedb --engine postgres:postgresdb --engine mysql:mysqldb postgresdb/querier.go package database import ( @@ -16,19 +17,23 @@ import ( ) // Open opens a database connection and returns a Querier. -// URL schemes: sqlite:/, postgresql://, mysql:// +// URL schemes: sqlite:/, postgresql://, mysql://. func Open(ctx context.Context, dbURL string) (Querier, error) { switch { case strings.HasPrefix(dbURL, "sqlite:"): path := strings.TrimPrefix(dbURL, "sqlite:") + sdb, err := sql.Open("sqlite3", path) if err != nil { return nil, fmt.Errorf("opening sqlite: %w", err) } + sdb.SetMaxOpenConns(1) + if _, err := sdb.ExecContext(ctx, "PRAGMA foreign_keys = ON"); err != nil { return nil, fmt.Errorf("enabling foreign keys: %w", err) } + return &sqliteWrapper{adapter: sqlitedb.NewAdapter(sdb)}, nil case strings.HasPrefix(dbURL, "postgres://"), strings.HasPrefix(dbURL, "postgresql://"): @@ -36,14 +41,17 @@ func Open(ctx context.Context, dbURL string) (Querier, error) { if err != nil { return nil, fmt.Errorf("opening postgres: %w", err) } + return &postgresWrapper{adapter: postgresdb.NewAdapter(sdb)}, nil case strings.HasPrefix(dbURL, "mysql://"): dsn := strings.TrimPrefix(dbURL, "mysql://") + sdb, err := sql.Open("mysql", dsn) if err != nil { return nil, fmt.Errorf("opening mysql: %w", err) } + return &mysqlWrapper{adapter: mysqldb.NewAdapter(sdb)}, nil default: diff --git a/example/pkg/database/generate.go b/example/pkg/database/generate.go deleted file mode 100644 index fff7b3d..0000000 --- a/example/pkg/database/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package database - -//go:generate go tool github.com/kalbasit/sqlc-multi-db postgresdb/querier.go diff --git a/example/pkg/database/generated_models.go b/example/pkg/database/generated_models.go index 5096abf..524cd4b 100644 --- a/example/pkg/database/generated_models.go +++ b/example/pkg/database/generated_models.go @@ -12,8 +12,8 @@ type AddBookTagParams struct { } type AddBookTagsParams struct { - BookID []int64 - TagID []int64 + BookIds []int64 + TagIds []int64 } type Book struct { diff --git a/example/pkg/database/generated_querier.go b/example/pkg/database/generated_querier.go index 20b3a6f..e560b94 100644 --- a/example/pkg/database/generated_querier.go +++ b/example/pkg/database/generated_querier.go @@ -7,43 +7,78 @@ import ( ) type Querier interface { - // AddBookTag adds a tag to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES ($1, $2) + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES ($1, $2) AddBookTag(ctx context.Context, arg AddBookTagParams) error - // AddBookTags adds multiple tags to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES (unnest($1::bigint[]), unnest($2::bigint[])) // @bulk-for AddBookTag + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES (unnest($1::bigint[]), unnest($2::bigint[])) AddBookTags(ctx context.Context, arg AddBookTagsParams) error - // CreateBook creates a new book. // INSERT INTO books ("title", "author", "description") VALUES ($1, $2, $3) RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // INSERT INTO books ("title", "author", "description") + // VALUES ($1, $2, $3) + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" CreateBook(ctx context.Context, arg CreateBookParams) (Book, error) - // CreateTag creates a new tag. // INSERT INTO tags ("name") VALUES ($1) RETURNING "id", "name", "created_at", "updated_at" + // + // INSERT INTO tags ("name") + // VALUES ($1) + // RETURNING "id", "name", "created_at", "updated_at" CreateTag(ctx context.Context, name string) (Tag, error) - // DeleteBook deletes a book by ID. // DELETE FROM books WHERE id = $1 + // + // DELETE FROM books + // WHERE id = $1 DeleteBook(ctx context.Context, id int64) error - // GetBook retrieves a book by ID. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = $1 + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE id = $1 GetBook(ctx context.Context, id int64) (Book, error) // GetBookByID (Synthetic) GetBookByID(ctx context.Context, id int64) (Book, error) - // GetBookTags retrieves all tags for a book. // SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = $1 + // + // SELECT t."id", t."name", t."created_at", t."updated_at" + // FROM tags t + // INNER JOIN book_tags bt ON t.id = bt.tag_id + // WHERE bt.book_id = $1 GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) - // GetBooksByAuthor retrieves all books by an author. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = $1 + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE author = $1 GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) - // GetTag retrieves a tag by ID. // SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = $1 + // + // SELECT "id", "name", "created_at", "updated_at" + // FROM tags + // WHERE id = $1 GetTag(ctx context.Context, id int64) (Tag, error) // GetTagByID (Synthetic) GetTagByID(ctx context.Context, id int64) (Tag, error) - // ListBooks retrieves all books. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // ORDER BY title ListBooks(ctx context.Context) ([]Book, error) - // UpdateBook updates a book. // UPDATE books SET "title" = $1, "author" = $2, "description" = $3, "updated_at" = NOW() WHERE id = $4 RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // UPDATE books + // SET "title" = $1, + // "author" = $2, + // "description" = $3, + // "updated_at" = NOW() + // WHERE id = $4 + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" UpdateBook(ctx context.Context, arg UpdateBookParams) (Book, error) WithTx(tx *sql.Tx) Querier diff --git a/example/pkg/database/generated_wrapper_mysql.go b/example/pkg/database/generated_wrapper_mysql.go index 953e72a..94cfb3a 100644 --- a/example/pkg/database/generated_wrapper_mysql.go +++ b/example/pkg/database/generated_wrapper_mysql.go @@ -1,4 +1,5 @@ // Code generated by sqlc-multi-db. DO NOT EDIT. + package database import ( @@ -26,15 +27,15 @@ func (w *mysqlWrapper) AddBookTag(ctx context.Context, arg AddBookTagParams) err func (w *mysqlWrapper) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { /* --- Auto-Loop for Bulk Insert on Non-Postgres --- */ - if len(arg.TagID) != len(arg.BookID) { + if len(arg.TagIds) != len(arg.BookIds) { return ErrMismatchedSlices } - for i, v := range arg.BookID { + for i, v := range arg.BookIds { _ = i err := w.adapter.AddBookTag(ctx, mysqldb.AddBookTagParams{ BookID: v, - TagID: arg.TagID[i], + TagID: arg.TagIds[i], }, ) if err != nil { diff --git a/example/pkg/database/generated_wrapper_postgres.go b/example/pkg/database/generated_wrapper_postgres.go index 0ca41ab..99212e2 100644 --- a/example/pkg/database/generated_wrapper_postgres.go +++ b/example/pkg/database/generated_wrapper_postgres.go @@ -1,4 +1,7 @@ // Code generated by sqlc-multi-db. DO NOT EDIT. + +//go:build !js + package database import ( @@ -26,13 +29,13 @@ func (w *postgresWrapper) AddBookTag(ctx context.Context, arg AddBookTagParams) func (w *postgresWrapper) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { /* --- Auto-Loop for Bulk Insert on Non-Postgres --- */ - if len(arg.TagID) != len(arg.BookID) { + if len(arg.TagIds) != len(arg.BookIds) { return ErrMismatchedSlices } return w.adapter.AddBookTags(ctx, postgresdb.AddBookTagsParams{ - BookID: arg.BookID, - TagID: arg.TagID, + BookIds: arg.BookIds, + TagIds: arg.TagIds, }) } diff --git a/example/pkg/database/generated_wrapper_sqlite.go b/example/pkg/database/generated_wrapper_sqlite.go index fbeb0b2..f36438b 100644 --- a/example/pkg/database/generated_wrapper_sqlite.go +++ b/example/pkg/database/generated_wrapper_sqlite.go @@ -1,4 +1,5 @@ // Code generated by sqlc-multi-db. DO NOT EDIT. + package database import ( @@ -26,15 +27,15 @@ func (w *sqliteWrapper) AddBookTag(ctx context.Context, arg AddBookTagParams) er func (w *sqliteWrapper) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { /* --- Auto-Loop for Bulk Insert on Non-Postgres --- */ - if len(arg.TagID) != len(arg.BookID) { + if len(arg.TagIds) != len(arg.BookIds) { return ErrMismatchedSlices } - for i, v := range arg.BookID { + for i, v := range arg.BookIds { _ = i err := w.adapter.AddBookTag(ctx, sqlitedb.AddBookTagParams{ BookID: v, - TagID: arg.TagID[i], + TagID: arg.TagIds[i], }, ) if err != nil { diff --git a/example/pkg/database/mysqldb/db.go b/example/pkg/database/mysqldb/db.go index 046c88e..0698f03 100644 --- a/example/pkg/database/mysqldb/db.go +++ b/example/pkg/database/mysqldb/db.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package mysqldb diff --git a/example/pkg/database/mysqldb/models.go b/example/pkg/database/mysqldb/models.go index 0b698f8..1cd9bed 100644 --- a/example/pkg/database/mysqldb/models.go +++ b/example/pkg/database/mysqldb/models.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package mysqldb @@ -16,6 +18,11 @@ type Book struct { UpdatedAt time.Time } +type BookTag struct { + BookID int64 + TagID int64 +} + type Tag struct { ID int64 Name string diff --git a/example/pkg/database/mysqldb/querier.go b/example/pkg/database/mysqldb/querier.go index b587c23..e009fce 100644 --- a/example/pkg/database/mysqldb/querier.go +++ b/example/pkg/database/mysqldb/querier.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package mysqldb @@ -8,48 +10,72 @@ import ( ) type Querier interface { - // AddBookTag adds a tag to a book. // INSERT INTO book_tags (`book_id`, `tag_id`) VALUES (?, ?) + // + // INSERT INTO book_tags (`book_id`, `tag_id`) + // VALUES (?, ?) AddBookTag(ctx context.Context, arg AddBookTagParams) error - - // AddBookTags adds multiple tags to a book. // INSERT INTO book_tags (`book_id`, `tag_id`) VALUES (?, ?) // @bulk-for AddBookTag + // + // INSERT INTO book_tags (`book_id`, `tag_id`) + // VALUES (?, ?) AddBookTags(ctx context.Context, arg AddBookTagsParams) error - - // CreateBook creates a new book. // INSERT INTO books (`title`, `author`, `description`) VALUES (?, ?, ?) + // + // INSERT INTO books (`title`, `author`, `description`) + // VALUES (?, ?, ?) CreateBook(ctx context.Context, arg CreateBookParams) (sql.Result, error) - - // CreateTag creates a new tag. // INSERT INTO tags (`name`) VALUES (?) + // + // INSERT INTO tags (`name`) + // VALUES (?) CreateTag(ctx context.Context, name string) (sql.Result, error) - - // DeleteBook deletes a book by ID. // DELETE FROM books WHERE id = ? + // + // DELETE FROM books + // WHERE id = ? DeleteBook(ctx context.Context, id int64) error - - // GetBook retrieves a book by ID. // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books WHERE id = ? + // + // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` + // FROM books + // WHERE id = ? GetBook(ctx context.Context, id int64) (Book, error) - - // GetBookTags retrieves all tags for a book. // SELECT t.`id`, t.`name`, t.`created_at`, t.`updated_at` FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ? + // + // SELECT t.`id`, t.`name`, t.`created_at`, t.`updated_at` + // FROM tags t + // INNER JOIN book_tags bt ON t.id = bt.tag_id + // WHERE bt.book_id = ? GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) - - // GetBooksByAuthor retrieves all books by an author. // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books WHERE author = ? + // + // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` + // FROM books + // WHERE `author` = ? GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) - - // GetTag retrieves a tag by ID. // SELECT `id`, `name`, `created_at`, `updated_at` FROM tags WHERE id = ? + // + // SELECT `id`, `name`, `created_at`, `updated_at` + // FROM tags + // WHERE id = ? GetTag(ctx context.Context, id int64) (Tag, error) - - // ListBooks retrieves all books. // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books ORDER BY title + // + // SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` + // FROM books + // ORDER BY `title` ListBooks(ctx context.Context) ([]Book, error) - - // UpdateBook updates a book. // UPDATE books SET `title` = ?, `author` = ?, `description` = ?, `updated_at` = NOW() WHERE id = ? + // + // UPDATE books + // SET `title` = ?, + // `author` = ?, + // `description` = ?, + // `updated_at` = NOW() + // WHERE id = ? UpdateBook(ctx context.Context, arg UpdateBookParams) (sql.Result, error) } + +var _ Querier = (*Queries)(nil) diff --git a/example/pkg/database/mysqldb/query.mysql.sql.go b/example/pkg/database/mysqldb/query.mysql.sql.go index 612f3c0..49bd2c6 100644 --- a/example/pkg/database/mysqldb/query.mysql.sql.go +++ b/example/pkg/database/mysqldb/query.mysql.sql.go @@ -1,4 +1,7 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.mysql.sql package mysqldb @@ -7,80 +10,129 @@ import ( "database/sql" ) +const addBookTag = `-- name: AddBookTag :exec +INSERT INTO book_tags (` + "`" + `book_id` + "`" + `, ` + "`" + `tag_id` + "`" + `) +VALUES (?, ?) +` + type AddBookTagParams struct { BookID int64 TagID int64 } -type AddBookTagsParams struct { - BookID []int64 - TagID []int64 -} - -type CreateBookParams struct { - Title string - Author string - Description sql.NullString -} - -type UpdateBookParams struct { - Title string - Author string - Description sql.NullString - ID int64 -} - -const addBookTag = `-- name: AddBookTag :exec -INSERT INTO book_tags (` + "`" + `book_id` + "`" + `, ` + "`" + `tag_id` + "`" + `) VALUES (?, ?)` - +// INSERT INTO book_tags (`book_id`, `tag_id`) VALUES (?, ?) +// +// INSERT INTO book_tags (`book_id`, `tag_id`) +// VALUES (?, ?) func (q *Queries) AddBookTag(ctx context.Context, arg AddBookTagParams) error { _, err := q.db.ExecContext(ctx, addBookTag, arg.BookID, arg.TagID) return err } const addBookTags = `-- name: AddBookTags :exec -INSERT INTO book_tags (` + "`" + `book_id` + "`" + `, ` + "`" + `tag_id` + "`" + `) VALUES (?, ?)` +INSERT INTO book_tags (` + "`" + `book_id` + "`" + `, ` + "`" + `tag_id` + "`" + `) +VALUES (?, ?) +` + +type AddBookTagsParams struct { + BookID int64 + TagID int64 +} +// INSERT INTO book_tags (`book_id`, `tag_id`) VALUES (?, ?) +// @bulk-for AddBookTag +// +// INSERT INTO book_tags (`book_id`, `tag_id`) +// VALUES (?, ?) func (q *Queries) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { _, err := q.db.ExecContext(ctx, addBookTags, arg.BookID, arg.TagID) return err } const createBook = `-- name: CreateBook :execresult -INSERT INTO books (` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `) VALUES (?, ?, ?)` +INSERT INTO books (` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `) +VALUES (?, ?, ?) +` +type CreateBookParams struct { + Title string + Author string + Description sql.NullString +} + +// INSERT INTO books (`title`, `author`, `description`) VALUES (?, ?, ?) +// +// INSERT INTO books (`title`, `author`, `description`) +// VALUES (?, ?, ?) func (q *Queries) CreateBook(ctx context.Context, arg CreateBookParams) (sql.Result, error) { return q.db.ExecContext(ctx, createBook, arg.Title, arg.Author, arg.Description) } const createTag = `-- name: CreateTag :execresult -INSERT INTO tags (` + "`" + `name` + "`" + `) VALUES (?)` +INSERT INTO tags (` + "`" + `name` + "`" + `) +VALUES (?) +` +// INSERT INTO tags (`name`) VALUES (?) +// +// INSERT INTO tags (`name`) +// VALUES (?) func (q *Queries) CreateTag(ctx context.Context, name string) (sql.Result, error) { return q.db.ExecContext(ctx, createTag, name) } const deleteBook = `-- name: DeleteBook :exec -DELETE FROM books WHERE id = ?` +DELETE FROM books +WHERE id = ? +` +// DELETE FROM books WHERE id = ? +// +// DELETE FROM books +// WHERE id = ? func (q *Queries) DeleteBook(ctx context.Context, id int64) error { _, err := q.db.ExecContext(ctx, deleteBook, id) return err } const getBook = `-- name: GetBook :one -SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` FROM books WHERE id = ?` +SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` +FROM books +WHERE id = ? +` +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books WHERE id = ? +// +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` +// FROM books +// WHERE id = ? func (q *Queries) GetBook(ctx context.Context, id int64) (Book, error) { row := q.db.QueryRowContext(ctx, getBook, id) var i Book - err := row.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const getBookTags = `-- name: GetBookTags :many -SELECT t.` + "`" + `id` + "`" + `, t.` + "`" + `name` + "`" + `, t.` + "`" + `created_at` + "`" + `, t.` + "`" + `updated_at` + "`" + ` FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ?` +SELECT t.` + "`" + `id` + "`" + `, t.` + "`" + `name` + "`" + `, t.` + "`" + `created_at` + "`" + `, t.` + "`" + `updated_at` + "`" + ` +FROM tags t +INNER JOIN book_tags bt ON t.id = bt.tag_id +WHERE bt.book_id = ? +` +// SELECT t.`id`, t.`name`, t.`created_at`, t.`updated_at` FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ? +// +// SELECT t.`id`, t.`name`, t.`created_at`, t.`updated_at` +// FROM tags t +// INNER JOIN book_tags bt ON t.id = bt.tag_id +// WHERE bt.book_id = ? func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) { rows, err := q.db.QueryContext(ctx, getBookTags, bookID) if err != nil { @@ -90,17 +142,33 @@ func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) var items []Tag for rows.Next() { var i Tag - if err := rows.Scan(&i.ID, &i.Name, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const getBooksByAuthor = `-- name: GetBooksByAuthor :many -SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` FROM books WHERE author = ?` +SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` +FROM books +WHERE ` + "`" + `author` + "`" + ` = ? +` +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books WHERE author = ? +// +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` +// FROM books +// WHERE `author` = ? func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) { rows, err := q.db.QueryContext(ctx, getBooksByAuthor, author) if err != nil { @@ -110,27 +178,58 @@ func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, var items []Book for rows.Next() { var i Book - if err := rows.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const getTag = `-- name: GetTag :one -SELECT ` + "`" + `id` + "`" + `, ` + "`" + `name` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` FROM tags WHERE id = ?` +SELECT ` + "`" + `id` + "`" + `, ` + "`" + `name` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` +FROM tags +WHERE id = ? +` +// SELECT `id`, `name`, `created_at`, `updated_at` FROM tags WHERE id = ? +// +// SELECT `id`, `name`, `created_at`, `updated_at` +// FROM tags +// WHERE id = ? func (q *Queries) GetTag(ctx context.Context, id int64) (Tag, error) { row := q.db.QueryRowContext(ctx, getTag, id) var i Tag - err := row.Scan(&i.ID, &i.Name, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const listBooks = `-- name: ListBooks :many -SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` FROM books ORDER BY ` + "`" + `title` + "`" + `` +SELECT ` + "`" + `id` + "`" + `, ` + "`" + `title` + "`" + `, ` + "`" + `author` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `created_at` + "`" + `, ` + "`" + `updated_at` + "`" + ` +FROM books +ORDER BY ` + "`" + `title` + "`" + ` +` +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` FROM books ORDER BY title +// +// SELECT `id`, `title`, `author`, `description`, `created_at`, `updated_at` +// FROM books +// ORDER BY `title` func (q *Queries) ListBooks(ctx context.Context) ([]Book, error) { rows, err := q.db.QueryContext(ctx, listBooks) if err != nil { @@ -140,17 +239,53 @@ func (q *Queries) ListBooks(ctx context.Context) ([]Book, error) { var items []Book for rows.Next() { var i Book - if err := rows.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const updateBook = `-- name: UpdateBook :execresult -UPDATE books SET ` + "`" + `title` + "`" + ` = ?, ` + "`" + `author` + "`" + ` = ?, ` + "`" + `description` + "`" + ` = ?, ` + "`" + `updated_at` + "`" + ` = NOW() WHERE id = ?` +UPDATE books +SET ` + "`" + `title` + "`" + ` = ?, + ` + "`" + `author` + "`" + ` = ?, + ` + "`" + `description` + "`" + ` = ?, + ` + "`" + `updated_at` + "`" + ` = NOW() +WHERE id = ? +` + +type UpdateBookParams struct { + Title string + Author string + Description sql.NullString + ID int64 +} +// UPDATE books SET `title` = ?, `author` = ?, `description` = ?, `updated_at` = NOW() WHERE id = ? +// +// UPDATE books +// SET `title` = ?, +// `author` = ?, +// `description` = ?, +// `updated_at` = NOW() +// WHERE id = ? func (q *Queries) UpdateBook(ctx context.Context, arg UpdateBookParams) (sql.Result, error) { - return q.db.ExecContext(ctx, updateBook, arg.Title, arg.Author, arg.Description, arg.ID) + return q.db.ExecContext(ctx, updateBook, + arg.Title, + arg.Author, + arg.Description, + arg.ID, + ) } diff --git a/example/pkg/database/postgresdb/db.go b/example/pkg/database/postgresdb/db.go index 656c3b4..d690421 100644 --- a/example/pkg/database/postgresdb/db.go +++ b/example/pkg/database/postgresdb/db.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package postgresdb diff --git a/example/pkg/database/postgresdb/models.go b/example/pkg/database/postgresdb/models.go index d606177..a58ea91 100644 --- a/example/pkg/database/postgresdb/models.go +++ b/example/pkg/database/postgresdb/models.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package postgresdb @@ -16,6 +18,11 @@ type Book struct { UpdatedAt time.Time } +type BookTag struct { + BookID int64 + TagID int64 +} + type Tag struct { ID int64 Name string diff --git a/example/pkg/database/postgresdb/querier.go b/example/pkg/database/postgresdb/querier.go index be00bae..51a7812 100644 --- a/example/pkg/database/postgresdb/querier.go +++ b/example/pkg/database/postgresdb/querier.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package postgresdb @@ -7,48 +9,75 @@ import ( ) type Querier interface { - // AddBookTag adds a tag to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES ($1, $2) + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES ($1, $2) AddBookTag(ctx context.Context, arg AddBookTagParams) error - - // AddBookTags adds multiple tags to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES (unnest($1::bigint[]), unnest($2::bigint[])) // @bulk-for AddBookTag + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES (unnest($1::bigint[]), unnest($2::bigint[])) AddBookTags(ctx context.Context, arg AddBookTagsParams) error - - // CreateBook creates a new book. // INSERT INTO books ("title", "author", "description") VALUES ($1, $2, $3) RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // INSERT INTO books ("title", "author", "description") + // VALUES ($1, $2, $3) + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" CreateBook(ctx context.Context, arg CreateBookParams) (Book, error) - - // CreateTag creates a new tag. // INSERT INTO tags ("name") VALUES ($1) RETURNING "id", "name", "created_at", "updated_at" + // + // INSERT INTO tags ("name") + // VALUES ($1) + // RETURNING "id", "name", "created_at", "updated_at" CreateTag(ctx context.Context, name string) (Tag, error) - - // DeleteBook deletes a book by ID. // DELETE FROM books WHERE id = $1 + // + // DELETE FROM books + // WHERE id = $1 DeleteBook(ctx context.Context, id int64) error - - // GetBook retrieves a book by ID. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = $1 + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE id = $1 GetBook(ctx context.Context, id int64) (Book, error) - - // GetBookTags retrieves all tags for a book. // SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = $1 + // + // SELECT t."id", t."name", t."created_at", t."updated_at" + // FROM tags t + // INNER JOIN book_tags bt ON t.id = bt.tag_id + // WHERE bt.book_id = $1 GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) - - // GetBooksByAuthor retrieves all books by an author. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = $1 + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE author = $1 GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) - - // GetTag retrieves a tag by ID. // SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = $1 + // + // SELECT "id", "name", "created_at", "updated_at" + // FROM tags + // WHERE id = $1 GetTag(ctx context.Context, id int64) (Tag, error) - - // ListBooks retrieves all books. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // ORDER BY title ListBooks(ctx context.Context) ([]Book, error) - - // UpdateBook updates a book. // UPDATE books SET "title" = $1, "author" = $2, "description" = $3, "updated_at" = NOW() WHERE id = $4 RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // UPDATE books + // SET "title" = $1, + // "author" = $2, + // "description" = $3, + // "updated_at" = NOW() + // WHERE id = $4 + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" UpdateBook(ctx context.Context, arg UpdateBookParams) (Book, error) } + +var _ Querier = (*Queries)(nil) diff --git a/example/pkg/database/postgresdb/query.postgres.sql.go b/example/pkg/database/postgresdb/query.postgres.sql.go index ba8368b..d019fa4 100644 --- a/example/pkg/database/postgresdb/query.postgres.sql.go +++ b/example/pkg/database/postgresdb/query.postgres.sql.go @@ -1,39 +1,31 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.postgres.sql package postgresdb import ( "context" "database/sql" + + "github.com/lib/pq" ) +const addBookTag = `-- name: AddBookTag :exec +INSERT INTO book_tags ("book_id", "tag_id") +VALUES ($1, $2) +` + type AddBookTagParams struct { BookID int64 TagID int64 } -type AddBookTagsParams struct { - BookID []int64 - TagID []int64 -} - -type CreateBookParams struct { - Title string - Author string - Description sql.NullString -} - -type UpdateBookParams struct { - Title string - Author string - Description sql.NullString - ID int64 -} - -const addBookTag = `-- name: AddBookTag :exec -INSERT INTO book_tags ("book_id", "tag_id") -VALUES ($1, $2)` - +// INSERT INTO book_tags ("book_id", "tag_id") VALUES ($1, $2) +// +// INSERT INTO book_tags ("book_id", "tag_id") +// VALUES ($1, $2) func (q *Queries) AddBookTag(ctx context.Context, arg AddBookTagParams) error { _, err := q.db.ExecContext(ctx, addBookTag, arg.BookID, arg.TagID) return err @@ -41,18 +33,41 @@ func (q *Queries) AddBookTag(ctx context.Context, arg AddBookTagParams) error { const addBookTags = `-- name: AddBookTags :exec INSERT INTO book_tags ("book_id", "tag_id") -VALUES (unnest($1::bigint[]), unnest($2::bigint[]))` +VALUES (unnest($1::bigint[]), unnest($2::bigint[])) +` + +type AddBookTagsParams struct { + BookIds []int64 + TagIds []int64 +} +// INSERT INTO book_tags ("book_id", "tag_id") VALUES (unnest($1::bigint[]), unnest($2::bigint[])) +// @bulk-for AddBookTag +// +// INSERT INTO book_tags ("book_id", "tag_id") +// VALUES (unnest($1::bigint[]), unnest($2::bigint[])) func (q *Queries) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { - _, err := q.db.ExecContext(ctx, addBookTags, arg.BookID, arg.TagID) + _, err := q.db.ExecContext(ctx, addBookTags, pq.Array(arg.BookIds), pq.Array(arg.TagIds)) return err } const createBook = `-- name: CreateBook :one INSERT INTO books ("title", "author", "description") VALUES ($1, $2, $3) -RETURNING "id", "title", "author", "description", "created_at", "updated_at"` +RETURNING "id", "title", "author", "description", "created_at", "updated_at" +` + +type CreateBookParams struct { + Title string + Author string + Description sql.NullString +} +// INSERT INTO books ("title", "author", "description") VALUES ($1, $2, $3) RETURNING "id", "title", "author", "description", "created_at", "updated_at" +// +// INSERT INTO books ("title", "author", "description") +// VALUES ($1, $2, $3) +// RETURNING "id", "title", "author", "description", "created_at", "updated_at" func (q *Queries) CreateBook(ctx context.Context, arg CreateBookParams) (Book, error) { row := q.db.QueryRowContext(ctx, createBook, arg.Title, arg.Author, arg.Description) var i Book @@ -70,8 +85,14 @@ func (q *Queries) CreateBook(ctx context.Context, arg CreateBookParams) (Book, e const createTag = `-- name: CreateTag :one INSERT INTO tags ("name") VALUES ($1) -RETURNING "id", "name", "created_at", "updated_at"` +RETURNING "id", "name", "created_at", "updated_at" +` +// INSERT INTO tags ("name") VALUES ($1) RETURNING "id", "name", "created_at", "updated_at" +// +// INSERT INTO tags ("name") +// VALUES ($1) +// RETURNING "id", "name", "created_at", "updated_at" func (q *Queries) CreateTag(ctx context.Context, name string) (Tag, error) { row := q.db.QueryRowContext(ctx, createTag, name) var i Tag @@ -86,8 +107,13 @@ func (q *Queries) CreateTag(ctx context.Context, name string) (Tag, error) { const deleteBook = `-- name: DeleteBook :exec DELETE FROM books -WHERE id = $1` +WHERE id = $1 +` +// DELETE FROM books WHERE id = $1 +// +// DELETE FROM books +// WHERE id = $1 func (q *Queries) DeleteBook(ctx context.Context, id int64) error { _, err := q.db.ExecContext(ctx, deleteBook, id) return err @@ -96,8 +122,14 @@ func (q *Queries) DeleteBook(ctx context.Context, id int64) error { const getBook = `-- name: GetBook :one SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books -WHERE id = $1` +WHERE id = $1 +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = $1 +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// WHERE id = $1 func (q *Queries) GetBook(ctx context.Context, id int64) (Book, error) { row := q.db.QueryRowContext(ctx, getBook, id) var i Book @@ -116,8 +148,15 @@ const getBookTags = `-- name: GetBookTags :many SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id -WHERE bt.book_id = $1` +WHERE bt.book_id = $1 +` +// SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = $1 +// +// SELECT t."id", t."name", t."created_at", t."updated_at" +// FROM tags t +// INNER JOIN book_tags bt ON t.id = bt.tag_id +// WHERE bt.book_id = $1 func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) { rows, err := q.db.QueryContext(ctx, getBookTags, bookID) if err != nil { @@ -149,8 +188,14 @@ func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) const getBooksByAuthor = `-- name: GetBooksByAuthor :many SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books -WHERE author = $1` +WHERE author = $1 +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = $1 +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// WHERE author = $1 func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) { rows, err := q.db.QueryContext(ctx, getBooksByAuthor, author) if err != nil { @@ -184,8 +229,14 @@ func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, const getTag = `-- name: GetTag :one SELECT "id", "name", "created_at", "updated_at" FROM tags -WHERE id = $1` +WHERE id = $1 +` +// SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = $1 +// +// SELECT "id", "name", "created_at", "updated_at" +// FROM tags +// WHERE id = $1 func (q *Queries) GetTag(ctx context.Context, id int64) (Tag, error) { row := q.db.QueryRowContext(ctx, getTag, id) var i Tag @@ -201,8 +252,14 @@ func (q *Queries) GetTag(ctx context.Context, id int64) (Tag, error) { const listBooks = `-- name: ListBooks :many SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books -ORDER BY title` +ORDER BY title +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// ORDER BY title func (q *Queries) ListBooks(ctx context.Context) ([]Book, error) { rows, err := q.db.QueryContext(ctx, listBooks) if err != nil { @@ -240,10 +297,32 @@ SET "title" = $1, "description" = $3, "updated_at" = NOW() WHERE id = $4 -RETURNING "id", "title", "author", "description", "created_at", "updated_at"` +RETURNING "id", "title", "author", "description", "created_at", "updated_at" +` + +type UpdateBookParams struct { + Title string + Author string + Description sql.NullString + ID int64 +} +// UPDATE books SET "title" = $1, "author" = $2, "description" = $3, "updated_at" = NOW() WHERE id = $4 RETURNING "id", "title", "author", "description", "created_at", "updated_at" +// +// UPDATE books +// SET "title" = $1, +// "author" = $2, +// "description" = $3, +// "updated_at" = NOW() +// WHERE id = $4 +// RETURNING "id", "title", "author", "description", "created_at", "updated_at" func (q *Queries) UpdateBook(ctx context.Context, arg UpdateBookParams) (Book, error) { - row := q.db.QueryRowContext(ctx, updateBook, arg.Title, arg.Author, arg.Description, arg.ID) + row := q.db.QueryRowContext(ctx, updateBook, + arg.Title, + arg.Author, + arg.Description, + arg.ID, + ) var i Book err := row.Scan( &i.ID, diff --git a/example/pkg/database/sqlitedb/db.go b/example/pkg/database/sqlitedb/db.go index 29cd8c5..ee7f561 100644 --- a/example/pkg/database/sqlitedb/db.go +++ b/example/pkg/database/sqlitedb/db.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package sqlitedb diff --git a/example/pkg/database/sqlitedb/models.go b/example/pkg/database/sqlitedb/models.go index 74b3937..ac47d0a 100644 --- a/example/pkg/database/sqlitedb/models.go +++ b/example/pkg/database/sqlitedb/models.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package sqlitedb @@ -16,6 +18,11 @@ type Book struct { UpdatedAt time.Time } +type BookTag struct { + BookID int64 + TagID int64 +} + type Tag struct { ID int64 Name string diff --git a/example/pkg/database/sqlitedb/querier.go b/example/pkg/database/sqlitedb/querier.go index b916551..bc7779b 100644 --- a/example/pkg/database/sqlitedb/querier.go +++ b/example/pkg/database/sqlitedb/querier.go @@ -1,4 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 package sqlitedb @@ -7,48 +9,75 @@ import ( ) type Querier interface { - // AddBookTag adds a tag to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?) + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES (?, ?) AddBookTag(ctx context.Context, arg AddBookTagParams) error - - // AddBookTags adds multiple tags to a book. // INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?) // @bulk-for AddBookTag + // + // INSERT INTO book_tags ("book_id", "tag_id") + // VALUES (?, ?) AddBookTags(ctx context.Context, arg AddBookTagsParams) error - - // CreateBook creates a new book. // INSERT INTO books ("title", "author", "description") VALUES (?, ?, ?) RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // INSERT INTO books ("title", "author", "description") + // VALUES (?, ?, ?) + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" CreateBook(ctx context.Context, arg CreateBookParams) (Book, error) - - // CreateTag creates a new tag. // INSERT INTO tags ("name") VALUES (?) RETURNING "id", "name", "created_at", "updated_at" + // + // INSERT INTO tags ("name") + // VALUES (?) + // RETURNING "id", "name", "created_at", "updated_at" CreateTag(ctx context.Context, name string) (Tag, error) - - // DeleteBook deletes a book by ID. // DELETE FROM books WHERE id = ? + // + // DELETE FROM books + // WHERE id = ? DeleteBook(ctx context.Context, id int64) error - - // GetBook retrieves a book by ID. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = ? + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE id = ? GetBook(ctx context.Context, id int64) (Book, error) - - // GetBookTags retrieves all tags for a book. // SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ? + // + // SELECT t."id", t."name", t."created_at", t."updated_at" + // FROM tags t + // INNER JOIN book_tags bt ON t.id = bt.tag_id + // WHERE bt.book_id = ? GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) - - // GetBooksByAuthor retrieves all books by an author. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = ? + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // WHERE author = ? GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) - - // GetTag retrieves a tag by ID. // SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = ? + // + // SELECT "id", "name", "created_at", "updated_at" + // FROM tags + // WHERE id = ? GetTag(ctx context.Context, id int64) (Tag, error) - - // ListBooks retrieves all books. // SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title + // + // SELECT "id", "title", "author", "description", "created_at", "updated_at" + // FROM books + // ORDER BY title ListBooks(ctx context.Context) ([]Book, error) - - // UpdateBook updates a book. // UPDATE books SET "title" = ?, "author" = ?, "description" = ?, "updated_at" = CURRENT_TIMESTAMP WHERE id = ? RETURNING "id", "title", "author", "description", "created_at", "updated_at" + // + // UPDATE books + // SET "title" = ?, + // "author" = ?, + // "description" = ?, + // "updated_at" = CURRENT_TIMESTAMP + // WHERE id = ? + // RETURNING "id", "title", "author", "description", "created_at", "updated_at" UpdateBook(ctx context.Context, arg UpdateBookParams) (Book, error) } + +var _ Querier = (*Queries)(nil) diff --git a/example/pkg/database/sqlitedb/query.sqlite.sql.go b/example/pkg/database/sqlitedb/query.sqlite.sql.go index 618ff2d..45532fa 100644 --- a/example/pkg/database/sqlitedb/query.sqlite.sql.go +++ b/example/pkg/database/sqlitedb/query.sqlite.sql.go @@ -1,4 +1,7 @@ // Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.sqlite.sql package sqlitedb @@ -7,86 +10,151 @@ import ( "database/sql" ) +const addBookTag = `-- name: AddBookTag :exec +INSERT INTO book_tags ("book_id", "tag_id") +VALUES (?, ?) +` + type AddBookTagParams struct { BookID int64 TagID int64 } -type AddBookTagsParams struct { - BookID []int64 - TagID []int64 -} - -type CreateBookParams struct { - Title string - Author string - Description sql.NullString -} - -type UpdateBookParams struct { - Title string - Author string - Description sql.NullString - ID int64 -} - -const addBookTag = `-- name: AddBookTag :exec -INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?)` - +// INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?) +// +// INSERT INTO book_tags ("book_id", "tag_id") +// VALUES (?, ?) func (q *Queries) AddBookTag(ctx context.Context, arg AddBookTagParams) error { _, err := q.db.ExecContext(ctx, addBookTag, arg.BookID, arg.TagID) return err } const addBookTags = `-- name: AddBookTags :exec -INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?)` +INSERT INTO book_tags ("book_id", "tag_id") +VALUES (?, ?) +` + +type AddBookTagsParams struct { + BookID int64 + TagID int64 +} +// INSERT INTO book_tags ("book_id", "tag_id") VALUES (?, ?) +// @bulk-for AddBookTag +// +// INSERT INTO book_tags ("book_id", "tag_id") +// VALUES (?, ?) func (q *Queries) AddBookTags(ctx context.Context, arg AddBookTagsParams) error { _, err := q.db.ExecContext(ctx, addBookTags, arg.BookID, arg.TagID) return err } const createBook = `-- name: CreateBook :one -INSERT INTO books ("title", "author", "description") VALUES (?, ?, ?) RETURNING "id", "title", "author", "description", "created_at", "updated_at"` +INSERT INTO books ("title", "author", "description") +VALUES (?, ?, ?) +RETURNING "id", "title", "author", "description", "created_at", "updated_at" +` +type CreateBookParams struct { + Title string + Author string + Description sql.NullString +} + +// INSERT INTO books ("title", "author", "description") VALUES (?, ?, ?) RETURNING "id", "title", "author", "description", "created_at", "updated_at" +// +// INSERT INTO books ("title", "author", "description") +// VALUES (?, ?, ?) +// RETURNING "id", "title", "author", "description", "created_at", "updated_at" func (q *Queries) CreateBook(ctx context.Context, arg CreateBookParams) (Book, error) { row := q.db.QueryRowContext(ctx, createBook, arg.Title, arg.Author, arg.Description) var i Book - err := row.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const createTag = `-- name: CreateTag :one -INSERT INTO tags ("name") VALUES (?) RETURNING "id", "name", "created_at", "updated_at"` +INSERT INTO tags ("name") +VALUES (?) +RETURNING "id", "name", "created_at", "updated_at" +` +// INSERT INTO tags ("name") VALUES (?) RETURNING "id", "name", "created_at", "updated_at" +// +// INSERT INTO tags ("name") +// VALUES (?) +// RETURNING "id", "name", "created_at", "updated_at" func (q *Queries) CreateTag(ctx context.Context, name string) (Tag, error) { row := q.db.QueryRowContext(ctx, createTag, name) var i Tag - err := row.Scan(&i.ID, &i.Name, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const deleteBook = `-- name: DeleteBook :exec -DELETE FROM books WHERE id = ?` +DELETE FROM books +WHERE id = ? +` +// DELETE FROM books WHERE id = ? +// +// DELETE FROM books +// WHERE id = ? func (q *Queries) DeleteBook(ctx context.Context, id int64) error { _, err := q.db.ExecContext(ctx, deleteBook, id) return err } const getBook = `-- name: GetBook :one -SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = ?` +SELECT "id", "title", "author", "description", "created_at", "updated_at" +FROM books +WHERE id = ? +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE id = ? +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// WHERE id = ? func (q *Queries) GetBook(ctx context.Context, id int64) (Book, error) { row := q.db.QueryRowContext(ctx, getBook, id) var i Book - err := row.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const getBookTags = `-- name: GetBookTags :many -SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ?` +SELECT t."id", t."name", t."created_at", t."updated_at" +FROM tags t +INNER JOIN book_tags bt ON t.id = bt.tag_id +WHERE bt.book_id = ? +` +// SELECT t."id", t."name", t."created_at", t."updated_at" FROM tags t INNER JOIN book_tags bt ON t.id = bt.tag_id WHERE bt.book_id = ? +// +// SELECT t."id", t."name", t."created_at", t."updated_at" +// FROM tags t +// INNER JOIN book_tags bt ON t.id = bt.tag_id +// WHERE bt.book_id = ? func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) { rows, err := q.db.QueryContext(ctx, getBookTags, bookID) if err != nil { @@ -96,17 +164,33 @@ func (q *Queries) GetBookTags(ctx context.Context, bookID int64) ([]Tag, error) var items []Tag for rows.Next() { var i Tag - if err := rows.Scan(&i.ID, &i.Name, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const getBooksByAuthor = `-- name: GetBooksByAuthor :many -SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = ?` +SELECT "id", "title", "author", "description", "created_at", "updated_at" +FROM books +WHERE author = ? +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books WHERE author = ? +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// WHERE author = ? func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, error) { rows, err := q.db.QueryContext(ctx, getBooksByAuthor, author) if err != nil { @@ -116,27 +200,58 @@ func (q *Queries) GetBooksByAuthor(ctx context.Context, author string) ([]Book, var items []Book for rows.Next() { var i Book - if err := rows.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const getTag = `-- name: GetTag :one -SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = ?` +SELECT "id", "name", "created_at", "updated_at" +FROM tags +WHERE id = ? +` +// SELECT "id", "name", "created_at", "updated_at" FROM tags WHERE id = ? +// +// SELECT "id", "name", "created_at", "updated_at" +// FROM tags +// WHERE id = ? func (q *Queries) GetTag(ctx context.Context, id int64) (Tag, error) { row := q.db.QueryRowContext(ctx, getTag, id) var i Tag - err := row.Scan(&i.ID, &i.Name, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } const listBooks = `-- name: ListBooks :many -SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title` +SELECT "id", "title", "author", "description", "created_at", "updated_at" +FROM books +ORDER BY title +` +// SELECT "id", "title", "author", "description", "created_at", "updated_at" FROM books ORDER BY title +// +// SELECT "id", "title", "author", "description", "created_at", "updated_at" +// FROM books +// ORDER BY title func (q *Queries) ListBooks(ctx context.Context) ([]Book, error) { rows, err := q.db.QueryContext(ctx, listBooks) if err != nil { @@ -146,20 +261,65 @@ func (q *Queries) ListBooks(ctx context.Context) ([]Book, error) { var items []Book for rows.Next() { var i Book - if err := rows.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ); err != nil { return nil, err } items = append(items, i) } - return items, rows.Err() + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } const updateBook = `-- name: UpdateBook :one -UPDATE books SET "title" = ?, "author" = ?, "description" = ?, "updated_at" = CURRENT_TIMESTAMP WHERE id = ? RETURNING "id", "title", "author", "description", "created_at", "updated_at"` +UPDATE books +SET "title" = ?, + "author" = ?, + "description" = ?, + "updated_at" = CURRENT_TIMESTAMP +WHERE id = ? +RETURNING "id", "title", "author", "description", "created_at", "updated_at" +` + +type UpdateBookParams struct { + Title string + Author string + Description sql.NullString + ID int64 +} +// UPDATE books SET "title" = ?, "author" = ?, "description" = ?, "updated_at" = CURRENT_TIMESTAMP WHERE id = ? RETURNING "id", "title", "author", "description", "created_at", "updated_at" +// +// UPDATE books +// SET "title" = ?, +// "author" = ?, +// "description" = ?, +// "updated_at" = CURRENT_TIMESTAMP +// WHERE id = ? +// RETURNING "id", "title", "author", "description", "created_at", "updated_at" func (q *Queries) UpdateBook(ctx context.Context, arg UpdateBookParams) (Book, error) { - row := q.db.QueryRowContext(ctx, updateBook, arg.Title, arg.Author, arg.Description, arg.ID) + row := q.db.QueryRowContext(ctx, updateBook, + arg.Title, + arg.Author, + arg.Description, + arg.ID, + ) var i Book - err := row.Scan(&i.ID, &i.Title, &i.Author, &i.Description, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.Title, + &i.Author, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + ) return i, err } diff --git a/generator/templates.go b/generator/templates.go index c2387fb..04bc123 100644 --- a/generator/templates.go +++ b/generator/templates.go @@ -123,17 +123,25 @@ func (w *{{$.Engine.Name}}Wrapper) {{.Name}}({{joinParamsSignature .Params}}) ({ for i, v := range {{(index .Params 1).Name}}.{{$sliceField.Name}} { _ = i err := w.adapter.{{$singularMethodName}}({{(index .Params 0).Name}}, {{$.Engine.Package}}.{{$targetSingularParamType}}{ - {{range $targetStructField := $targetStructInfo.Fields}} - {{/* Find matching field in bulk (source) struct */}} + {{range $targetIdx, $targetField := $targetStructInfo.Fields}} + {{/* Find matching field in bulk (source) struct by name */}} {{$sourceField := dict "Name" ""}} - {{range $bulkStructInfo.Fields}} - {{if eq .Name $targetStructField.Name}} - {{$sourceField = .}} + {{$matchedIdx := -1}} + {{range $bulkIdx, $bulkField := $bulkStructInfo.Fields}} + {{if eq $bulkField.Name $targetField.Name}} + {{$sourceField = $bulkField}} + {{$matchedIdx = $bulkIdx}} {{end}} - {{if and (eq $sourceField.Name "") (eq (toSingular .Name) $targetStructField.Name)}} - {{$sourceField = .}} + {{if and (eq $sourceField.Name "") (eq (toSingular $bulkField.Name) $targetField.Name)}} + {{$sourceField = $bulkField}} + {{$matchedIdx = $bulkIdx}} {{end}} {{end}} + {{/* Fall back to positional matching if name matching failed */}} + {{if eq $sourceField.Name ""}} + {{$sourceField = index $bulkStructInfo.Fields $targetIdx}} + {{$matchedIdx = $targetIdx}} + {{end}} {{if ne $sourceField.Name ""}} {{$srcExpr := ""}} {{if eq $sourceField.Name $sliceField.Name}} @@ -147,7 +155,7 @@ func (w *{{$.Engine.Name}}Wrapper) {{.Name}}({{joinParamsSignature .Params}}) ({ {{if or (eq $sourceField.Name $sliceField.Name) (isSlice $sourceField.Type)}} {{$srcType = trimPrefix $srcType "[]"}} {{end}} - {{generateFieldConversion $targetStructField.Name $targetStructField.Type $srcType $srcExpr}}, + {{generateFieldConversion $targetField.Name $targetField.Type $srcType $srcExpr}}, {{end}} {{end}} }, diff --git a/nix/devshells/flake-module.nix b/nix/devshells/flake-module.nix index 02d0f69..08202be 100644 --- a/nix/devshells/flake-module.nix +++ b/nix/devshells/flake-module.nix @@ -12,6 +12,7 @@ pkgs.go pkgs.golangci-lint pkgs.pre-commit + pkgs.sqlc ]; _GO_VERSION = "${pkgs.go.version}"; @@ -26,6 +27,10 @@ if [[ "$(${pkgs.gnugrep}/bin/grep '^\(go \)[0-9.]*$' go.mod)" != "go ''${_GO_VERSION}" ]]; then ${pkgs.gnused}/bin/sed -e "s:^\(go \)[0-9.]*$:\1''${_GO_VERSION}:" -i go.mod fi + + if [[ "$(${pkgs.gnugrep}/bin/grep '^\(go \)[0-9.]*$' example/go.mod)" != "go ''${_GO_VERSION}" ]]; then + ${pkgs.gnused}/bin/sed -e "s:^\(go \)[0-9.]*$:\1''${_GO_VERSION}:" -i example/go.mod + fi ''; }; };