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

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

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

# sqlc generate コマンドの実行例
## ディレクトリ構成&コード
```sh
$ 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クエリ（この場合はユーザー作成）を実行するための関数を提供します。