check / check (push) Successful in 3m16s
GORM adds deleted_at IS NULL to these queries, and SQLite, which has no table statistics here, preferred the deleted_at index to the new single-column ones wherever a column is matched against several values or compared with <. The event log's attempt load, retention's lookups of expired events and their deliveries, and the queue-depth sampler still read every live row. Each index now also covers deleted_at, first in the events index because created_at is compared with <; events keeps its created_at index for retention's final delete. A test checks SQLite's plan for each statement as GORM builds it. Model: opus-5-5
29 lines
1.2 KiB
Go
29 lines
1.2 KiB
Go
package database
|
|
|
|
import "gorm.io/gorm"
|
|
|
|
// DeliveryResult represents the result of a delivery attempt
|
|
//
|
|
//nolint:lll // a struct tag cannot wrap
|
|
type DeliveryResult struct {
|
|
BaseModel
|
|
|
|
// DeliveryID and DeletedAt make up one index, in that order.
|
|
// DeletedAt repeats the BaseModel field only to join it: GORM adds
|
|
// "deleted_at IS NULL" to almost every query, and where a column is
|
|
// matched against several values SQLite otherwise reads through the
|
|
// deleted_at index, which every live row matches.
|
|
DeliveryID string `gorm:"type:uuid;not null;index:idx_delivery_results_delivery_id,priority:1" json:"deliveryId"`
|
|
DeletedAt gorm.DeletedAt `gorm:"index:idx_delivery_results_delivery_id,priority:2" json:"deletedAt,omitzero"`
|
|
|
|
AttemptNum int `gorm:"not null" json:"attemptNum"`
|
|
Success bool `json:"success"`
|
|
StatusCode int `json:"statusCode,omitempty"`
|
|
ResponseBody string `gorm:"type:text" json:"responseBody,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
Duration int64 `json:"durationMs"` // Duration in milliseconds
|
|
|
|
// Relations
|
|
Delivery Delivery `json:"delivery,omitzero"`
|
|
}
|