catalog

package
v0.0.0-...-86ddd85 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

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

View Source
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.

View Source
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.

View Source
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).

View Source
const CatalogTemplateName = CatalogConstant + "_TEMPLATE"

CatalogTemplateName is the name of the catalog's own schema template. Matches Java's RecordLayerStoreCatalog.CATALOG_TEMPLATE constant ("CATALOG_TEMPLATE").

View Source
const CatalogTemplateVersion = 1

CatalogTemplateVersion is the version of the built-in catalog schema template. Java pins this to 1.

View Source
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

func DefaultCatalogSubspace() subspace.Subspace

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 (*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

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

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

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):

  1. If database missing and !createDatabaseIfNecessary → UNDEFINED_DATABASE.
  2. The schema template referenced by the Schema (name, version) MUST exist in the SchemaTemplateCatalog, else UNKNOWN_SCHEMA_TEMPLATE.
  3. 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):

  1. Ensures the catalog schema template ("CATALOG_TEMPLATE") exists.
  2. Ensures the /__SYS database row exists.
  3. Persists the catalog schema (/__SYS/CATALOG) into the store.

Idempotent: safe to call on every startup.

func (*RecordLayerStoreCatalog) ListDatabases

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

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

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.

Jump to

Keyboard shortcuts

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