Documentation
¶
Overview ¶
Package catalog contains concrete implementations of the api.StoreCatalog / api.SchemaTemplateCatalog / api.Transaction interfaces.
The in-memory implementation (InMemoryStoreCatalog + friends) is intended for unit tests and development — it keeps the whole catalog in a mutex-protected map. It does NOT implement real multi-writer transactional isolation; concurrent SaveSchema / Commit across two live transactions may interleave in ways a real FDB-backed impl wouldn't.
The Java-compatible FDB-backed catalog is RecordLayerStoreCatalog (fdb_store_catalog.go).
Index ¶
- Constants
- func BuildCatalogMetaData() (*recordlayer.RecordMetaData, error)
- func DefaultCatalogSubspace() subspace.Subspace
- type CatalogDatabaseMetaData
- func (m *CatalogDatabaseMetaData) Columns(_ context.Context, ...) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) DatabaseProductName() string
- func (m *CatalogDatabaseMetaData) DatabaseProductVersion() string
- func (m *CatalogDatabaseMetaData) DriverName() string
- func (m *CatalogDatabaseMetaData) DriverVersion() string
- func (m *CatalogDatabaseMetaData) IndexInfo(_ context.Context, catalog, schema, table string, unique, _ bool) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) IsReadOnly() bool
- func (m *CatalogDatabaseMetaData) PrimaryKeys(_ context.Context, catalog, schema, table string) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) Schemas(ctx context.Context) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) SchemasFiltered(_ context.Context, catalog, schemaPattern string) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) Tables(_ context.Context, catalog, schemaPattern, tableNamePattern string, ...) (api.ResultSet, error)
- func (m *CatalogDatabaseMetaData) URL() string
- func (m *CatalogDatabaseMetaData) UserName() string
- type CatalogDatabaseMetaDataOptions
- type FDBTransaction
- func (t *FDBTransaction) Abort() error
- func (t *FDBTransaction) BoundSchemaTemplate() api.SchemaTemplate
- func (t *FDBTransaction) Close() error
- func (t *FDBTransaction) Commit() error
- func (t *FDBTransaction) Context() *recordlayer.FDBRecordContext
- func (t *FDBTransaction) IsClosed() bool
- func (t *FDBTransaction) SetBoundSchemaTemplate(template api.SchemaTemplate)
- func (t *FDBTransaction) UnsetBoundSchemaTemplate()
- func (t *FDBTransaction) Unwrap() any
- type InMemorySchemaTemplateCatalog
- func (c *InMemorySchemaTemplateCatalog) CreateTemplate(txn api.Transaction, newTemplate api.SchemaTemplate) error
- func (c *InMemorySchemaTemplateCatalog) DeleteTemplate(txn api.Transaction, templateName string, throwIfDoesNotExist bool) error
- func (c *InMemorySchemaTemplateCatalog) DeleteTemplateVersion(txn api.Transaction, templateName string, version int, ...) error
- func (c *InMemorySchemaTemplateCatalog) DoesSchemaTemplateExist(txn api.Transaction, templateName string) (bool, error)
- func (c *InMemorySchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion(txn api.Transaction, templateName string, version int) (bool, error)
- func (c *InMemorySchemaTemplateCatalog) ListTemplates(txn api.Transaction) (api.ResultSet, error)
- func (c *InMemorySchemaTemplateCatalog) LoadSchemaTemplate(txn api.Transaction, templateName string) (api.SchemaTemplate, error)
- func (c *InMemorySchemaTemplateCatalog) LoadSchemaTemplateAtVersion(txn api.Transaction, templateName string, version int) (api.SchemaTemplate, error)
- func (c *InMemorySchemaTemplateCatalog) LoadTemplateProto(txn api.Transaction, templateName string, version int) (*gen.MetaData, error)
- type InMemoryStoreCatalog
- func (c *InMemoryStoreCatalog) CreateDatabase(txn api.Transaction, dbURI string) error
- func (c *InMemoryStoreCatalog) DeleteDatabase(txn api.Transaction, dbURI string, throwIfDoesNotExist bool) (bool, error)
- func (c *InMemoryStoreCatalog) DeleteSchema(txn api.Transaction, dbURI, schemaName string) error
- func (c *InMemoryStoreCatalog) DoesDatabaseExist(txn api.Transaction, dbURI string) (bool, error)
- func (c *InMemoryStoreCatalog) DoesSchemaExist(txn api.Transaction, dbURI, schemaName string) (bool, error)
- func (c *InMemoryStoreCatalog) ListDatabases(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
- func (c *InMemoryStoreCatalog) ListSchemas(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
- func (c *InMemoryStoreCatalog) ListSchemasInDatabase(txn api.Transaction, databaseID string, _ api.Continuation) (api.ResultSet, error)
- func (c *InMemoryStoreCatalog) LoadSchema(txn api.Transaction, databaseID, schemaName string) (api.Schema, error)
- func (c *InMemoryStoreCatalog) RepairSchema(txn api.Transaction, databaseID, schemaName string) error
- func (c *InMemoryStoreCatalog) SaveSchema(txn api.Transaction, dataToWrite api.Schema, createDatabaseIfNecessary bool, ...) error
- func (c *InMemoryStoreCatalog) SchemaTemplateCatalog() api.SchemaTemplateCatalog
- type InMemoryTransaction
- func (t *InMemoryTransaction) Abort() error
- func (t *InMemoryTransaction) BoundSchemaTemplate() api.SchemaTemplate
- func (t *InMemoryTransaction) Close() error
- func (t *InMemoryTransaction) Commit() error
- func (t *InMemoryTransaction) IsClosed() bool
- func (t *InMemoryTransaction) SetBoundSchemaTemplate(template api.SchemaTemplate)
- func (t *InMemoryTransaction) UnsetBoundSchemaTemplate()
- func (t *InMemoryTransaction) Unwrap() any
- type RecordLayerStoreCatalog
- func (c *RecordLayerStoreCatalog) CreateDatabase(txn api.Transaction, dbURI string) error
- func (c *RecordLayerStoreCatalog) DeleteDatabase(txn api.Transaction, dbURI string, throwIfDoesNotExist bool) (bool, error)
- func (c *RecordLayerStoreCatalog) DeleteSchema(txn api.Transaction, dbURI, schemaName string) error
- func (c *RecordLayerStoreCatalog) DoesDatabaseExist(txn api.Transaction, dbURI string) (bool, error)
- func (c *RecordLayerStoreCatalog) DoesSchemaExist(txn api.Transaction, dbURI, schemaName string) (bool, error)
- func (c *RecordLayerStoreCatalog) Initialize(txn api.Transaction) error
- func (c *RecordLayerStoreCatalog) ListDatabases(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
- func (c *RecordLayerStoreCatalog) ListSchemas(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
- func (c *RecordLayerStoreCatalog) ListSchemasInDatabase(txn api.Transaction, databaseID string, _ api.Continuation) (api.ResultSet, error)
- func (c *RecordLayerStoreCatalog) LoadSchema(txn api.Transaction, databaseID, schemaName string) (api.Schema, error)
- func (c *RecordLayerStoreCatalog) RepairSchema(txn api.Transaction, dbURI, schemaName string) error
- func (c *RecordLayerStoreCatalog) RestoreTemplateVersion(ctx context.Context, db *recordlayer.FDBDatabase, ...) error
- func (c *RecordLayerStoreCatalog) SaveSchema(txn api.Transaction, s api.Schema, createDatabaseIfNecessary bool, ...) error
- func (c *RecordLayerStoreCatalog) SchemaTemplateCatalog() api.SchemaTemplateCatalog
- type RecordLayerStoreSchemaTemplateCatalog
- func (c *RecordLayerStoreSchemaTemplateCatalog) CreateTemplate(txn api.Transaction, newTemplate api.SchemaTemplate) error
- func (c *RecordLayerStoreSchemaTemplateCatalog) DeleteTemplate(txn api.Transaction, templateName string, throwIfDoesNotExist bool) error
- func (c *RecordLayerStoreSchemaTemplateCatalog) DeleteTemplateVersion(txn api.Transaction, templateName string, version int, ...) error
- func (c *RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExist(txn api.Transaction, templateName string) (bool, error)
- func (c *RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion(txn api.Transaction, templateName string, version int) (bool, error)
- func (c *RecordLayerStoreSchemaTemplateCatalog) ListTemplates(txn api.Transaction) (api.ResultSet, error)
- func (c *RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplate(txn api.Transaction, templateName string) (api.SchemaTemplate, error)
- func (c *RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplateAtVersion(txn api.Transaction, templateName string, version int) (api.SchemaTemplate, error)
- func (c *RecordLayerStoreSchemaTemplateCatalog) LoadTemplateProto(txn api.Transaction, templateName string, version int) (*gen.MetaData, error)
- type RelationalSchemaEvolutionValidator
- type TemplateBinding
Constants ¶
const ( // SysConstant is the root system namespace ("__SYS"). Contains // the catalog's own record store. SysConstant = "__SYS" // CatalogConstant is the schema name inside __SYS that holds the // catalog records (DATABASE_INFO, SCHEMA, SCHEMA_TEMPLATE). CatalogConstant = "CATALOG" // DBNameDir is the KeySpaceDirectory name for a database entry // under a domain. DBNameDir = "dbName" // SchemaDir is the KeySpaceDirectory name for a schema entry // under a database. SchemaDir = "schema" // DefaultSchemaDir marks the "default" schema child directory // (used for convenience-resolution today per Java). DefaultSchemaDir = "defaultSchema" // InterningLayer is the dedicated subspace name for the // interning-layer string resolver (turns long domain / db names // into short integer IDs). InterningLayer = "__internedStrings" // InterningLayerValue is the fixed scalar stored at the // interning-layer subspace (two-byte sentinel "IL"). InterningLayerValue = "IL" )
Keyspace-path constants for the FDB-backed catalog. Mirrors Java's com.apple.foundationdb.relational.recordlayer.RelationalKeyspaceProvider byte-for-byte so the on-FDB layout is cross-language compatible.
Layout:
/ — root
└── __SYS — system schema (SysConstant)
└── CATALOG — catalog schema (CatalogConstant)
└── <domain name> — user domains (naïve today per Java)
└── <dbName> — DB_NAME_DIR child
└── <schema> — SCHEMA_DIR child
Used by the (not-yet-landed) FDB-backed RecordLayerStoreCatalog to construct KeySpacePaths. Defining the constants here now keeps the whole catalog package as the single source of truth for the SQL-layer-side of the layout; the FDB impl will import these.
const ( ColDatabaseID = "DATABASE_ID" ColSchemaName = "SCHEMA_NAME" ColTemplateName = "TEMPLATE_NAME" ColTemplateVersion = "TEMPLATE_VERSION" ColMetaData = "META_DATA" // Indexes on SCHEMAS. IdxTemplatesCount = "TEMPLATES_COUNT_INDEX" IdxTemplatesValue = "TEMPLATES_VALUE_INDEX" // Index on DATABASES. IdxDatabasesCount = "DATABASES_COUNT_INDEX" )
Catalog column / index constants. Mirror Java's com.apple.foundationdb.relational.recordlayer.catalog.systables.SystemTable + sibling table classes.
const ( // SchemaRecordTypeKey is the RECORD_TYPE_KEY prefix for Schema // records in the catalog store. SchemaRecordTypeKey int64 = 0 // DatabaseInfoRecordTypeKey prefixes DatabaseInfo records. DatabaseInfoRecordTypeKey int64 = 1 // SchemaTemplateRecordTypeKey prefixes SchemaTemplate records. SchemaTemplateRecordTypeKey int64 = 2 // SchemasTableName is the user-visible INFORMATION_SCHEMA name for // the Schema record type (Java: "SCHEMAS"). The Go proto descriptor // uses the Go-style message name "Schemas"; wire compatibility is // preserved because Java and Go both agree on record-type key 0 // and on field numbers inside the Schemas/SCHEMAS message (both // generated programmatically with the same 1-based column layout). SchemasTableName = "SCHEMAS" // DatabaseTableName — Java-visible name for Databases records. DatabaseTableName = "DATABASES" // SchemaTemplateTableName — Java-visible name for Templates records. SchemaTemplateTableName = "TEMPLATES" // SchemasRecordName / DatabasesRecordName / TemplatesRecordName are // the internal proto descriptor names that recordlayer uses to // resolve record types. They match the message names in // proto/relational/catalog_data.proto. SchemasRecordName = "Schemas" DatabasesRecordName = "Databases" TemplatesRecordName = "Templates" )
System-table identity constants. Mirror Java's com.apple.foundationdb.relational.recordlayer.catalog.systables. SystemTableRegistry byte-for-byte.
RECORD_TYPE_KEY values are the leading tuple element on every catalog record in FDB — they're what distinguishes a Schema record from a Database record at the key level. Java hard-codes the numeric values; changing them breaks wire compatibility for any catalog Java has written to.
The table-name constants are the user-visible names in INFORMATION_SCHEMA / SHOW TABLES output for the system schema (__SYS/CATALOG).
const CatalogTemplateName = CatalogConstant + "_TEMPLATE"
CatalogTemplateName is the name of the catalog's own schema template. Matches Java's RecordLayerStoreCatalog.CATALOG_TEMPLATE constant ("CATALOG_TEMPLATE").
const CatalogTemplateVersion = 1
CatalogTemplateVersion is the version of the built-in catalog schema template. Java pins this to 1.
const SysDatabaseID = "/" + SysConstant
SysDatabaseID is the system database path. Java uses "/__SYS".
Variables ¶
This section is empty.
Functions ¶
func BuildCatalogMetaData ¶
func BuildCatalogMetaData() (*recordlayer.RecordMetaData, error)
BuildCatalogMetaData materialises the RecordMetaData for the three catalog record types (SCHEMAS, DATABASES, TEMPLATES).
Wire layout (byte-for-byte with Java RecordLayerStoreCatalog):
SCHEMAS — record type key 0, PK [typeKey, DATABASE_ID, SCHEMA_NAME] DATABASES — record type key 1, PK [typeKey, DATABASE_ID] TEMPLATES — record type key 2, PK [typeKey, TEMPLATE_NAME, TEMPLATE_VERSION]
Indexes:
SCHEMAS.TEMPLATES_COUNT_INDEX — COUNT grouped by (TEMPLATE_NAME, TEMPLATE_VERSION) SCHEMAS.TEMPLATES_VALUE_INDEX — VALUE on (TEMPLATE_NAME, TEMPLATE_VERSION, DATABASE_ID, SCHEMA_NAME) DATABASES.DATABASES_COUNT_INDEX — ungrouped COUNT
Returns an error only if the underlying RecordMetaDataBuilder rejects the proto descriptor; under normal conditions this cannot fail.
func DefaultCatalogSubspace ¶
DefaultCatalogSubspace returns the standard __SYS/CATALOG subspace in the exact byte layout Java writes. Java's RelationalKeyspaceProvider defines:
KeySpaceDirectory(SYS, KeyType.NULL) // __SYS domain
KeySpaceDirectory(SYS, KeyType.NULL) // __SYS database
KeySpaceDirectory(CATALOG, KeyType.LONG, 0L) // CATALOG schema
The directory *names* (__SYS, __SYS, CATALOG) are path labels; the on-wire tuple element for each level is the KeyType constant. So the catalog's actual subspace prefix is the tuple (NULL, NULL, int64(0)) — NOT three strings. Go previously used subspace.Sub("__SYS", "CATALOG") which encodes two string tuple elements and is incompatible with Java-written catalogs. See fdb-record-layer/.../RelationalKeyspaceProvider.java#getSystemDirectory.
The SQL driver's keyspace.RelationalKeyspace.CatalogSubspace uses the same prefix.
Types ¶
type CatalogDatabaseMetaData ¶
type CatalogDatabaseMetaData struct {
// contains filtered or unexported fields
}
CatalogDatabaseMetaData implements api.DatabaseMetaData by running queries against a StoreCatalog. Suitable for JDBC-style introspection tools and for backing sql.DB.Stats-like consumers.
Each query runs in a fresh api.Transaction (new InMemoryTransaction) and closes it before returning — the ResultSet does not outlive the transaction. Callers iterating the ResultSet see a point-in-time snapshot; concurrent catalog changes after the method returns do not surface.
The Go DatabaseMetaData interface is a lean subset of Java's RelationalDatabaseMetaData — see api/database_metadata.go for what's included and what's deferred.
func NewCatalogDatabaseMetaData ¶
func NewCatalogDatabaseMetaData(opts CatalogDatabaseMetaDataOptions) *CatalogDatabaseMetaData
NewCatalogDatabaseMetaData constructs a CatalogDatabaseMetaData. Panics if opts.StoreCatalog is nil — DatabaseMetaData without a catalog is meaningless.
func (*CatalogDatabaseMetaData) Columns ¶
func (m *CatalogDatabaseMetaData) Columns(_ context.Context, catalog, schemaPattern, tableNamePattern, columnNamePattern string) (api.ResultSet, error)
Columns returns per-column metadata matching the given catalog / schema / table / column patterns. 24-column JDBC shape — see api/database_metadata.go for the column list and ordering.
DATA_TYPE is derived from api.JDBCType on the column's DataType. TYPE_NAME is the DataType.String() rendering. NULLABLE / IS_NULLABLE mirror DataType.IsNullable — proto2 REQUIRED fields report "NO" / ColumnNoNulls, everything else "YES" / ColumnNullable.
Columns the relational layer doesn't track (COLUMN_SIZE, DECIMAL_DIGITS, CHAR_OCTET_LENGTH, ...) surface as nil; callers iterating a real JDBC ResultSet would see them as SQL NULL.
func (*CatalogDatabaseMetaData) DatabaseProductName ¶
func (m *CatalogDatabaseMetaData) DatabaseProductName() string
func (*CatalogDatabaseMetaData) DatabaseProductVersion ¶
func (m *CatalogDatabaseMetaData) DatabaseProductVersion() string
func (*CatalogDatabaseMetaData) DriverName ¶
func (m *CatalogDatabaseMetaData) DriverName() string
func (*CatalogDatabaseMetaData) DriverVersion ¶
func (m *CatalogDatabaseMetaData) DriverVersion() string
func (*CatalogDatabaseMetaData) IndexInfo ¶
func (m *CatalogDatabaseMetaData) IndexInfo(_ context.Context, catalog, schema, table string, unique, _ bool) (api.ResultSet, error)
IndexInfo returns per-index metadata for a single table. If unique=true, only unique indexes are returned. approximate is ignored — the in-memory catalog has no notion of stale statistics.
13-column JDBC shape. Our api.Index doesn't expose per-column position data today, so we surface a single row per index (with ORDINAL_POSITION=1, COLUMN_NAME empty). JDBC clients that walk the result by column position still see a consistent shape.
func (*CatalogDatabaseMetaData) IsReadOnly ¶
func (m *CatalogDatabaseMetaData) IsReadOnly() bool
func (*CatalogDatabaseMetaData) PrimaryKeys ¶
func (m *CatalogDatabaseMetaData) PrimaryKeys(_ context.Context, catalog, schema, table string) (api.ResultSet, error)
PrimaryKeys returns the primary-key columns of a single table. Each row is one PK column (key_seq 1..N). Today we surface the recordlayer-level primary key tuple as a single "compound key" row — the Java side splits into individual column rows when the PK is a composite expression, which we'll match once our key-expression introspection grows.
func (*CatalogDatabaseMetaData) Schemas ¶
Schemas returns every schema in every catalog. Columns match JDBC DatabaseMetaData.getSchemas(): (TABLE_SCHEM, TABLE_CATALOG). TABLE_CATALOG is the database URI path; Java surfaces it as the "catalog" value in JDBC terminology.
func (*CatalogDatabaseMetaData) SchemasFiltered ¶
func (m *CatalogDatabaseMetaData) SchemasFiltered(_ context.Context, catalog, schemaPattern string) (api.ResultSet, error)
SchemasFiltered narrows Schemas by catalog + schema LIKE patterns. Empty patterns match anything (SQL standard: no filter).
func (*CatalogDatabaseMetaData) Tables ¶
func (m *CatalogDatabaseMetaData) Tables(_ context.Context, catalog, schemaPattern, tableNamePattern string, types []string) (api.ResultSet, error)
Tables enumerates every table in every schema matching the patterns. types optionally restricts to a subset of table types ("TABLE", "VIEW", "SYSTEM TABLE"); nil or empty returns all types.
Since our catalog today has only regular tables (no views, no system tables), every returned row has TABLE_TYPE == "TABLE" and all type columns (TYPE_CAT / TYPE_SCHEM / TYPE_NAME) are empty.
func (*CatalogDatabaseMetaData) URL ¶
func (m *CatalogDatabaseMetaData) URL() string
func (*CatalogDatabaseMetaData) UserName ¶
func (m *CatalogDatabaseMetaData) UserName() string
type CatalogDatabaseMetaDataOptions ¶
type CatalogDatabaseMetaDataOptions struct {
// StoreCatalog: required. Backs every discovery query.
StoreCatalog api.StoreCatalog
// NewTransaction: factory for a fresh transaction per query. If
// nil, a new *InMemoryTransaction is used (valid only when the
// catalog is an InMemoryStoreCatalog).
NewTransaction func() api.Transaction
// URL, UserName, ReadOnly, ProductName, ProductVersion, DriverName,
// DriverVersion: returned by the corresponding accessors.
URL string
UserName string
ReadOnly bool
ProductName string
ProductVersion string
DriverName string
DriverVersion string
}
CatalogDatabaseMetaDataOptions configures identification fields. The storeCatalog is required; everything else is optional and defaults to sensible values.
type FDBTransaction ¶
type FDBTransaction struct {
// contains filtered or unexported fields
}
FDBTransaction bridges a *recordlayer.FDBRecordContext onto the api.Transaction interface. Mirrors Java's RecordContextTransaction: it owns no lifecycle of its own beyond the commit/abort/close state machine — the underlying FDBRecordContext handles the real FDB work.
The transaction is considered "closed" once Commit or Abort returns successfully, or Close is called. Subsequent operations return ErrCodeTransactionInactive.
func NewFDBTransaction ¶
func NewFDBTransaction(ctx *recordlayer.FDBRecordContext) *FDBTransaction
NewFDBTransaction wraps an FDBRecordContext. The caller retains ownership of ctx; Close() does NOT cancel the underlying context (matches Java's behaviour where RecordContextTransaction.close is a no-op when the runner manages the context). Callers must Commit or Abort before discarding the transaction.
func (*FDBTransaction) Abort ¶
func (t *FDBTransaction) Abort() error
Abort cancels the underlying FDB transaction and marks this transaction closed. Idempotent with Commit — the first of the two wins; subsequent calls return ErrCodeTransactionInactive.
func (*FDBTransaction) BoundSchemaTemplate ¶
func (t *FDBTransaction) BoundSchemaTemplate() api.SchemaTemplate
BoundSchemaTemplate returns the template bound to this transaction, or nil.
func (*FDBTransaction) Close ¶
func (t *FDBTransaction) Close() error
Close releases state held by this bridge. Does NOT touch the underlying FDBRecordContext — the caller that created it owns its lifecycle. Safe to call multiple times.
func (*FDBTransaction) Commit ¶
func (t *FDBTransaction) Commit() error
Commit finalises the underlying FDB transaction. After a successful commit the transaction is marked closed; further operations error. A failed commit leaves the transaction in the pre-commit state so callers may decide whether to Abort / Close.
func (*FDBTransaction) Context ¶
func (t *FDBTransaction) Context() *recordlayer.FDBRecordContext
Context returns the underlying record-layer context. Catalog impls use this to open record stores; equivalent to Java's Transaction.unwrap(FDBRecordContext.class).
func (*FDBTransaction) IsClosed ¶
func (t *FDBTransaction) IsClosed() bool
IsClosed reports whether Commit / Abort / Close has been called.
func (*FDBTransaction) SetBoundSchemaTemplate ¶
func (t *FDBTransaction) SetBoundSchemaTemplate(template api.SchemaTemplate)
SetBoundSchemaTemplate binds or replaces the template.
func (*FDBTransaction) UnsetBoundSchemaTemplate ¶
func (t *FDBTransaction) UnsetBoundSchemaTemplate()
UnsetBoundSchemaTemplate clears any bound template.
func (*FDBTransaction) Unwrap ¶
func (t *FDBTransaction) Unwrap() any
Unwrap returns the underlying *recordlayer.FDBRecordContext. Satisfies api.Transaction.Unwrap — callers that need the FDB handle should go through unwrapFDB rather than asserting *FDBTransaction directly so a future decorator Transaction that forwards Unwrap continues to work.
type InMemorySchemaTemplateCatalog ¶
type InMemorySchemaTemplateCatalog struct {
// contains filtered or unexported fields
}
InMemorySchemaTemplateCatalog stores schema templates keyed by (name, version). Companion to InMemoryStoreCatalog.
func NewInMemorySchemaTemplateCatalog ¶
func NewInMemorySchemaTemplateCatalog() *InMemorySchemaTemplateCatalog
NewInMemorySchemaTemplateCatalog returns an empty template catalog.
func (*InMemorySchemaTemplateCatalog) CreateTemplate ¶
func (c *InMemorySchemaTemplateCatalog) CreateTemplate(txn api.Transaction, newTemplate api.SchemaTemplate) error
CreateTemplate persists a new (name, version) through the FDB catalog's route (RecordLayerStoreSchemaTemplateCatalog.CreateTemplate): the exact-duplicate refusal, then refuseBelowLatest against the latest stored version, the version guard, and for a new version of a stored name the carry from the latest version's ToProto (carryTemplate, with the lane check over the indexes it defines). What is stored is the template the carried bytes load as; a fresh name is lane-checked (checkIndexLanes) and stored as given, and so is a template that is not a RecordLayerSchemaTemplate, which has no meta-data to carry or check.
func (*InMemorySchemaTemplateCatalog) DeleteTemplate ¶
func (c *InMemorySchemaTemplateCatalog) DeleteTemplate(txn api.Transaction, templateName string, throwIfDoesNotExist bool) error
DeleteTemplate removes every version of templateName.
func (*InMemorySchemaTemplateCatalog) DeleteTemplateVersion ¶
func (c *InMemorySchemaTemplateCatalog) DeleteTemplateVersion(txn api.Transaction, templateName string, version int, throwIfDoesNotExist bool) error
DeleteTemplateVersion removes one specific (name, version). A version a schema binds is not deleted (the version guard, template_bindings.go).
func (*InMemorySchemaTemplateCatalog) DoesSchemaTemplateExist ¶
func (c *InMemorySchemaTemplateCatalog) DoesSchemaTemplateExist(txn api.Transaction, templateName string) (bool, error)
DoesSchemaTemplateExist: any version of templateName.
func (*InMemorySchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion ¶
func (c *InMemorySchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion(txn api.Transaction, templateName string, version int) (bool, error)
DoesSchemaTemplateExistAtVersion: specific (name, version).
func (*InMemorySchemaTemplateCatalog) ListTemplates ¶
func (c *InMemorySchemaTemplateCatalog) ListTemplates(txn api.Transaction) (api.ResultSet, error)
ListTemplates returns every (name, version) pair, sorted by (name, version).
func (*InMemorySchemaTemplateCatalog) LoadSchemaTemplate ¶
func (c *InMemorySchemaTemplateCatalog) LoadSchemaTemplate(txn api.Transaction, templateName string) (api.SchemaTemplate, error)
LoadSchemaTemplate returns the highest-versioned template with the given name. ErrCodeUnknownSchemaTemplate when not found.
func (*InMemorySchemaTemplateCatalog) LoadSchemaTemplateAtVersion ¶
func (c *InMemorySchemaTemplateCatalog) LoadSchemaTemplateAtVersion(txn api.Transaction, templateName string, version int) (api.SchemaTemplate, error)
LoadSchemaTemplateAtVersion returns one specific (name, version).
func (*InMemorySchemaTemplateCatalog) LoadTemplateProto ¶
func (c *InMemorySchemaTemplateCatalog) LoadTemplateProto(txn api.Transaction, templateName string, version int) (*gen.MetaData, error)
LoadTemplateProto returns the stored template's MetaData. The in-memory catalog keeps template objects and no bytes, so this is the template's ToProto: it holds only templates Go built, through CreateTemplate, so there is no unknown field or extension another engine wrote for it to lose.
type InMemoryStoreCatalog ¶
type InMemoryStoreCatalog struct {
// contains filtered or unexported fields
}
InMemoryStoreCatalog keeps the entire catalog (databases + schemas) in a mutex-protected map. Intended for unit tests and development; the FDB-backed implementation is RecordLayerStoreCatalog.
A single InMemoryStoreCatalog instance is safe for concurrent use across transactions — the mutex serialises the full state — but does NOT implement MVCC. Readers see whatever the latest writer committed; aborts are no-ops.
func NewInMemoryStoreCatalog ¶
func NewInMemoryStoreCatalog() *InMemoryStoreCatalog
NewInMemoryStoreCatalog returns a fresh, empty catalog.
func (*InMemoryStoreCatalog) CreateDatabase ¶
func (c *InMemoryStoreCatalog) CreateDatabase(txn api.Transaction, dbURI string) error
CreateDatabase records a new database. Returns ErrCodeDatabaseAlreadyExists when dbURI is already present.
func (*InMemoryStoreCatalog) DeleteDatabase ¶
func (c *InMemoryStoreCatalog) DeleteDatabase(txn api.Transaction, dbURI string, throwIfDoesNotExist bool) (bool, error)
DeleteDatabase removes a database and all its schemas. Always returns true on success — the in-memory path never partially completes (no time limit).
func (*InMemoryStoreCatalog) DeleteSchema ¶
func (c *InMemoryStoreCatalog) DeleteSchema(txn api.Transaction, dbURI, schemaName string) error
DeleteSchema removes (dbURI, schemaName).
func (*InMemoryStoreCatalog) DoesDatabaseExist ¶
func (c *InMemoryStoreCatalog) DoesDatabaseExist(txn api.Transaction, dbURI string) (bool, error)
DoesDatabaseExist returns true iff dbURI is present.
func (*InMemoryStoreCatalog) DoesSchemaExist ¶
func (c *InMemoryStoreCatalog) DoesSchemaExist(txn api.Transaction, dbURI, schemaName string) (bool, error)
DoesSchemaExist returns true iff (dbURI, schemaName) resolves.
func (*InMemoryStoreCatalog) ListDatabases ¶
func (c *InMemoryStoreCatalog) ListDatabases(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
ListDatabases returns a sorted ResultSet of (database_name) rows. Continuations are ignored for the in-memory impl.
func (*InMemoryStoreCatalog) ListSchemas ¶
func (c *InMemoryStoreCatalog) ListSchemas(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
ListSchemas returns a ResultSet of (database_name, schema_name) rows across every database.
func (*InMemoryStoreCatalog) ListSchemasInDatabase ¶
func (c *InMemoryStoreCatalog) ListSchemasInDatabase(txn api.Transaction, databaseID string, _ api.Continuation) (api.ResultSet, error)
ListSchemasInDatabase narrows ListSchemas to a single database.
func (*InMemoryStoreCatalog) LoadSchema ¶
func (c *InMemoryStoreCatalog) LoadSchema(txn api.Transaction, databaseID, schemaName string) (api.Schema, error)
LoadSchema looks up a Schema by (databaseID, schemaName).
Java compliance: RecordLayerStoreCatalog.loadSchema always returns UNDEFINED_SCHEMA regardless of whether the database exists or only the schema is missing. The underlying primary key Tuple is (RECORD_TYPE_KEY, dbPath, schemaName) so "no record found" is the only observable state — we collapse both misses to ErrCodeUndefinedSchema to match.
func (*InMemoryStoreCatalog) RepairSchema ¶
func (c *InMemoryStoreCatalog) RepairSchema(txn api.Transaction, databaseID, schemaName string) error
RepairSchema rebinds schemaName to the latest version of its owning template, as Java's repairSchema: it loads the schema with its template (refused when the bound version is gone) and saves it onto the latest version with UPGRADE, through saveSchemaHeld and so the rebind validator. The mutex is held throughout, so the template reads and the write see one state.
func (*InMemoryStoreCatalog) SaveSchema ¶
func (c *InMemoryStoreCatalog) SaveSchema(txn api.Transaction, dataToWrite api.Schema, createDatabaseIfNecessary bool, existsBehavior api.SchemaExistsBehavior) error
SaveSchema persists schema, in Java's saveSchema order, as the FDB catalog's SaveSchema: validate the schema; the database exists (else UNDEFINED_DATABASE unless createDatabaseIfNecessary); the template exists at the schema's version (UNKNOWN_SCHEMA_TEMPLATE); the stored row loads with its template, which fails when that version is gone; existsBehavior decides a save over a stored row, and Go's rebind validator checks one that overwrites it; write.
Note the error codes: UNDEFINED_DATABASE here, not UNKNOWN_DATABASE — those are two distinct SQLSTATEs in Java.
func (*InMemoryStoreCatalog) SchemaTemplateCatalog ¶
func (c *InMemoryStoreCatalog) SchemaTemplateCatalog() api.SchemaTemplateCatalog
SchemaTemplateCatalog returns the nested template catalog.
type InMemoryTransaction ¶
type InMemoryTransaction struct {
// contains filtered or unexported fields
}
InMemoryTransaction is a minimal api.Transaction for tests. Concurrent calls to any method after Close / Commit / Abort return ErrCodeTransactionInactive. State is protected by a mutex; there is no MVCC, no write buffer — changes against the catalog are applied directly and a later Abort does NOT roll them back.
Good enough for unit tests; a real FDB transaction is required before running SQL over live data.
func NewInMemoryTransaction ¶
func NewInMemoryTransaction() *InMemoryTransaction
NewInMemoryTransaction returns a fresh, open transaction.
func (*InMemoryTransaction) Abort ¶
func (t *InMemoryTransaction) Abort() error
Abort marks the transaction closed WITHOUT rolling back prior writes — see package doc. Idempotent with Commit in the sense that the first of the two wins and subsequent calls error.
func (*InMemoryTransaction) BoundSchemaTemplate ¶
func (t *InMemoryTransaction) BoundSchemaTemplate() api.SchemaTemplate
BoundSchemaTemplate returns the bound template, or nil.
func (*InMemoryTransaction) Close ¶
func (t *InMemoryTransaction) Close() error
Close is safe to call multiple times; only the first call transitions the state.
func (*InMemoryTransaction) Commit ¶
func (t *InMemoryTransaction) Commit() error
Commit marks the transaction closed. The in-memory catalog applies writes eagerly, so Commit has no remaining work to do; it is the "closed" transition that matters to callers.
func (*InMemoryTransaction) IsClosed ¶
func (t *InMemoryTransaction) IsClosed() bool
IsClosed reports whether the transaction has been Committed / Aborted / Closed.
func (*InMemoryTransaction) SetBoundSchemaTemplate ¶
func (t *InMemoryTransaction) SetBoundSchemaTemplate(template api.SchemaTemplate)
SetBoundSchemaTemplate binds (or replaces) the template.
func (*InMemoryTransaction) UnsetBoundSchemaTemplate ¶
func (t *InMemoryTransaction) UnsetBoundSchemaTemplate()
UnsetBoundSchemaTemplate clears any bound template.
func (*InMemoryTransaction) Unwrap ¶
func (t *InMemoryTransaction) Unwrap() any
Unwrap returns the transaction itself because the in-memory catalog is the underlying storage backend. Satisfies api.Transaction.Unwrap.
type RecordLayerStoreCatalog ¶
type RecordLayerStoreCatalog struct {
// contains filtered or unexported fields
}
RecordLayerStoreCatalog is the FDB-backed api.StoreCatalog. Mirrors Java's com.apple.foundationdb.relational.recordlayer.catalog.RecordLayerStoreCatalog.
All methods open a fresh FDBRecordStore per call against the catalogSubspace, matching Java's pattern. Initialize marks the catalog store's state cacheable, as Java's does; the header flag is what a Java initialize reads, whether or not a Go state cache is configured.
Scope: schema + database CRUD, basic existence checks, ListSchemasInDatabase / ListDatabases. Schema template catalog lives in a sibling type returned from SchemaTemplateCatalog().
func NewRecordLayerStoreCatalog ¶
func NewRecordLayerStoreCatalog(catalogSubspace subspace.Subspace) (*RecordLayerStoreCatalog, error)
NewRecordLayerStoreCatalog constructs the catalog rooted at the given __SYS/CATALOG subspace. Callers typically use OpenRecordLayerStoreCatalog() which bakes in the standard layout.
func OpenRecordLayerStoreCatalog ¶
func OpenRecordLayerStoreCatalog() (*RecordLayerStoreCatalog, error)
OpenRecordLayerStoreCatalog uses the shared Java/Go catalog prefix. See DefaultCatalogSubspace for the byte-layout rationale.
func (*RecordLayerStoreCatalog) CreateDatabase ¶
func (c *RecordLayerStoreCatalog) CreateDatabase(txn api.Transaction, dbURI string) error
CreateDatabase creates a Database row for dbURI. No-op if already present (matches Java's RecordLayerStoreCatalog — saveRecord is used directly, so a duplicate is overwritten silently; we mirror that).
func (*RecordLayerStoreCatalog) DeleteDatabase ¶
func (c *RecordLayerStoreCatalog) DeleteDatabase(txn api.Transaction, dbURI string, throwIfDoesNotExist bool) (bool, error)
DeleteDatabase removes dbURI and every schema within it. Matches Java's RecordLayerStoreCatalog.deleteDatabase: scan-and-delete all Schemas rows with PK prefix [SCHEMA_TYPE_KEY, dbURI], then delete the Databases row. Returns (true, nil) on success, (false, nil) on timeout (Java returns false silently when TRANSACTION_INACTIVE/TIMEOUT; we surface other FDB errors). throwIfDoesNotExist=true raises ErrCodeUnknownDatabase when the db row is absent.
func (*RecordLayerStoreCatalog) DeleteSchema ¶
func (c *RecordLayerStoreCatalog) DeleteSchema(txn api.Transaction, dbURI, schemaName string) error
DeleteSchema removes (dbURI, schemaName). Returns ErrCodeUndefinedSchema when the row is absent (matches Java).
func (*RecordLayerStoreCatalog) DoesDatabaseExist ¶
func (c *RecordLayerStoreCatalog) DoesDatabaseExist(txn api.Transaction, dbURI string) (bool, error)
DoesDatabaseExist reports whether a Database row exists at dbURI.
func (*RecordLayerStoreCatalog) DoesSchemaExist ¶
func (c *RecordLayerStoreCatalog) DoesSchemaExist(txn api.Transaction, dbURI, schemaName string) (bool, error)
DoesSchemaExist reports whether a Schema row exists at (dbURI, schemaName).
func (*RecordLayerStoreCatalog) Initialize ¶
func (c *RecordLayerStoreCatalog) Initialize(txn api.Transaction) error
Initialize bootstraps the catalog schema's self-referential entries. It must be called once before the catalog is used, typically at service startup. Matches Java's RecordLayerStoreCatalog.initialize(txn):
- Marks the catalog store's state cacheable.
- Ensures the catalog schema template ("CATALOG_TEMPLATE") exists.
- Persists the catalog schema (/__SYS/CATALOG), creating the /__SYS database row if necessary, with ERROR_IF_DIFFERENT.
Java's initialize, in its order: open the catalog store and mark its state cacheable, create the catalog's template when no version of it is stored, then saveSchema(txn, catalogSchema, true, ERROR_IF_DIFFERENT), which writes nothing over an identical stored row, so concurrent initializations of an initialized catalog do not conflict, and refuses a row bound to a different template. Errors propagate as Java's do, with their own codes.
Idempotent: safe to call on every startup.
func (*RecordLayerStoreCatalog) ListDatabases ¶
func (c *RecordLayerStoreCatalog) ListDatabases(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
ListDatabases returns an api.ResultSet over every database. Materialises in-memory; continuation support is deferred. Uses a prefix scan keyed on [DATABASE_INFO_TYPE_KEY] matching Java's listDatabases TupleRange shape.
func (*RecordLayerStoreCatalog) ListSchemas ¶
func (c *RecordLayerStoreCatalog) ListSchemas(txn api.Transaction, _ api.Continuation) (api.ResultSet, error)
ListSchemas returns every schema in every database. Like ListDatabases, materialises in-memory; continuation is a follow-up.
func (*RecordLayerStoreCatalog) ListSchemasInDatabase ¶
func (c *RecordLayerStoreCatalog) ListSchemasInDatabase(txn api.Transaction, databaseID string, _ api.Continuation) (api.ResultSet, error)
ListSchemasInDatabase narrows ListSchemas to a single database. An empty databaseID returns every schema (same as ListSchemas).
func (*RecordLayerStoreCatalog) LoadSchema ¶
func (c *RecordLayerStoreCatalog) LoadSchema(txn api.Transaction, databaseID, schemaName string) (api.Schema, error)
LoadSchema loads (databaseID, schemaName) → api.Schema by deserialising the Schemas record, resolving its template via the SchemaTemplateCatalog, and materialising a Schema via template.GenerateSchema. Matches Java semantics: missing rows surface as ErrCodeUndefinedSchema regardless of whether the database or the schema was the missing bit (primary-key tuple lookup can't tell).
func (*RecordLayerStoreCatalog) RepairSchema ¶
func (c *RecordLayerStoreCatalog) RepairSchema(txn api.Transaction, dbURI, schemaName string) error
RepairSchema rebinds schemaName in dbURI to the latest version of its owning template. Matches Java's repairSchema: load the schema with its template (refused when the bound version is gone), load the latest version, and save onto it with UPGRADE, a no-op when the schema is already on the latest version.
func (*RecordLayerStoreCatalog) RestoreTemplateVersion ¶
func (c *RecordLayerStoreCatalog) RestoreTemplateVersion(ctx context.Context, db *recordlayer.FDBDatabase, ks *keyspace.RelationalKeyspace, name string, version int, md []byte, ) error
RestoreTemplateVersion restores a dropped template version from its stored MetaData bytes (md, the backup of the version's catalog META_DATA), for the schemas still bound to it, resolving their stores through ks, the keyspace the deployment opens its schemas with. It is fleet.RestoreTemplateVersion; every check above runs on every call. A refusal is 42F59 INVALID_SCHEMA_TEMPLATE, or 42F62 DUPLICATE_SCHEMA_TEMPLATE when the version is stored.
func (*RecordLayerStoreCatalog) SaveSchema ¶
func (c *RecordLayerStoreCatalog) SaveSchema(txn api.Transaction, s api.Schema, createDatabaseIfNecessary bool, existsBehavior api.SchemaExistsBehavior) error
SaveSchema persists a Schema, in Java's saveSchema order: validate the schema; the database exists (created when createDatabaseIfNecessary, else UNDEFINED_DATABASE); the template exists at the schema's version (UNKNOWN_SCHEMA_TEMPLATE); load the stored row with its template, which fails when that template version is gone; existsBehavior decides a save over a stored row; write. A save that existsBehavior makes a no-op writes nothing, so it adds no write conflict range.
func (*RecordLayerStoreCatalog) SchemaTemplateCatalog ¶
func (c *RecordLayerStoreCatalog) SchemaTemplateCatalog() api.SchemaTemplateCatalog
SchemaTemplateCatalog returns the template catalog sibling.
type RecordLayerStoreSchemaTemplateCatalog ¶
type RecordLayerStoreSchemaTemplateCatalog struct {
// contains filtered or unexported fields
}
RecordLayerStoreSchemaTemplateCatalog is the FDB-backed api.SchemaTemplateCatalog. Mirrors Java's RecordLayerStoreSchemaTemplateCatalog — versioned templates keyed by (templateName, templateVersion), with META_DATA holding the serialised RecordMetaData proto.
func (*RecordLayerStoreSchemaTemplateCatalog) CreateTemplate ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) CreateTemplate(txn api.Transaction, newTemplate api.SchemaTemplate) error
CreateTemplate persists a new (name, version), the one build-path writer of a template (DIVERGENCES.md "CreateTemplate refuses more than an exact duplicate, and carries a new version"). In order:
- an existing (name, version) is refused with Java's text, "Schema template already exists" (ErrCodeDuplicateSchemaTemplate), Java's createTemplate's only refusal;
- a version at or below the latest stored one is refused, and the relational evolution validator runs against that latest version (refuseBelowLatest; both a declared extension, section 9 (w));
- the version guard (template_bindings.go): a schema bound to a dropped version above the latest refuses the save;
- a new version of a stored template is carried from the latest stored version's bytes (carryTemplate: record-type keys, union numbers and indexes kept, the lane check over the indexes it defines, the evolution validator with index rebuilds allowed), and the carried bytes are what is written; a fresh name is lane-checked (checkIndexLanes) and written as built.
func (*RecordLayerStoreSchemaTemplateCatalog) DeleteTemplate ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) DeleteTemplate(txn api.Transaction, templateName string, throwIfDoesNotExist bool) error
DeleteTemplate removes ALL versions of templateName. When throwIfDoesNotExist is true, a missing template raises ErrCodeUnknownSchemaTemplate.
func (*RecordLayerStoreSchemaTemplateCatalog) DeleteTemplateVersion ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) DeleteTemplateVersion(txn api.Transaction, templateName string, version int, throwIfDoesNotExist bool) error
DeleteTemplateVersion removes one exact (name, version): Java's deleteTemplate(txn, name, version, throwIfDoesNotExist) (RecordLayerStoreSchemaTemplateCatalog.java:317-325), with its text.
A version a schema binds is not deleted (the version guard, template_bindings.go), where Java deletes the row regardless: deleting it would leave the schema bound to a version the catalog no longer has, which neither engine then loads, and which a later save could re-issue with other metadata. The refusal is a declared divergence (DIVERGENCES.md "DeleteTemplateVersion refuses a version schemas still bind; DROP SCHEMA TEMPLATE does not").
func (*RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExist ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExist(txn api.Transaction, templateName string) (bool, error)
DoesSchemaTemplateExist reports whether any version of templateName exists.
func (*RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) DoesSchemaTemplateExistAtVersion(txn api.Transaction, templateName string, version int) (bool, error)
DoesSchemaTemplateExistAtVersion — exact (name, version) lookup.
func (*RecordLayerStoreSchemaTemplateCatalog) ListTemplates ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) ListTemplates(txn api.Transaction) (api.ResultSet, error)
ListTemplates enumerates every (name, version) row.
func (*RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplate ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplate(txn api.Transaction, templateName string) (api.SchemaTemplate, error)
LoadSchemaTemplate loads the latest version of templateName. Matches Java: reverse scan, return first result. Errors with ErrCodeUnknownSchemaTemplate when no version exists.
func (*RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplateAtVersion ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) LoadSchemaTemplateAtVersion(txn api.Transaction, templateName string, version int) (api.SchemaTemplate, error)
LoadSchemaTemplateAtVersion — exact version lookup.
func (*RecordLayerStoreSchemaTemplateCatalog) LoadTemplateProto ¶
func (c *RecordLayerStoreSchemaTemplateCatalog) LoadTemplateProto(txn api.Transaction, templateName string, version int) (*gen.MetaData, error)
LoadTemplateProto returns the row's META_DATA unmarshalled, as stored.
type RelationalSchemaEvolutionValidator ¶
type RelationalSchemaEvolutionValidator struct{}
RelationalSchemaEvolutionValidator validates that a new schema template version is backward-compatible with the current version stored in the catalog.
Rules (conservative by default — matches Java's relational evolution semantics):
- Tables may be added; tables may NOT be removed.
- For each existing table: columns may be added; columns may NOT be removed.
- Column data types must not change (type widening is not yet implemented).
- Primary key column order must not change (PKs are the first N columns in the StructDataType; we compare column names in declared order).
func NewRelationalSchemaEvolutionValidator ¶
func NewRelationalSchemaEvolutionValidator() *RelationalSchemaEvolutionValidator
NewRelationalSchemaEvolutionValidator returns a validator with default (strict) settings.
func (*RelationalSchemaEvolutionValidator) Validate ¶
func (v *RelationalSchemaEvolutionValidator) Validate(oldTemplate, newTemplate api.SchemaTemplate) error
Validate checks that newTemplate is backward-compatible with oldTemplate. Returns a non-nil error describing the first violation found.
type TemplateBinding ¶
type TemplateBinding struct {
DatabaseID, SchemaName string
}
TemplateBinding is a schema bound to a template version.