db

package
v0.0.0-...-4cdf813 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DealClassGood      = "good"       // 20-35% below baseline
	DealClassGreat     = "great"      // 35-50% below baseline
	DealClassAmazing   = "amazing"    // 50%+ below baseline
	DealClassErrorFare = "error_fare" // Suspiciously cheap (70%+)
)

DealClassification constants

View Source
const (
	DealSourceSweep   = "sweep"   // From continuous price sweeps
	DealSourceSocial  = "social"  // From social-pulse webhook
	DealSourceWebhook = "webhook" // From external webhook
	DealSourceManual  = "manual"  // Manually entered
)

DealSourceType constants

View Source
const (
	DealStatusActive    = "active"
	DealStatusExpired   = "expired"
	DealStatusPublished = "published"
	DealStatusVerified  = "verified"
)

DealStatus constants

Variables

View Source
var Top100Airports = []TopAirport{

	{"ATL", "US"},
	{"DFW", "US"},
	{"DEN", "US"},
	{"LAX", "US"},
	{"ORD", "US"},
	{"JFK", "US"},
	{"SFO", "US"},
	{"LAS", "US"},
	{"MIA", "US"},
	{"CLT", "US"},
	{"SEA", "US"},
	{"PHX", "US"},
	{"EWR", "US"},
	{"MCO", "US"},
	{"MSP", "US"},
	{"BOS", "US"},
	{"DTW", "US"},
	{"IAH", "US"},
	{"BWI", "US"},
	{"FLL", "US"},
	{"TPA", "US"},
	{"SAN", "US"},
	{"PDX", "US"},
	{"STL", "US"},
	{"HNL", "US"},

	{"YYZ", "CA"},
	{"MEX", "MX"},
	{"CUN", "MX"},

	{"LHR", "GB"},
	{"LGW", "GB"},
	{"MAN", "GB"},
	{"STN", "GB"},

	{"CDG", "FR"},
	{"ORY", "FR"},

	{"FRA", "DE"},
	{"MUC", "DE"},
	{"DUS", "DE"},
	{"HAM", "DE"},

	{"AMS", "NL"},
	{"MAD", "ES"},
	{"BCN", "ES"},
	{"PMI", "ES"},
	{"FCO", "IT"},
	{"MXP", "IT"},
	{"ZRH", "CH"},
	{"VIE", "AT"},
	{"LIS", "PT"},
	{"OSL", "NO"},
	{"CPH", "DK"},
	{"ARN", "SE"},

	{"DUB", "IE"},
	{"ATH", "GR"},
	{"BRU", "BE"},
	{"WAW", "PL"},
	{"IST", "TR"},
	{"AYT", "TR"},
	{"SAW", "TR"},
	{"DME", "RU"},
	{"SVO", "RU"},

	{"HND", "JP"},
	{"NRT", "JP"},
	{"ICN", "KR"},

	{"PVG", "CN"},
	{"PEK", "CN"},
	{"CAN", "CN"},
	{"SHA", "CN"},
	{"SZX", "CN"},
	{"CTU", "CN"},
	{"KMG", "CN"},
	{"XIY", "CN"},
	{"HGH", "CN"},
	{"CKG", "CN"},
	{"NKG", "CN"},
	{"TAO", "CN"},
	{"WUH", "CN"},
	{"CSX", "CN"},

	{"HKG", "HK"},
	{"TPE", "TW"},

	{"SIN", "SG"},
	{"BKK", "TH"},
	{"KUL", "MY"},
	{"MNL", "PH"},
	{"CGK", "ID"},

	{"DEL", "IN"},
	{"BOM", "IN"},

	{"DXB", "AE"},
	{"DOH", "QA"},
	{"AUH", "AE"},

	{"SYD", "AU"},
	{"MEL", "AU"},

	{"GRU", "BR"},
	{"BOG", "CO"},

	{"JNB", "ZA"},
	{"CMN", "MA"},
	{"CAI", "EG"},
}

Top100Airports contains IATA codes and country codes for major global airports. Despite the name, the list currently has 95 airports (not 100). Route calculations:

  • All routes (n*(n-1)): 95*94 = 8,930 routes
  • International routes (different countries): ~8,096 routes
  • With 2 trip lengths (7,14 days): ~16,192 queries per sweep

Source: ACI World Airport Traffic Rankings 2023

Functions

func BuildPostgresConnString

func BuildPostgresConnString(cfg config.PostgresConfig) string

BuildPostgresConnString builds a lib/pq keyword/value connection string from config.

func CountRoutes

func CountRoutes() (total int, international int, domestic int)

CountRoutes returns statistics about route generation

func EnsurePostgresAirportsSeeded

func EnsurePostgresAirportsSeeded(ctx context.Context, connString string) error

func GetAirportCountry

func GetAirportCountry(code string) string

GetAirportCountry returns the country code for an airport, or empty string if not found

func GetPool

func GetPool() *pgxpool.Pool

GetPool returns the PostgreSQL connection pool

func InitTestPostgres

func InitTestPostgres(cfg *config.Config) *pgxpool.Pool

InitTestPostgres initializes a test PostgreSQL pool

func RunMigrations

func RunMigrations(connString string) error

RunMigrations applies embedded SQL migrations in filename order and records them in schema_migrations.

The connString may be either a lib/pq keyword/value DSN or a postgres:// URL.

func Top100AirportCodes

func Top100AirportCodes() []string

Top100AirportCodes returns IATA codes from the Top100Airports list

Types

type Airline

type Airline struct {
	Code    string
	Name    string
	Country string
}

Airline represents an airline row

type Airport

type Airport struct {
	Code      string
	Name      string
	City      string
	Country   string
	Latitude  sql.NullFloat64
	Longitude sql.NullFloat64
}

Airport represents an airport row

type BulkSearch

type BulkSearch struct {
	ID            int
	JobID         sql.NullInt32
	Status        string
	TotalSearches int
	Completed     int
	TotalOffers   int
	ErrorCount    int
	Currency      string
	CreatedAt     time.Time
	CompletedAt   sql.NullTime
	UpdatedAt     time.Time
	MinPrice      sql.NullFloat64
	MaxPrice      sql.NullFloat64
	AveragePrice  sql.NullFloat64
}

BulkSearch represents the metadata for a bulk search

type BulkSearchOffer

