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 (RecordLayerStoreCatalog) is deferred to a later shift.
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)
- 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) 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)
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.
NOTE: this is the Java-wire-compat subspace, which the Go sqldriver does NOT yet use — pkg/relational/sqldriver/driver.go opens the catalog via keyspace.RelationalKeyspace.CatalogSubspace() (three strings). Migration to this function from the driver is tracked in TODO.md. Callers reading a Go-written catalog today (incl. frl's `meta catalog`) should use the keyspace helper; readers of a Java-written catalog (or a future Go driver) should use DefaultCatalogSubspace.
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: persist a new (name, version). Error on duplicate.
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).
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).
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 lives in a separate type (later shift).
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. For the in-memory impl that means re-running templates.LoadSchemaTemplate and re-generating the schema — no storage rewrite is required.
Looking up the template is a separate-mutex call, so we copy the template name out under our lock, release, call templates.LoadSchemaTemplate, and then re-acquire our lock AND re-check the database/schema still exist before writing. A concurrent DeleteDatabase/DeleteSchema between the two lock sections would otherwise panic on a nil-map write.
TOCTOU note: between the two lock sections a concurrent SaveSchema could replace the schema with one pointing at a different template. We'd then rebind to the OLD template name, overwriting the newer entry. This matches Java's FDB-backed impl, which uses row-level locking and has the same window. Not worth a fix for the in-memory bridge; the FDB-backed catalog will inherit Java's semantics.
func (*InMemoryStoreCatalog) SaveSchema ¶
func (c *InMemoryStoreCatalog) SaveSchema(txn api.Transaction, dataToWrite api.Schema, createDatabaseIfNecessary bool) error
SaveSchema persists or updates schema. Creates the owning database first when createDatabaseIfNecessary is true and it doesn't exist.
Java compliance (RecordLayerStoreCatalog.saveSchema):
- If database missing and !createDatabaseIfNecessary → UNDEFINED_DATABASE.
- The schema template referenced by the Schema (name, version) MUST exist in the SchemaTemplateCatalog, else UNKNOWN_SCHEMA_TEMPLATE.
- Otherwise upsert the (db, schema) entry.
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. Store state cacheability is not yet wired in — will be a follow-up once FDBDatabase.SetStoreStateCache flows through the SQL driver.
Scope (this shift): 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 opens the catalog at the Java-compatible (NULL, NULL, int64(0)) subspace. See DefaultCatalogSubspace for the full byte-layout rationale — and for the caveat that the Go sqldriver currently writes to a different (three-string) subspace.
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):
- Ensures the catalog schema template ("CATALOG_TEMPLATE") exists.
- Ensures the /__SYS database row exists.
- Persists the catalog schema (/__SYS/CATALOG) into the store.
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.
func (*RecordLayerStoreCatalog) SaveSchema ¶
func (c *RecordLayerStoreCatalog) SaveSchema(txn api.Transaction, s api.Schema, createDatabaseIfNecessary bool) error
SaveSchema persists or updates a Schema. Validates the schema name and verifies the owning database + template exist. If the database is missing and createDatabaseIfNecessary is false, returns ErrCodeUndefinedDatabase (matches Java).
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). Returns ErrCodeDuplicateSchemaTemplate when (name, version) already exists.
Matches Java's RecordLayerStoreSchemaTemplateCatalog.createTemplate() exactly: no evolution validation here. Java only validates metadata evolution inside FDBMetaDataStore.saveAndSetCurrent() (record-layer level, not relational); the relational createTemplate / saveSchema paths do not invoke MetaDataEvolutionValidator. Adding validation in Go would diverge — a Go writer would reject templates Java accepts. See TODO.md entry on the template-evolution validation gap (open both in Java and Go; worth an upstream discussion before unilateral Go-side enforcement).
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).
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.