Help us shape the future of Go! Take the 2026 Go Developer Survey

schema

package
v1.26.6 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package schema provides functionality for the TDTP framework.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatTimeOfDay

func FormatTimeOfDay(t time.Time) string

FormatTimeOfDay renders a TIME value (PostgreSQL `time`, subtype "time") as plain time of day. Trailing zeros in the fraction are trimmed and the dot disappears entirely when there is none, so a whole-second value formats as "14:38:11" — the same bytes the previous %02d:%02d:%02d formatting produced, while microseconds now survive instead of being cut off.

func FormatTimestamp

func FormatTimestamp(t time.Time) string

FormatTimestamp renders a DATETIME/TIMESTAMP value in TDTP's canonical form. It is the single definition of that format: adapters converting a driver value and FormatValue re-formatting a parsed one must agree, or the second pass silently undoes the first.

RFC3339Nano rather than RFC3339, because RFC3339 formats to whole seconds and every database this framework talks to stores more: Postgres `timestamp` keeps microseconds, MSSQL `datetime2` up to 100ns. Exporting through RFC3339 discarded that, and a round-trip could not give it back.

The loss was not only cosmetic. --sync-incremental derives its watermark from the exported data, so against a microsecond column the watermark could never represent the row it stood for: `last_updated > '11:38:11Z'` still matches the row at 11:38:11.52877, and the sync re-sent that row on every run forever. Neither > nor >= converges when the watermark is coarser than the values it is compared against.

Compatibility rests on two measured properties:

  • A value with no sub-second component formats byte-identically under both layouts, so packets for such data — and their checksums — do not change.
  • time.Parse with the RFC3339 layout already accepts a fractional part, so every existing reader takes the longer string unchanged. datetimeFormats above leads with exactly that layout.

One caveat: RFC3339Nano trims trailing zeros, so widths differ between rows and "…:11.5Z" sorts before "…:11Z" as raw text. Nothing here compares these as text — tdtql's comparator compares parsed times, the SQL generator hands the value to the database, and sync's watermark comparison parses first — but a caller sorting the raw strings would be wrong to.

func GetDefaultPrecision

func GetDefaultPrecision() int

GetDefaultPrecision возвращает точность по умолчанию для DECIMAL

func GetDefaultScale

func GetDefaultScale() int

GetDefaultScale возвращает масштаб по умолчанию для DECIMAL

func GetDefaultTimezone

func GetDefaultTimezone() string

GetDefaultTimezone возвращает таймзону по умолчанию

func IsBlobType

func IsBlobType(t DataType) bool

IsBlobType проверяет является ли тип бинарным

func IsBooleanType

func IsBooleanType(t DataType) bool

IsBooleanType проверяет является ли тип логическим

func IsDateTimeType

func IsDateTimeType(t DataType) bool

IsDateTimeType проверяет является ли тип временным

func IsNumericType

func IsNumericType(t DataType) bool

IsNumericType проверяет является ли тип числовым

func IsTextType

func IsTextType(t DataType) bool

IsTextType проверяет является ли тип текстовым

func IsValidType

func IsValidType(t DataType) bool

IsValidType проверяет валидность типа данных

Types

type Builder

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

Builder помогает строить схемы

func NewBuilder

func NewBuilder() *Builder

NewBuilder создает новый builder

func (*Builder) AddBlob

func (b *Builder) AddBlob(name string) *Builder

AddBlob добавляет BLOB поле

func (*Builder) AddBoolean

func (b *Builder) AddBoolean(name string) *Builder

AddBoolean добавляет BOOLEAN поле

func (*Builder) AddDate

func (b *Builder) AddDate(name string) *Builder

AddDate добавляет DATE поле

func (*Builder) AddDatetime

func (b *Builder) AddDatetime(name, timezone string) *Builder

AddDatetime добавляет DATETIME поле

func (*Builder) AddDecimal

func (b *Builder) AddDecimal(name string, precision, scale int) *Builder

AddDecimal добавляет DECIMAL поле

func (*Builder) AddField

func (b *Builder) AddField(field packet.Field) *Builder

AddField добавляет произвольное поле

func (*Builder) AddInteger

func (b *Builder) AddInteger(name string, key bool) *Builder

AddInteger добавляет INTEGER поле

func (*Builder) AddReal

func (b *Builder) AddReal(name string) *Builder

AddReal добавляет REAL поле

func (*Builder) AddText

func (b *Builder) AddText(name string, length int) *Builder

AddText добавляет TEXT поле

func (*Builder) AddTimestamp

func (b *Builder) AddTimestamp(name string) *Builder

AddTimestamp добавляет TIMESTAMP поле

func (*Builder) Build

func (b *Builder) Build() packet.Schema

Build строит схему

func (*Builder) FieldCount

func (b *Builder) FieldCount() int

FieldCount возвращает количество полей

func (*Builder) HasKeyField