type BulkSearchOffer struct {
	ID                   int
	BulkSearchID         int
	Origin               string
	Destination          string
	DepartureDate        time.Time
	ReturnDate           sql.NullTime
	Price                float64
	Currency             string
	AirlineCodes         []string
	SrcAirportCode       sql.NullString
	DstAirportCode       sql.NullString
	SrcCity              sql.NullString
	DstCity              sql.NullString
	FlightDuration       sql.NullInt32
	ReturnFlightDuration sql.NullInt32
	DistanceMiles        sql.NullFloat64
	CostPerMile          sql.NullFloat64
	OutboundFlights      json.RawMessage
	ReturnFlights        json.RawMessage
	OfferJSON            json.RawMessage
	CreatedAt            time.Time
}

BulkSearchOffer represents all offers captured during a bulk run

type BulkSearchOfferRecord

type BulkSearchOfferRecord struct {
	BulkSearchID         int
	Origin               string
	Destination          string
	DepartureDate        time.Time
	ReturnDate           sql.NullTime
	Price                float64
	Currency             string
	AirlineCodes         []string
	SrcAirportCode       sql.NullString
	DstAirportCode       sql.NullString
	SrcCity              sql.NullString
	DstCity              sql.NullString
	FlightDuration       sql.NullInt32
	ReturnFlightDuration sql.NullInt32
	DistanceMiles        sql.NullFloat64
	CostPerMile          sql.NullFloat64
	OutboundFlightsJSON  []byte
	ReturnFlightsJSON    []byte
	OfferJSON            []byte
}

BulkSearchOfferRecord represents the data needed to insert an offer for a bulk run

type BulkSearchResult

type BulkSearchResult struct {
	Origin               string
	Destination          string
	DepartureDate        time.Time
	ReturnDate           sql.NullTime
	Price                float64
	Currency             string
	AirlineCode          sql.NullString
	Duration             sql.NullInt32
	SrcAirportCode       sql.NullString
	DstAirportCode       sql.NullString
	SrcCity              sql.NullString
	DstCity              sql.NullString
	FlightDuration       sql.NullInt32
	ReturnFlightDuration sql.NullInt32
	OutboundFlights      json.RawMessage
	ReturnFlights        json.RawMessage
	OfferJSON            json.RawMessage
}

BulkSearchResult represents a single result row from a bulk search

type BulkSearchResultRecord

type BulkSearchResultRecord struct {
	BulkSearchID         int
	Origin               string
	Destination          string
	DepartureDate        time.Time
	ReturnDate           sql.NullTime
	Price                float64
	Currency             string
	AirlineCode          sql.NullString
	Duration             sql.NullInt32
	SrcAirportCode       sql.NullString
	DstAirportCode       sql.NullString
	SrcCity              sql.NullString
	DstCity              sql.NullString
	FlightDuration       sql.NullInt32
	ReturnFlightDuration sql.NullInt32
	OutboundFlightsJSON  []byte
	ReturnFlightsJSON    []byte
	OfferJSON            []byte
}

BulkSearchResultRecord represents the data needed to insert a bulk search result

type BulkSearchSummary

type BulkSearchSummary struct {
	ID           int
	Status       string
	Completed    int
	TotalOffers  int
	ErrorCount   int
	MinPrice     sql.NullFloat64
	MaxPrice     sql.NullFloat64
	AveragePrice sql.NullFloat64
}

BulkSearchSummary represents aggregated results for a bulk search run

type Certificate

type Certificate struct {
	Domain     string
	CertChain  []byte
	PrivateKey []byte
	Expires    time.Time
}

Certificate represents a TLS certificate stored in the database

type Connection

type Connection struct {
	Airport      string  `json:"airport"`       // Destination airport code
	Name         string  `json:"name"`          // Airport name
	Country      string  `json:"country"`       // Country code
	CheapestPath float64 `json:"cheapest_path"` // Cheapest total price to reach
	Hops         int     `json:"hops"`          // Number of stops
}

Connection represents a reachable destination from an origin

type ContinuousSweepProgress

type ContinuousSweepProgress struct {
	ID                  int
	SweepNumber         int
	RouteIndex          int
	TotalRoutes         int
	CurrentOrigin       sql.NullString
	CurrentDestination  sql.NullString
	QueriesCompleted    int
	ErrorsCount         int
	LastError           sql.NullString
	SweepStartedAt      sql.NullTime
	LastUpdated         time.Time
	TripLengths         []int
	PacingMode          string // "adaptive" or "fixed"
	TargetDurationHours int
	MinDelayMs          int
	IsRunning           bool
	IsPaused            bool
	InternationalOnly   bool
}

ContinuousSweepProgress tracks the current state of the continuous sweep

type ContinuousSweepResultsFilter

type ContinuousSweepResultsFilter struct {
	Origin      string
	Destination string
	FromDate    time.Time
	ToDate      time.Time
	Limit       int
	Offset      int
}

ContinuousSweepResultsFilter defines filters for querying continuous sweep results

type ContinuousSweepStats

type ContinuousSweepStats struct {
	ID                   int
	SweepNumber          int
	StartedAt            time.Time
	CompletedAt          sql.NullTime
	TotalRoutes          int
	SuccessfulQueries    int
	FailedQueries        int
	TotalDurationSeconds sql.NullInt32
	AvgDelayMs           sql.NullInt32
	MinPriceFound        sql.NullFloat64
	MaxPriceFound        sql.NullFloat64
	CreatedAt            time.Time
}

ContinuousSweepStats represents historical stats for completed sweeps

type DealAlert

type DealAlert struct {
	ID                   int
	DetectedDealID       int
	Origin               string
	Destination          string
	Price                float64
	Currency             string
	DiscountPercent      sql.NullFloat64
	DealClassification   sql.NullString
	DealScore            sql.NullInt32
	PublishedAt          time.Time
	PublishMethod        string
	NotificationSent     bool
	NotificationSentAt   sql.NullTime
	NotificationChannels []string
	CreatedAt            time.Time
}

DealAlert represents a published deal ready for notification

type DealFilter

type DealFilter struct {
	Origin         string
	Destination    string
	MinScore       int
	MaxPrice       *float64
	MinDiscount    *float64
	Classification string
	Status         string
	SourceType     string
	IncludeExpired bool
	Limit          int
	Offset         int
}

DealFilter is used to filter deals in queries

type DealSource

