| 389 | } |
| 390 | |
| 391 | func scanAPIKeysForUser(ctx context.Context, tx pgx.Tx, userID string) ([]APIKeyExportEntry, error) { |
| 392 | rows, err := tx.Query(ctx, |
| 393 | `SELECT id, name, key_prefix, created_at, last_used_at, revoked_at |
| 394 | FROM api_keys WHERE user_id = $1 ORDER BY created_at`, userID) |
| 395 | if err != nil { |
| 396 | return nil, err |
| 397 | } |
| 398 | defer rows.Close() |
| 399 | var out []APIKeyExportEntry |
| 400 | for rows.Next() { |
| 401 | var k APIKeyExportEntry |
| 402 | if err := rows.Scan(&k.ID, &k.Name, &k.KeyPrefix, &k.CreatedAt, &k.LastUsedAt, &k.RevokedAt); err != nil { |
| 403 | return nil, err |
| 404 | } |
| 405 | out = append(out, k) |
| 406 | } |
| 407 | return out, rows.Err() |
| 408 | } |
| 409 | |
| 410 | func scanMessagesForUser(ctx context.Context, tx pgx.Tx, userID string) ([]Message, error) { |
| 411 | // COALESCE the nullable string columns into '' so we can scan into |