func (b *Builder) HasKeyField() bool

HasKeyField проверяет наличие первичного ключа

func (*Builder) Reset

func (b *Builder) Reset() *Builder

Reset очищает builder

type Converter

type Converter struct{}

Converter отвечает за конвертацию значений

func NewConverter

func NewConverter() *Converter

NewConverter создает новый конвертер

func (*Converter) FormatValue

func (c *Converter) FormatValue(tv *TypedValue) string

FormatValue форматирует типизированное значение обратно в строку

func (*Converter) ParseValue

func (c *Converter) ParseValue(rawValue string, field FieldDef) (*TypedValue, error)

ParseValue парсит строковое значение согласно типу поля

type DataType

type DataType string

DataType представляет тип данных поля

const (
	TypeInteger   DataType = "INTEGER"
	TypeInt       DataType = "INT"
	TypeReal      DataType = "REAL"
	TypeFloat     DataType = "FLOAT"
	TypeDouble    DataType = "DOUBLE"
	TypeDecimal   DataType = "DECIMAL"
	TypeText      DataType = "TEXT"
	TypeVarchar   DataType = "VARCHAR"
	TypeChar      DataType = "CHAR"
	TypeString    DataType = "STRING"
	TypeBoolean   DataType = "BOOLEAN"
	TypeBool      DataType = "BOOL"
	TypeDate      DataType = "DATE"
	TypeDatetime  DataType = "DATETIME"
	TypeTimestamp DataType = "TIMESTAMP"
	TypeBlob      DataType = "BLOB"
)

Поддерживаемые типы данных согласно спецификации TDTP

func NormalizeType

func NormalizeType(t DataType) DataType

NormalizeType нормализует синонимы типов

type FieldDef

type FieldDef struct {
	Name      string
	Type      DataType
	Subtype   string // e.g., "time", "jsonb", "uuid"
	Length    int
	Precision int
	Scale     int
	Timezone  string
	Key       bool
	Nullable  bool
}

FieldDef расширенное определение поля с валидацией

type TypedValue

type TypedValue struct {
	Type DataType
	// Subtype повторяет FieldDef.Subtype ("time", "jsonb", "uuid", ...).
	// Нужен FormatValue и TypedValueToSQL: без него TIME из PostgreSQL
	// неотличим от TIMESTAMP и печатается как "0000-01-01T14:38:11Z" —
	// значение, которое PostgreSQL обратно в колонку time уже не примет.
	Subtype string
	// Precision повторяет FieldDef.Precision. Для DATETIME/TIMESTAMP это
	// разрядность дробной части: адаптер обязан отдать в колонку ровно
	// столько знаков, сколько она вмещает, иначе БД округлит сама.
	Precision  int
	RawValue   string
	IsNull     bool
	IntValue   *int64
	FloatValue *float64
	// DecimalValue is the exact decimal text of a DECIMAL value — no
	// exponent, no float rounding. FloatValue is still set for DECIMAL as a
	// convenience, but float64 keeps ~16 significant digits: writers and
	// formatters must use DecimalValue, or 1234567890123450.1234 becomes
	// 1234567890123450 and 9007199254740993 becomes …992.
	DecimalValue *string
	StringValue  *string
	BoolValue    *bool
	TimeValue    *time.Time
	BlobValue    []byte
}

TypedValue представляет типизированное значение

type ValidationError

type ValidationError struct {
	Field   string
	Message string
	Value   string
}

ValidationError ошибка валидации

func (*ValidationError) Error

func (e *ValidationError) Error() string

type Validator

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

Validator валидирует схемы и данные

func NewValidator

func NewValidator() *Validator

NewValidator создает новый валидатор

func (*Validator) GetFieldByName

func (v *Validator) GetFieldByName(schema packet.Schema, name string) (*packet.Field, error)

GetFieldByName находит поле по имени

func (*Validator) GetKeyFields

func (v *Validator) GetKeyFields(schema packet.Schema) []packet.Field

GetKeyFields возвращает поля первичного ключа

func (*Validator) ValidateDataPacket

func (v *Validator) ValidateDataPacket(pkt *packet.DataPacket) error

ValidateDataPacket проверяет весь DataPacket

func (*Validator) ValidatePrimaryKey

func (v *Validator) ValidatePrimaryKey(rows [][]string, schema packet.Schema) error

ValidatePrimaryKey проверяет уникальность первичного ключа

func (*Validator) ValidateRow

func (v *Validator) ValidateRow(row []string, schema packet.Schema) error

ValidateRow проверяет соответствие строки данных схеме

func (*Validator) ValidateRows

func (v *Validator) ValidateRows(rows [][]string, schema packet.Schema) []error

ValidateRows проверяет множество строк

func (*Validator) ValidateSchema

func (v *Validator) ValidateSchema(schema packet.Schema) error

ValidateSchema проверяет корректность схемы

Jump to

Keyboard shortcuts

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