type DealSource struct {
	ID             int
	Name           string
	SourceType     string
	WebhookURL     sql.NullString
	APIKey         sql.NullString
	Enabled        bool
	LastReceivedAt sql.NullTime
	DealsReceived  int
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

DealSource represents an external deal source (for webhook integration)

type DetectedDeal

type DetectedDeal struct {
	ID                 int
	Origin             string
	Destination        string
	DepartureDate      time.Time
	ReturnDate         sql.NullTime
	TripLength         sql.NullInt32
	Price              float64
	Currency           string
	BaselineMean       sql.NullFloat64
	BaselineMedian     sql.NullFloat64
	DiscountPercent    sql.NullFloat64
	DealScore          sql.NullInt32
	DealClassification sql.NullString
	DistanceMiles      sql.NullFloat64
	CostPerMile        sql.NullFloat64
	CabinClass         string
	SourceType         string
	SourceID           sql.NullString
	SearchURL          sql.NullString
	DealFingerprint    string
	FirstSeenAt        time.Time
	LastSeenAt         time.Time
	TimesSeen          int
	Status             string
	Verified           bool
	VerifiedPrice      sql.NullFloat64
	VerifiedAt         sql.NullTime
	ExpiresAt          sql.NullTime
	CreatedAt          time.Time
	UpdatedAt          time.Time
}

DetectedDeal represents a flight deal identified by the system

type ErrInvalidSearchID

type ErrInvalidSearchID struct {
	ID string
}

ErrInvalidSearchID is returned when the search ID is invalid

func (*ErrInvalidSearchID) Error

func (e *ErrInvalidSearchID) Error() string

type FlightOffer

type FlightOffer struct {
	ID               int
	Price            float64
	Currency         string
	AirlineCodes     sql.NullString
	OutboundDuration sql.NullInt64
	OutboundStops    sql.NullInt64
	ReturnDuration   sql.NullInt64
	ReturnStops      sql.NullInt64
	CreatedAt        time.Time
}

FlightOffer represents the data structure for a single flight offer row

type FlightSegment

type FlightSegment struct {
	ID               int
	FlightOfferID    int // Foreign key
	AirlineCode      string
	FlightNumber     string
	DepartureAirport string
	ArrivalAirport   string
	DepartureTime    time.Time
	ArrivalTime      time.Time
	Duration         int
	Airplane         string
	Legroom          string
	IsReturn         bool
}

FlightSegment represents the data structure for a single flight segment row

type JobDetails

type JobDetails struct {
	JobID              int // Foreign key or primary key if separate table
	Origin             string
	Destination        string
	DepartureDateStart time.Time
	DepartureDateEnd   time.Time
	ReturnDateStart    sql.NullTime
	ReturnDateEnd      sql.NullTime
	TripLength         sql.NullInt32
	DynamicDates       bool          // Use dates relative to execution time
	DaysFromExecution  sql.NullInt32 // Start searching X days from now
	SearchWindowDays   sql.NullInt32 // Search within X days window
	Adults             int
	Children           int
	InfantsLap         int
	InfantsSeat        int
	TripType           string
	Class              string
	Stops              string
	Currency           string // Added Currency
}

JobDetails represents the data structure for job details row

type LegInfo

type LegInfo struct {
	Origin      string  `json:"origin"`
	Destination string  `json:"destination"`
	Price       float64 `json:"price"`
	Airline     string  `json:"airline,omitempty"`
}

LegInfo contains pricing info for a single leg

type Neo4jDB

type Neo4jDB struct {
	// contains filtered or unexported fields
}

Neo4jDB represents a Neo4j database connection. It implicitly implements the Neo4jDatabase interface.

func NewNeo4jDB

func NewNeo4jDB(cfg config.Neo4jConfig) (*Neo4jDB, error)

NewNeo4jDB creates a new Neo4j database connection

func (*Neo4jDB) AddPricePoint

func (n *Neo4jDB) AddPricePoint(originCode, destCode string, departDate string, returnDate string, price float64, airlineCode string, tripType string, class string) error

AddPricePoint adds or updates a price point for a route on a specific date

func (*Neo4jDB) Close

func (n *Neo4jDB) Close() error

Close closes the database connection

func (*Neo4jDB) CreateAirline

func (n *Neo4jDB) CreateAirline(code, name, country string) error

CreateAirline creates or updates an airline node in Neo4j

func (*Neo4jDB) CreateAirport

func (n *Neo4jDB) CreateAirport(code, name, city, country string, latitude, longitude float64) error

CreateAirport creates or updates an airport node in Neo4j

func (*Neo4jDB) CreateFlightRoute

func (n *Neo4jDB) CreateFlightRoute(originCode, destCode, airlineCode string, distance int) error

CreateFlightRoute creates a directed flight route relationship with properties

func (*Neo4jDB) CreateRoute

func (n *Neo4jDB) CreateRoute(originCode, destCode, airlineCode, flightNumber string, avgPrice float64, avgDuration int) error

CreateRoute creates or updates a route relationship between airports

func (*Neo4jDB) ExecuteReadQuery

func (n *Neo4jDB) ExecuteReadQuery(ctx context.Context, query string, params map[string]interface{}) (Neo4jResult, error)

ExecuteReadQuery runs a read-only query against Neo4j. The returned Neo4jResult wraps both the result and session - caller MUST call Close() when done.

func (*Neo4jDB) FindCheapestPath

func (n *Neo4jDB) FindCheapestPath(ctx context.Context, origin, dest string, maxHops int, maxPrice float64) ([]PathResult, error)

FindCheapestPath finds the cheapest multi-hop paths between two airports

func (*Neo4jDB) FindConnections

func (n *Neo4jDB) FindConnections(ctx context.Context, origin string, maxHops int, maxPrice float64) ([]Connection, error)

FindConnections finds all reachable destinations from an origin within budget

func (*Neo4jDB) GetRouteStats

func (n *Neo4jDB) GetRouteStats(ctx context.Context, origin, dest string) (*RouteStats, error)

GetRouteStats returns aggregated price statistics for a specific route

func (*Neo4jDB) InitSchema

func (n *Neo4jDB) InitSchema() error

InitSchema initializes the database schema

func (*Neo4jDB) SeedNeo4jData

func (n *Neo4jDB) SeedNeo4jData(ctx context.Context, postgresDB PostgresDB) error

SeedNeo4jData seeds the Neo4j database with airports from the iata package. This is IDEMPOTENT - uses MERGE to create or update nodes.

type Neo4jDatabase

type Neo4jDatabase interface {
	CreateAirport(code, name, city, country string, latitude, longitude float64) error
	CreateRoute(originCode, destCode, airlineCode, flightNumber string, avgPrice float64, avgDuration int) error
	AddPricePoint(originCode, destCode string, departDate string, returnDate string, price float64, airlineCode string, tripType string, class string) error
	CreateAirline(code, name, country string) error
	Close() error
	ExecuteReadQuery(ctx context.Context, query string, params map[string]interface{}) (Neo4jResult, error)
	InitSchema() error
	// Graph traversal methods
	FindCheapestPath(ctx context.Context, origin, dest string, maxHops int, maxPrice float64) ([]PathResult, error)
	FindConnections(ctx context.Context, origin string, maxHops int, maxPrice float64) ([]Connection, error)
	GetRouteStats(ctx context.Context, origin, dest string) (*RouteStats, error)
}

Neo4jDatabase defines the interface for Neo4j database operations.

type Neo4jResult

type Neo4jResult interface {
	Next() bool // Removed context from Next again based on error at line 96
	Record() *neo4j.Record
	Err() error
	Close() error // Close the result and underlying session
}

Neo4jResult defines the interface for Neo4j query results

type Neo4jResultWithSession

type Neo4jResultWithSession struct {
	// contains filtered or unexported fields
}

Neo4jResultWithSession wraps a Neo4j result and its session to ensure proper cleanup. The session is closed when Close() is called on this wrapper.

func (*Neo4jResultWithSession) Close

func (r *Neo4jResultWithSession) Close() error

Close closes the underlying session (and implicitly the result)

func (*Neo4jResultWithSession) Err

func (r *Neo4jResultWithSession) Err() error

Err returns any error from result iteration

func (*Neo4jResultWithSession) Next

func (r *Neo4jResultWithSession) Next() bool

Next advances the result cursor

func (*Neo4jResultWithSession) Record

func (r *Neo4jResultWithSession) Record() *neo4j.Record

Record returns the current record

type Neo4jSession

type Neo4jSession interface {
	Run(ctx context.Context, cypher string, params map[string]interface{}) (Neo4jResult, error)
	Close() error // Keep context removed from Close
}

Neo4jSession defines the interface for a Neo4j session (read operations)

type PathResult

type PathResult struct {
	Stops      []string  `json:"stops"`       // Airport codes in order
	TotalPrice float64   `json:"total_price"` // Sum of leg prices
	Legs       []LegInfo `json:"legs"`        // Details per leg
}

PathResult represents a multi-hop route path with total cost

type PostgresDB

type PostgresDB interface {
	GetSearchByID(id string) (*Search, error)
	SaveSearch(search *Search) (string, error)
	Search(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	GetCertificate(domain string) (*Certificate, error)
	StoreCertificate(domain string, cert []byte, key []byte, expires time.Time) error
	Close() error
	// GetDB() *sql.DB // Remove this to enforce mocking via interface methods
	InitSchema() error
	BeginTx(ctx context.Context) (Tx, error) // Add transaction support

	// Add specific query methods needed by handlers
	QueryAirports(ctx context.Context) (Rows, error)
	QueryAirlines(ctx context.Context) (Rows, error)
	GetSearchQueryByID(ctx context.Context, id int) (*SearchQuery, error) // Define SearchQuery struct later
	GetFlightOffersBySearchID(ctx context.Context, searchID int) (Rows, error)
	GetFlightSegmentsByOfferID(ctx context.Context, offerID int) (Rows, error)
	CountSearches(ctx context.Context) (int, error)
	QuerySearchesPaginated(ctx context.Context, limit, offset int) (Rows, error)
	DeleteJobDetailsByJobID(ctx context.Context, tx Tx, jobID int) error
	DeleteScheduledJobByID(ctx context.Context, tx Tx, jobID int) (int64, error)
	GetJobDetailsByID(ctx context.Context, jobID int) (*JobDetails, error) // Define JobDetails struct later
	UpdateJobLastRun(ctx context.Context, jobID int) error
	UpdateJobEnabled(ctx context.Context, jobID int, enabled bool) (int64, error)
	GetJobCronExpression(ctx context.Context, jobID int) (string, error)
	ListJobs(ctx context.Context) (Rows, error)
	CreateScheduledJob(ctx context.Context, tx Tx, name, cronExpression string, enabled bool) (int, error)
	CreateJobDetails(ctx context.Context, tx Tx, details JobDetails) error
	UpdateScheduledJob(ctx context.Context, tx Tx, jobID int, name, cronExpression string) error
	UpdateJobDetails(ctx context.Context, tx Tx, jobID int, details JobDetails) error
	GetJobByID(ctx context.Context, jobID int) (*ScheduledJob, error)         // Define ScheduledJob struct later
	GetBulkSearchByID(ctx context.Context, searchID int) (*BulkSearch, error) // Define BulkSearch struct later
	QueryBulkSearchResultsPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
	InsertBulkSearchOffer(ctx context.Context, record BulkSearchOfferRecord) error
	QueryBulkSearchOffersPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
	ListBulkSearchOffers(ctx context.Context, searchID int) ([]BulkSearchOffer, error)
	CreateBulkSearchRecord(ctx context.Context, jobID sql.NullInt32, totalSearches int, currency, status string) (int, error)
	UpdateBulkSearchStatus(ctx context.Context, bulkSearchID int, status string) error
	UpdateBulkSearchTotalSearches(ctx context.Context, bulkSearchID int, totalSearches int) error
	UpdateBulkSearchProgress(ctx context.Context, bulkSearchID int, completed, totalOffers, errorCount int) error
	CompleteBulkSearch(ctx context.Context, summary BulkSearchSummary) error
	InsertBulkSearchResult(ctx context.Context, result BulkSearchResultRecord) error
	InsertBulkSearchResultsBatch(ctx context.Context, results []BulkSearchResultRecord) error
	// IncrementBulkSearchProgress atomically increments the completed count for a fan-out bulk search
	// and returns the new completed count and total routes.
	IncrementBulkSearchProgress(ctx context.Context, bulkSearchID int) (completed, total int, err error)
	// FinalizeBulkSearch computes final stats (min/max/avg price) and marks the search complete.
	FinalizeBulkSearch(ctx context.Context, bulkSearchID int) error
	ListBulkSearches(ctx context.Context, limit, offset int) (Rows, error)
	CreatePriceGraphSweep(ctx context.Context, jobID sql.NullInt32, originCount, destinationCount int, tripLengthMin, tripLengthMax sql.NullInt32, currency string) (int, error)
	UpdatePriceGraphSweepStatus(ctx context.Context, sweepID int, status string, startedAt, completedAt sql.NullTime, errorCount int) error
	GetPriceGraphSweepByID(ctx context.Context, sweepID int) (*PriceGraphSweep, error)
	ListPriceGraphSweeps(ctx context.Context, limit, offset int) (Rows, error)
	InsertPriceGraphResult(ctx context.Context, record PriceGraphResultRecord) error
	ListPriceGraphResults(ctx context.Context, sweepID, limit, offset int) (Rows, error)

	// Continuous sweep progress methods
	SaveContinuousSweepProgress(ctx context.Context, progress ContinuousSweepProgress) error
	SetContinuousSweepControlFlags(ctx context.Context, isRunning, isPaused *bool) error
	GetContinuousSweepProgress(ctx context.Context) (*ContinuousSweepProgress, error)
	InsertContinuousSweepStats(ctx context.Context, stats ContinuousSweepStats) error
	ListContinuousSweepStats(ctx context.Context, limit int) ([]ContinuousSweepStats, error)
	ListContinuousSweepResults(ctx context.Context, filters ContinuousSweepResultsFilter) ([]PriceGraphResultRecord, error)

	// Deal detection methods
	GetRouteBaseline(ctx context.Context, origin, dest string, tripLength int, class string) (*RouteBaseline, error)
	UpsertRouteBaseline(ctx context.Context, baseline RouteBaseline) error
	GetPriceHistoryForRoute(ctx context.Context, origin, dest string, tripLength int, class string, windowDays int) ([]float64, error)
	InsertDetectedDeal(ctx context.Context, deal DetectedDeal) (int, error)
	UpsertDetectedDeal(ctx context.Context, deal DetectedDeal) error
	GetDetectedDealByFingerprint(ctx context.Context, fingerprint string) (*DetectedDeal, error)
	ListActiveDeals(ctx context.Context, filter DealFilter) ([]DetectedDeal, error)
	ExpireOldDeals(ctx context.Context) (int64, error)
	InsertDealAlert(ctx context.Context, alert DealAlert) (int, error)
	ListDealAlerts(ctx context.Context, limit, offset int) ([]DealAlert, error)
}

PostgresDB interface defines the database operations

func NewPostgresDB

func NewPostgresDB(cfg config.PostgresConfig) (PostgresDB, error)

NewPostgresDB creates a new PostgreSQL database connection

type PostgresDBImpl

type PostgresDBImpl struct {
	// contains filtered or unexported fields
}

PostgresDBImpl is the concrete implementation

func (*PostgresDBImpl) BeginTx

func (p *PostgresDBImpl) BeginTx(ctx context.Context) (Tx, error)

BeginTx starts a new transaction

func (*PostgresDBImpl) Close

func (p *PostgresDBImpl) Close() error

Close closes the database connection

func (*PostgresDBImpl) CompleteBulkSearch

func (p *PostgresDBImpl) CompleteBulkSearch(ctx context.Context, summary BulkSearchSummary) error

func (*PostgresDBImpl) CountSearches

func (p *PostgresDBImpl) CountSearches(ctx context.Context) (int, error)

func (*PostgresDBImpl) CreateBulkSearchRecord

func (p *PostgresDBImpl) CreateBulkSearchRecord(ctx context.Context, jobID sql.NullInt32, totalSearches int, currency, status string) (int, error)

func (*PostgresDBImpl) CreateJobDetails

func (p *PostgresDBImpl) CreateJobDetails(ctx context.Context, tx Tx, details JobDetails) error

func (*PostgresDBImpl) CreatePriceGraphSweep

func (p *PostgresDBImpl) CreatePriceGraphSweep(ctx context.Context, jobID sql.NullInt32, originCount, destinationCount int, tripLengthMin, tripLengthMax sql.NullInt32, currency string) (int, error)

func (*PostgresDBImpl) CreateScheduledJob

func (p *PostgresDBImpl) CreateScheduledJob(ctx context.Context, tx Tx, name, cronExpression string, enabled bool) (int, error)

func (*PostgresDBImpl) DeleteJobDetailsByJobID

func (p *PostgresDBImpl) DeleteJobDetailsByJobID(ctx context.Context, tx Tx, jobID int) error

func (*PostgresDBImpl) DeleteScheduledJobByID

func (p *PostgresDBImpl) DeleteScheduledJobByID(ctx context.Context, tx Tx, jobID int) (int64, error)

func (*PostgresDBImpl) ExpireOldDeals

func (p *PostgresDBImpl) ExpireOldDeals(ctx context.Context) (int64, error)

ExpireOldDeals marks expired deals

func (*PostgresDBImpl) FinalizeBulkSearch

func (p *PostgresDBImpl) FinalizeBulkSearch(ctx context.Context, bulkSearchID int) error

FinalizeBulkSearch computes final stats from bulk_search_results and marks the search complete.

func (*PostgresDBImpl) GetBulkSearchByID

func (p *PostgresDBImpl) GetBulkSearchByID(ctx context.Context, searchID int) (*BulkSearch, error)

func (*PostgresDBImpl) GetCertificate

func (p *PostgresDBImpl) GetCertificate(domain string) (*Certificate, error)

GetCertificate retrieves a certificate from the database

func (*PostgresDBImpl) GetContinuousSweepProgress

func (p *PostgresDBImpl) GetContinuousSweepProgress(ctx context.Context) (*ContinuousSweepProgress, error)

GetContinuousSweepProgress retrieves the current continuous sweep progress

func (*PostgresDBImpl) GetDetectedDealByFingerprint

func (p *PostgresDBImpl) GetDetectedDealByFingerprint(ctx context.Context, fingerprint string) (*DetectedDeal, error)

GetDetectedDealByFingerprint retrieves a deal by its fingerprint

func (*PostgresDBImpl) GetFlightOffersBySearchID

func (p *PostgresDBImpl) GetFlightOffersBySearchID(ctx context.Context, searchID int) (Rows, error)

func (*PostgresDBImpl) GetFlightSegmentsByOfferID

func (p *PostgresDBImpl) GetFlightSegmentsByOfferID(ctx context.Context, offerID int) (Rows, error)

func (*PostgresDBImpl) GetJobByID

func (p *PostgresDBImpl) GetJobByID(ctx context.Context, jobID int) (*ScheduledJob, error)

func (*PostgresDBImpl) GetJobCronExpression

func (p *PostgresDBImpl) GetJobCronExpression(ctx context.Context, jobID int) (string, error)

func (*PostgresDBImpl) GetJobDetailsByID

func (p *PostgresDBImpl) GetJobDetailsByID(ctx context.Context, jobID int) (*JobDetails, error)

func (*PostgresDBImpl) GetPriceGraphSweepByID

func (p *PostgresDBImpl) GetPriceGraphSweepByID(ctx context.Context, sweepID int) (*PriceGraphSweep, error)

func (*PostgresDBImpl) GetPriceHistoryForRoute

func (p *PostgresDBImpl) GetPriceHistoryForRoute(ctx context.Context, origin, dest string, tripLength int, class string, windowDays int) ([]float64, error)

GetPriceHistoryForRoute retrieves historical prices for baseline calculation

func (*PostgresDBImpl) GetRouteBaseline

func (p *PostgresDBImpl) GetRouteBaseline(ctx context.Context, origin, dest string, tripLength int, class string) (*RouteBaseline, error)

GetRouteBaseline retrieves price baseline for a route

func (*PostgresDBImpl) GetSearchByID

func (p *PostgresDBImpl) GetSearchByID(id string) (*Search, error)

GetSearchByID retrieves a search record by its ID

func (*PostgresDBImpl) GetSearchQueryByID

func (p *PostgresDBImpl) GetSearchQueryByID(ctx context.Context, id int) (*SearchQuery, error)

func (*PostgresDBImpl) IncrementBulkSearchProgress

func (p *PostgresDBImpl) IncrementBulkSearchProgress(ctx context.Context, bulkSearchID int) (completed, total int, err error)

IncrementBulkSearchProgress atomically increments the completed count for a fan-out bulk search and returns the new completed count along with total_searches to check if we're done.

func (*PostgresDBImpl) InitSchema

func (p *PostgresDBImpl) InitSchema() error

InitSchema initializes the database schema

func (*PostgresDBImpl) InsertBulkSearchOffer

func (p *PostgresDBImpl) InsertBulkSearchOffer(ctx context.Context, record BulkSearchOfferRecord) error

func (*PostgresDBImpl) InsertBulkSearchResult

func (p *PostgresDBImpl) InsertBulkSearchResult(ctx context.Context, result BulkSearchResultRecord) error

func (*PostgresDBImpl) InsertBulkSearchResultsBatch

func (p *PostgresDBImpl) InsertBulkSearchResultsBatch(ctx context.Context, results []BulkSearchResultRecord) error

InsertBulkSearchResultsBatch inserts multiple bulk search results in a single transaction using multi-row INSERT for better performance. This reduces round-trips to the database.

func (*PostgresDBImpl) InsertContinuousSweepStats

func (p *PostgresDBImpl) InsertContinuousSweepStats(ctx context.Context, stats ContinuousSweepStats) error

InsertContinuousSweepStats inserts a completed sweep's statistics

func (*PostgresDBImpl) InsertDealAlert

func (p *PostgresDBImpl) InsertDealAlert(ctx context.Context, alert DealAlert) (int, error)

InsertDealAlert inserts a new deal alert

func (*PostgresDBImpl) InsertDetectedDeal

func (p *PostgresDBImpl) InsertDetectedDeal(ctx context.Context, deal DetectedDeal) (int, error)

InsertDetectedDeal inserts a new detected deal

func (*PostgresDBImpl) InsertPriceGraphResult

func (p *PostgresDBImpl) InsertPriceGraphResult(ctx context.Context, record PriceGraphResultRecord) error

func (*PostgresDBImpl) ListActiveDeals

func (p *PostgresDBImpl) ListActiveDeals(ctx context.Context, filter DealFilter) ([]DetectedDeal, error)

ListActiveDeals retrieves active deals with optional filtering

func (*PostgresDBImpl) ListBulkSearchOffers

func (p *PostgresDBImpl) ListBulkSearchOffers(ctx context.Context, searchID int) ([]BulkSearchOffer, error)

func (*PostgresDBImpl) ListBulkSearches

func (p *PostgresDBImpl) ListBulkSearches(ctx context.Context, limit, offset int) (Rows, error)

func (*PostgresDBImpl) ListContinuousSweepResults

func (p *PostgresDBImpl) ListContinuousSweepResults(ctx context.Context, filters ContinuousSweepResultsFilter) ([]PriceGraphResultRecord, error)

ListContinuousSweepResults returns price graph results from continuous sweeps (sweep_id = 0)

func (*PostgresDBImpl) ListContinuousSweepStats

func (p *PostgresDBImpl) ListContinuousSweepStats(ctx context.Context, limit int) ([]ContinuousSweepStats, error)

ListContinuousSweepStats retrieves the most recent sweep statistics

func (*PostgresDBImpl) ListDealAlerts

func (p *PostgresDBImpl) ListDealAlerts(ctx context.Context, limit, offset int) ([]DealAlert, error)

ListDealAlerts retrieves published deal alerts with pagination

func (*PostgresDBImpl) ListJobs

func (p *PostgresDBImpl) ListJobs(ctx context.Context) (Rows, error)

func (*PostgresDBImpl) ListPriceGraphResults

func (p *PostgresDBImpl) ListPriceGraphResults(ctx context.Context, sweepID, limit, offset int) (Rows, error)

func (*PostgresDBImpl) ListPriceGraphSweeps

func (p *PostgresDBImpl) ListPriceGraphSweeps(ctx context.Context, limit, offset int) (Rows, error)

func (*PostgresDBImpl) QueryAirlines

func (p *PostgresDBImpl) QueryAirlines(ctx context.Context) (Rows, error)

func (*PostgresDBImpl) QueryAirports

func (p *PostgresDBImpl) QueryAirports(ctx context.Context) (Rows, error)

func (*PostgresDBImpl) QueryBulkSearchOffersPaginated

func (p *PostgresDBImpl) QueryBulkSearchOffersPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)

func (*PostgresDBImpl) QueryBulkSearchResultsPaginated

func (p *PostgresDBImpl) QueryBulkSearchResultsPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)

