43 lines
1.1 KiB
Go
43 lines
1.1 KiB
Go
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"git.offline-twitter.com/offline-labs/gas-stack/pkg/must"
|
|
)
|
|
|
|
// PragmaFKViolation is a result row of SQLite's `pragma foreign_key_check`.
|
|
type PragmaFKViolation struct {
|
|
SrcTable string `db:"table"`
|
|
SrcRowid int `db:"rowid"`
|
|
DstTable string `db:"parent"`
|
|
ForeignKeyIdx int `db:"fkid"`
|
|
}
|
|
|
|
// PragmaFKViolations is a slice of FK violations. It also implements the `error` interface.
|
|
type PragmaFKViolations []PragmaFKViolation
|
|
|
|
func (v PragmaFKViolations) Error() string {
|
|
var b strings.Builder
|
|
for i, fkv := range v {
|
|
if i > 0 {
|
|
b.WriteString("\n")
|
|
}
|
|
fmt.Fprintf(&b, "Item #%d in table %q has invalid reference to table %q", fkv.SrcRowid, fkv.SrcTable, fkv.DstTable)
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
// PragmaForeignKeyCheck uses `pragma foreign_key_check` to do a full database check for any FK violations.
|
|
func PragmaForeignKeyCheck(q sqlx.Queryer) error {
|
|
var ret PragmaFKViolations
|
|
must.Do(sqlx.Select(q, &ret, `pragma foreign_key_check`))
|
|
if len(ret) == 0 {
|
|
return nil
|
|
}
|
|
return ret
|
|
}
|