crossverify

package
v0.120.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package crossverify checks that a database an engine loaded from a generated SQL script holds what the SQLite source holds: the same tables, columns, keys, indexes and every value.

It is an internal package on purpose. It is the verifier of the CI journey of `datatug db copy --to sqlscript:` (scripts/check-journey-mysql.sh), not a command: its long-term home is an extension of `datatug compare` once compare's known defects are fixed, and until then no second public comparison command exists.

The target is read through its Go driver, never through text conversions in the engine: integers as int64, floats as the 64 bits the engine returns, decimals as exact rationals, blobs as bytes. Only a date or time is compared as text, in the format the column was created with. The rules for each column kind are in canon.go. The verifier does not use the script writer's literal code, so a bug of the writer cannot hide itself.

What it expects is the plan the exporter makes for the same SQLite file (faithful.PlanScript), not the warnings of the export: a renamed index is expected under its new name, and the indexes an engine creates itself for a foreign key are modelled and left out.

Index

Constants

View Source
const (
	EngineMySQL  = "mysql"
	EngineMSSQL  = "mssql"
	EngineOracle = "oracle"
)

Engine names the engines the verifier knows.

Variables

This section is empty.

Functions

This section is empty.

Types

type Input

type Input struct {
	Plan   *faithful.ScriptPlan
	Source *sql.DB
	Target *sql.DB
	// Schema is the MySQL database (the SQL Server schema); the connection's current one when empty.
	Schema string
	// Engine is the engine that loaded the script: EngineMySQL (the default) or EngineMSSQL.
	Engine string

	// SourceSHA256 is the hash of the SQLite file, checked against the marker row; "" skips that check.
	SourceSHA256 string
	// contains filtered or unexported fields
}

Input is what to compare: the plan the exporter makes for the SQLite source, the source, and the database the script was loaded into.

type MyCheck added in v0.97.1

type MyCheck struct {
	Name, Clause string
}

MyCheck is a check constraint: its name and the clause as the server prints it (CHECK_CLAUSE).

type MyColumn

type MyColumn struct {
	Name, Type    string
	Nullable      bool
	AutoIncrement bool
	HasDefault    bool
	// Default is COLUMN_DEFAULT as the server prints it: the value of a literal default, the text of an
	// expression default (Generated).
	Default   string
	Generated bool
}

MyColumn is a column as MySQL reports it.

type MyFK

type MyFK struct {
	Name       string
	Columns    []string
	RefTable   string
	RefColumns []string
	OnUpdate   string
	OnDelete   string
	// Deferrable and Deferred are the deferral of the key (Oracle).
	Deferrable, Deferred bool
}

MyFK is a foreign key.

type MyIndex

type MyIndex struct {
	Name   string
	Unique bool
	// Filtered is true for an index with a WHERE clause (SQL Server).
	Filtered bool
	Columns  []MyIndexColumn
}

MyIndex is an index (a unique constraint is a unique index in MySQL).

type MyIndexColumn

type MyIndexColumn struct {
	Name string
	Desc bool
	// Prefix is the indexed prefix length of a prefix index, 0 for the whole column.
	Prefix int
}

MyIndexColumn is one key part of an index.

type MySQLCatalog

type MySQLCatalog struct {
	Schema string
	Tables []*MyTable
}

MySQLCatalog is the catalog of one MySQL database.

func ReadMSSQL added in v0.99.0

func ReadMSSQL(ctx context.Context, db Queryer, schema string) (*MySQLCatalog, error)

ReadMSSQL reads the catalog of schema (the connection's current schema when empty) from the sys views of SQL Server. The result has the shape of the MySQL catalog: the backing index of the primary key is the primary key, the backing index of a UNIQUE constraint is a unique index of the constraint's name, and a foreign key, check constraint or index that is disabled or filtered is flagged.

func ReadMySQL

func ReadMySQL(ctx context.Context, db Queryer, schema string) (*MySQLCatalog, error)

ReadMySQL reads the catalog of schema (the current database when empty) from information_schema.

func ReadOracle added in v0.102.0

func ReadOracle(ctx context.Context, db Queryer, schema string) (*MySQLCatalog, error)

ReadOracle reads the catalog of schema (the connection's current schema when empty) from the ALL_ views of Oracle. The result has the shape of the MySQL catalog: the backing index of the primary key is the primary key, the backing index of a UNIQUE constraint is a unique index of the constraint's name, a function-based unique index over CASE expressions is a filtered index over the columns it names, and a foreign key or check constraint that is disabled or not validated is flagged.

func (*MySQLCatalog) Table

func (c *MySQLCatalog) Table(name string) *MyTable

Table returns the table called name, or nil.

type MyTable

type MyTable struct {
	Name    string
	Columns []MyColumn
	PK      []string
	Indexes []MyIndex // without the primary key
	FKs     []MyFK
	Checks  int
	// CheckClauses are the check constraints, ordered by name.
	CheckClauses []MyCheck
	// Untrusted names the constraints the engine reports as disabled or not checked against the rows (SQL Server).
	Untrusted []string
}

MyTable is a table as MySQL reports it.

type Queryer

type Queryer interface {
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

Queryer is what the reader needs: a *sql.DB, *sql.Conn or *sql.Tx.

type Result

type Result struct {
	Diffs  []faithful.Diff
	Tables int
	Rows   int64
	// Values is the number of values compared one by one.
	Values int64
}

Result is what a verification found.

func Verify

func Verify(ctx context.Context, in Input) (*Result, error)

Verify compares the plan and the SQLite source with what MySQL holds: tables, columns (type, nullability, auto-increment, default), primary keys, foreign keys, unique keys and indexes (the indexes MySQL creates itself for a foreign key excluded), check constraints, row counts, the completion marker, and every value.

Jump to

Keyboard shortcuts

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