func (*PostgresDBImpl) QuerySearchesPaginated

func (p *PostgresDBImpl) QuerySearchesPaginated(ctx context.Context, limit, offset int) (Rows, error)

func (*PostgresDBImpl) SaveContinuousSweepProgress

func (p *PostgresDBImpl) SaveContinuousSweepProgress(ctx context.Context, progress ContinuousSweepProgress) error

SaveContinuousSweepProgress saves or updates the continuous sweep progress (upsert)

func (*PostgresDBImpl) SaveSearch

func (p *PostgresDBImpl) SaveSearch(search *Search) (string, error)

SaveSearch saves a search record to the database TODO: Implement SaveSearch logic

func (*PostgresDBImpl) Search

func (p *PostgresDBImpl) Search(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

Search executes a generic search query TODO: Implement Search logic if needed, or remove if unused

func (*PostgresDBImpl) SeedData

func (p *PostgresDBImpl) SeedData() error

SeedData seeds the database with initial data

func (*PostgresDBImpl) SetContinuousSweepControlFlags

func (p *PostgresDBImpl) SetContinuousSweepControlFlags(ctx context.Context, isRunning, isPaused *bool) error

func (*PostgresDBImpl) StoreCertificate

func (p *PostgresDBImpl) StoreCertificate(domain string, certChain []byte, privateKey []byte, expires time.Time) error

StoreCertificate saves a certificate to the database

func (*PostgresDBImpl) UpdateBulkSearchProgress

func (p *PostgresDBImpl) UpdateBulkSearchProgress(ctx context.Context, bulkSearchID int, completed, totalOffers, errorCount int) error

func (*PostgresDBImpl) UpdateBulkSearchStatus

func (p *PostgresDBImpl) UpdateBulkSearchStatus(ctx context.Context, bulkSearchID int, status string) error

func (*PostgresDBImpl) UpdateBulkSearchTotalSearches

func (p *PostgresDBImpl) UpdateBulkSearchTotalSearches(ctx context.Context, bulkSearchID int, totalSearches int) error

func (*PostgresDBImpl) UpdateJobDetails

func (p *PostgresDBImpl) UpdateJobDetails(ctx context.Context, tx Tx, jobID int, details JobDetails) error

func (*PostgresDBImpl) UpdateJobEnabled

func (p *PostgresDBImpl) UpdateJobEnabled(ctx context.Context, jobID int, enabled bool) (int64, error)

func (*PostgresDBImpl) UpdateJobLastRun

func (p *PostgresDBImpl) UpdateJobLastRun(ctx context.Context, jobID int) error

func (*PostgresDBImpl) UpdatePriceGraphSweepStatus

func (p *PostgresDBImpl) UpdatePriceGraphSweepStatus(ctx context.Context, sweepID int, status string, startedAt, completedAt sql.NullTime, errorCount int) error

func (*PostgresDBImpl) UpdateScheduledJob

func (p *PostgresDBImpl) UpdateScheduledJob(ctx context.Context, tx Tx, jobID int, name, cronExpression string) error

func (*PostgresDBImpl) UpsertDetectedDeal

func (p *PostgresDBImpl) UpsertDetectedDeal(ctx context.Context, deal DetectedDeal) error

UpsertDetectedDeal inserts or updates a deal (for deduplication)

func (*PostgresDBImpl) UpsertRouteBaseline

func (p *PostgresDBImpl) UpsertRouteBaseline(ctx context.Context, baseline RouteBaseline) error

UpsertRouteBaseline inserts or updates a route baseline

type PriceGraphResult

type PriceGraphResult struct {
	ID            int
	SweepID       int
	Origin        string
	Destination   string
	DepartureDate time.Time
	ReturnDate    sql.NullTime
	TripLength    sql.NullInt32
	Price         float64
	Currency      string
	DistanceMiles sql.NullFloat64
	CostPerMile   sql.NullFloat64
	Adults        int
	Children      int
	InfantsLap    int
	InfantsSeat   int
	TripType      string
	Class         string
	Stops         string
	SearchURL     sql.NullString
	QueriedAt     time.Time
	CreatedAt     time.Time
}

PriceGraphResult represents the cheapest fare returned by the price graph API

type PriceGraphResultRecord

type PriceGraphResultRecord struct {
	SweepID       int
	Origin        string
	Destination   string
	DepartureDate time.Time
	ReturnDate    sql.NullTime
	TripLength    sql.NullInt32
	Price         float64
	Currency      string
	DistanceMiles sql.NullFloat64
	CostPerMile   sql.NullFloat64
	Adults        int
	Children      int
	InfantsLap    int
	InfantsSeat   int
	TripType      string
	Class         string
	Stops         string
	SearchURL     sql.NullString
	QueriedAt     time.Time
}

PriceGraphResultRecord is used when inserting price graph results

type PriceGraphSweep

type PriceGraphSweep struct {
	ID               int
	JobID            sql.NullInt32
	Status           string
	OriginCount      int
	DestinationCount int
	TripLengthMin    sql.NullInt32
	TripLengthMax    sql.NullInt32
	Currency         string
	ErrorCount       int
	CreatedAt        time.Time
	UpdatedAt        time.Time
	StartedAt        sql.NullTime
	CompletedAt      sql.NullTime
}

PriceGraphSweep captures metadata about a price graph sweep run

type PriceGraphSweepJobDetails

type PriceGraphSweepJobDetails struct {
	ID                  int
	JobID               int
	TripLengths         []int
	DepartureWindowDays int
	DynamicDates        bool
	TripType            string
	Class               string
	Stops               string
	Adults              int
	Currency            string
	RateLimitMillis     int
	InternationalOnly   bool
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

PriceGraphSweepJobDetails represents sweep-specific job configuration

type Route

type Route struct {
	Origin      string
	Destination string
}

Route represents an origin-destination pair

func GenerateAllRoutes

func GenerateAllRoutes(airports []TopAirport) []Route

GenerateAllRoutes returns all origin-destination pairs (including domestic)

func GenerateInternationalRoutes

func GenerateInternationalRoutes(airports []TopAirport) []Route

GenerateInternationalRoutes returns all origin-destination pairs where countries differ

type RouteBaseline

type RouteBaseline struct {
	ID          int
	Origin      string
	Destination string
	TripLength  int
	Class       string
	SampleCount int
	MeanPrice   sql.NullFloat64
	MedianPrice sql.NullFloat64
	StddevPrice sql.NullFloat64
	MinPrice    sql.NullFloat64
	MaxPrice    sql.NullFloat64
	P10Price    sql.NullFloat64
	P25Price    sql.NullFloat64
	P75Price    sql.NullFloat64
	P90Price    sql.NullFloat64
	WindowStart sql.NullTime
	WindowEnd   sql.NullTime
	UpdatedAt   time.Time
	CreatedAt   time.Time
}

RouteBaseline stores historical price statistics for a route

type RoutePricePoint

type RoutePricePoint struct {
	Date       string  `json:"date,omitempty"`
	Price      float64 `json:"price"`
	Airline    string  `json:"airline,omitempty"`
	SeenAt     string  `json:"seen_at,omitempty"`
	TripType   string  `json:"trip_type,omitempty"`
	ReturnDate string  `json:"return_date,omitempty"`
}

type RouteStats

type RouteStats struct {
	Origin      string   `json:"origin"`
	Destination string   `json:"destination"`
	MinPrice    float64  `json:"min_price"`
	MaxPrice    float64  `json:"max_price"`
	AvgPrice    float64  `json:"avg_price"`
	PricePoints int      `json:"price_points"` // Number of observations
	Airlines    []string `json:"airlines"`     // Airlines serving the route

	// Source indicates which graph dataset produced these stats.
	// - price_point: derived from :PRICE_POINT relationships (date-specific, filterable by date/age/trip type)
	// - route: derived from :ROUTE relationships (avgPrice aggregates, no date-specific samples)
	Source string `json:"source,omitempty"`
	Note   string `json:"note,omitempty"`

	RouteEdges int `json:"route_edges,omitempty"` // Populated when Source=route.

	MinPriceDate       string `json:"min_price_date,omitempty"`
	MinPriceAirline    string `json:"min_price_airline,omitempty"`
	MinPriceSeenAt     string `json:"min_price_seen_at,omitempty"`
	MinPriceTripType   string `json:"min_price_trip_type,omitempty"`
	MinPriceReturnDate string `json:"min_price_return_date,omitempty"`

	MaxPriceDate       string `json:"max_price_date,omitempty"`
	MaxPriceAirline    string `json:"max_price_airline,omitempty"`
	MaxPriceSeenAt     string `json:"max_price_seen_at,omitempty"`
	MaxPriceTripType   string `json:"max_price_trip_type,omitempty"`
	MaxPriceReturnDate string `json:"max_price_return_date,omitempty"`

	FirstSeenAt string `json:"first_seen_at,omitempty"`
	LastSeenAt  string `json:"last_seen_at,omitempty"`

	Samples []RoutePricePoint `json:"samples,omitempty"`
}

RouteStats contains aggregated statistics for a route

type RowScanner

type RowScanner interface {
	Scan(dest ...interface{}) error
}

RowScanner defines the interface for scanning a single row result. This allows mocking database row scanning behavior.

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...interface{}) error
	Close() error
	Err() error
}

