0
0

Go:sqlc generate コマンドによって生成された3つのGoファイル

Posted at

sqlc とは

SQLクエリから型安全なGoのコードを生成するツールです。
これにより、SQLクエリとアプリケーションコード間の不整合を減らし、データベース操作の安全性と効率を向上させることができます。

sqlc generate とは

sqlc の主要な機能の一つで、事前に定義されたSQLクエリからGoのコードを生成します。

sqlc generate コマンドの実行例

ディレクトリ構成&コード

$ tree
.
├── db
│   ├── db.go                  ← sqlc generateコマンドで生成されたファイル
│   ├── models.go              ← sqlc generateコマンドで生成されたファイル
│   ├── create_user.sql.go     ← sqlc generateコマンドで生成されたファイル
│   ├── migration
│   │   └── 001_create_users_table.up.sql
│   └── sql
│       └── create_user.sql
├── go.mod
├── go.sum
├── main.go
├── sqlc.yaml
001_create_users_table.up.sql
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
create_user.sql
-- name: CreateUser :exec
INSERT INTO users (email, password_hash) VALUES ($1, $2);
sqlc.yml
version: "1"
packages:
  - name: "db"
    path: "./db"
    queries: "./db/sql"
    schema: "./db/migration"
    engine: "postgresql"

sqlc generate コマンド 実行

sqlc.ymlファイル配下で、sqlc generate コマンドを実行すると、db.go models.go create_user.sql.goが生成されます。

db.go

  • 目的:データベース操作を行うための基本的な機能を提供する。
  • 利用方法:データベースへの接続やクエリの実行に利用します。
db.go
package db

import (
	"context"
	"database/sql"
)

type DBTX interface {
	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}

func New(db DBTX) *Queries {
	return &Queries{db: db}
}

type Queries struct {
	db DBTX
}

func (q *Queries) WithTx(tx *sql.Tx) *Queries {
	return &Queries{
		db: tx,
	}
}

models.go

  • 目的:データベースのテーブル構造をGoの構造体として表現する。
  • 利用方法:データベースから取得したデータをGoのオブジェクトとして扱うために使用します。
models.go
package db

import (
	"database/sql"
)

type User struct {
	ID           int32
	Email        string
	PasswordHash string
	CreatedAt    sql.NullTime
	UpdatedAt    sql.NullTime
}

create_user.sql.go

  • 目的:特定のSQLクエリを実行するための関数を提供する。
  • 利用方法:このファイルに含まれる関数を呼び出して、データベースにユーザーを作成するなどの具体的な操作を行います。
create_user.sql.go
package db

import (
	"context"
)

const createUser = `-- name: CreateUser :exec
INSERT INTO users (email, password_hash) VALUES ($1, $2)
`

type CreateUserParams struct {
	Email        string
	PasswordHash string
}

func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error {
	_, err := q.db.ExecContext(ctx, createUser, arg.Email, arg.PasswordHash)
	return err
}

使用例

db.goファイル(db.New)の関数を呼び出してオブジェクトを作成し、create_user.sql.goファイル(dbQueries.CreateUser)の関数で特定のSQLクエリが実行される。

main.go
// ~~省略~~
	// db.Queriesオブジェクトを作成
	dbQueries := db.New(conn)
	// ユーザーを作成
    hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	err = dbQueries.CreateUser(context.Background(), db.CreateUserParams{
		Email:        email,
		PasswordHash: string(hashedPassword),
	})
// ~~省略~~

まとめ

  • db.go はデータベース接続と一般的な操作を管理するために使用されます。
  • models.go はデータベースのテーブル構造をGoの構造体で表現するために使用されます。
  • create_user.sql.go は特定のSQLクエリ(この場合はユーザー作成)を実行するための関数を提供します。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0