package image import ( "context" "database/sql" "time" ) type Row struct { ID int64 ItemID int64 OriginalURL string ContentType string Bytes []byte Width int Height int IsThumb bool CreatedAt time.Time } type Ref struct { ID int64 ItemID int64 IsThumb bool } func QListByItem(ctx context.Context, db *sql.DB, itemID int64) ([]Row, error) { rows, err := db.QueryContext(ctx, ` SELECT id, item_id, original_url, content_type, bytes, width, height, is_thumb, created_at FROM image WHERE item_id = $1 ORDER BY is_thumb DESC, id ASC `, itemID) if err != nil { return nil, err } defer rows.Close() var items []Row for rows.Next() { var row Row if err := rows.Scan(&row.ID, &row.ItemID, &row.OriginalURL, &row.ContentType, &row.Bytes, &row.Width, &row.Height, &row.IsThumb, &row.CreatedAt); err != nil { return nil, err } items = append(items, row) } return items, rows.Err() } func QListPrimaryRefsByItems(ctx context.Context, db *sql.DB, itemIDs []int64) (map[int64]Ref, error) { if len(itemIDs) == 0 { return map[int64]Ref{}, nil } rows, err := db.QueryContext(ctx, ` SELECT id, item_id, is_thumb FROM image WHERE item_id = ANY($1) ORDER BY item_id ASC, is_thumb DESC, id ASC `, itemIDs) if err != nil { return nil, err } defer rows.Close() results := make(map[int64]Ref) for rows.Next() { var row Ref if err := rows.Scan(&row.ID, &row.ItemID, &row.IsThumb); err != nil { return nil, err } if _, exists := results[row.ItemID]; !exists { results[row.ItemID] = row } } return results, rows.Err() } func QFindByID(ctx context.Context, db *sql.DB, id int64) (*Row, error) { var row Row err := db.QueryRowContext(ctx, ` SELECT id, item_id, original_url, content_type, bytes, width, height, is_thumb, created_at FROM image WHERE id = $1 LIMIT 1 `, id).Scan(&row.ID, &row.ItemID, &row.OriginalURL, &row.ContentType, &row.Bytes, &row.Width, &row.Height, &row.IsThumb, &row.CreatedAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &row, nil } func QCreate(ctx context.Context, db *sql.DB, itemID int64, originalURL, contentType string, bytes []byte, width, height int, isThumb bool) (Row, error) { var row Row err := db.QueryRowContext(ctx, ` INSERT INTO image (item_id, original_url, content_type, bytes, width, height, is_thumb) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, item_id, original_url, content_type, bytes, width, height, is_thumb, created_at `, itemID, originalURL, contentType, bytes, width, height, isThumb).Scan( &row.ID, &row.ItemID, &row.OriginalURL, &row.ContentType, &row.Bytes, &row.Width, &row.Height, &row.IsThumb, &row.CreatedAt, ) return row, err } func QDeleteByItem(ctx context.Context, db *sql.DB, itemID int64) error { _, err := db.ExecContext(ctx, `DELETE FROM image WHERE item_id = $1`, itemID) return err }