Rows defines the interface for query results

type ScheduledJob

type ScheduledJob struct {
	ID             int
	Name           string
	CronExpression string
	Enabled        bool
	LastRun        sql.NullTime
	CreatedAt      time.Time
	UpdatedAt      time.Time
	JobType        string // "bulk_search" or "price_graph_sweep"
}

ScheduledJob represents the data structure for a scheduled job row

type Search struct {
	ID          string
	SearchID    string
	Origin      string
	Destination string
	Departure   time.Time
	Return      *time.Time
	Passengers  int
	CabinClass  string
	Status      string
	Results     []flights.FullOffer
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

Search represents a flight search query and results (kept for potential future use, though might be redundant)

type SearchNotFoundError

type SearchNotFoundError struct {
	ID string
}

SearchNotFoundError is returned when the search is not found

func (*SearchNotFoundError) Error

func (e *SearchNotFoundError) Error() string

type SearchQuery

type SearchQuery struct {
	ID            int
	Origin        string
	Destination   string
	DepartureDate time.Time
	ReturnDate    sql.NullTime
	Status        string
	CreatedAt     time.Time
}

SearchQuery represents the data structure for a single search query row

type SweepStatusResponse

type SweepStatusResponse struct {
	IsRunning           bool      `json:"is_running"`
	IsPaused            bool      `json:"is_paused"`
	SweepNumber         int       `json:"sweep_number"`
	RouteIndex          int       `json:"route_index"`
	TotalRoutes         int       `json:"total_routes"`
	ProgressPercent     float64   `json:"progress_percent"`
	CurrentOrigin       string    `json:"current_origin"`
	CurrentDestination  string    `json:"current_destination"`
	Class               string    `json:"class"`
	Stops               string    `json:"stops"`
	TripLengths         []int     `json:"trip_lengths"`
	QueriesCompleted    int       `json:"queries_completed"`
	ErrorsCount         int       `json:"errors_count"`
	LastError           string    `json:"last_error,omitempty"`
	SweepStartedAt      time.Time `json:"sweep_started_at,omitempty"`
	EstimatedCompletion time.Time `json:"estimated_completion,omitempty"`
	PacingMode          string    `json:"pacing_mode"`
	CurrentDelayMs      int       `json:"current_delay_ms"`
	MinDelayMs          int       `json:"min_delay_ms"`
	TargetDurationHours int       `json:"target_duration_hours"`
	QueriesPerHour      float64   `json:"queries_per_hour"`
}

SweepStatusResponse is the API response for sweep status

type TopAirport

type TopAirport struct {
	Code    string
	Country string
}

TopAirport represents an airport with its country code for international filtering

type Tx

type Tx interface {
	Commit() error
	Rollback() error
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
	QueryRowContext(ctx context.Context, query string, args ...any) RowScanner // Use RowScanner and ...any

}

Tx defines the interface for database transactions

type TxWrapper

type TxWrapper struct {
	*sql.Tx
}

TxWrapper wraps *sql.Tx to satisfy the db.Tx interface, specifically adapting QueryRowContext.

func (*TxWrapper) QueryRowContext

func (tw *TxWrapper) QueryRowContext(ctx context.Context, query string, args ...any) RowScanner

QueryRowContext calls the underlying *sql.Tx.QueryRowContext and returns the *sql.Row, which satisfies the db.RowScanner interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL