All

クエリを実行し、結果をスライスで返します。scan.All のラッパーです。

使用方法

type userObj struct {
    ID   int
    Name string
}

ctx := context.Background()
db, err := bob.Open("postgres", "...")
if err != nil {
    // ...
}

q := psql.Select(...)
users, err := bob.All(ctx, db, q, scan.StructMapper[userObj]())
if err != nil {
    // ...
}

特徴

  • 複数の結果: 全ての結果をスライスで取得
  • 型安全: 構造体マッピングをサポート
  • メモリ効率: 結果が大きい場合は Cursor を検討

使用例

基本的な使用

type User struct {
    ID    int    `db:"id"`
    Name  string `db:"name"`
    Email string `db:"email"`
}

query := psql.Select("id", "name", "email").
    From("users").
    Where(psql.Quote("active").EQ(psql.Arg(true)))

users, err := bob.All(ctx, db, query, scan.StructMapper[User]())
if err != nil {
    return nil, err
}

fmt.Printf("Found %d users\n", len(users))
for _, user := range users {
    fmt.Printf("User: %+v\n", user)
}

条件付きクエリ

type UserSummary struct {
    ID        int       `db:"id"`
    Name      string    `db:"name"`
    Email     string    `db:"email"`
    CreatedAt time.Time `db:"created_at"`
    PostCount int       `db:"post_count"`
}

query := psql.Select(
    psql.Quote("users", "id"),
    psql.Quote("users", "name"),
    psql.Quote("users", "email"),
    psql.Quote("users", "created_at"),
    psql.F("COUNT", psql.Quote("posts", "id")).As("post_count"),
).From("users").
    LeftJoin("posts", psql.Quote("posts", "user_id").EQ(psql.Quote("users", "id"))).
    Where(psql.Quote("users", "created_at").GTE(psql.Arg(time.Now().AddDate(0, -1, 0)))).
    GroupBy(psql.Quote("users", "id")).
    OrderBy(psql.Quote("users", "created_at").Desc())

users, err := bob.All(ctx, db, query, scan.StructMapper[UserSummary]())
if err != nil {
    return nil, err
}

ページネーション

type User struct {
    ID    int    `db:"id"`
    Name  string `db:"name"`
    Email string `db:"email"`
}

func GetUsersPaginated(ctx context.Context, db bob.Executor, page, limit int) ([]User, error) {
    offset := (page - 1) * limit
    
    query := psql.Select("id", "name", "email").
        From("users").
        OrderBy(psql.Quote("id").Asc()).
        Limit(limit).
        Offset(offset)
    
    return bob.All(ctx, db, query, scan.StructMapper[User]())
}

注意点

  • メモリ使用量: 大きな結果セットの場合、全てのデータがメモリに読み込まれます
  • パフォーマンス: 大量のデータを扱う場合は、代わりに Cursor を検討してください
  • 空の結果: 結果が見つからない場合、空のスライスを返します(エラーではありません)

All は、中程度のサイズの結果セットを一度に処理する場合に最適です。