Documentation
¶
Overview ¶
Package keyspace defines the relational-layer FDB key structure, Java's RelationalKeyspaceProvider byte for byte:
catalog store: (NULL, NULL, 0) __SYS / __SYS / CATALOG user schema: (domain, database, schema) three longs
The domain is a directory of the FDB directory layer at the root (Java's ScopedDirectoryLayer.global); the database and the schema are names interned in the domain's interning layer at (domain, "IL") (ScopedInterningLayer). A store written by Go is the store Java opens, and the reverse.
Index ¶
- Constants
- func ParseDBPath(dbPath string) ([]string, error)
- func RegisterDomainIfNotExists(name string)
- func RegisteredDomains() []string
- type DatabasePath
- type RelationalKeyspace
- func (k *RelationalKeyspace) CatalogSubspace() subspace.Subspace
- func (k *RelationalKeyspace) LookupSchemaSubspace(ctx context.Context, db *recordlayer.FDBDatabase, dbPath, schemaName string) (subspace.Subspace, error)
- func (k *RelationalKeyspace) SchemaSubspace(rctx *recordlayer.FDBRecordContext, dbPath, schemaName string) (subspace.Subspace, error)
- func (k *RelationalKeyspace) SchemaSubspaceIn(ctx context.Context, db Runner, dbPath, schemaName string) (subspace.Subspace, error)
- func (k *RelationalKeyspace) StatisticsSubspace() subspace.Subspace
- type Runner
Constants ¶
const ( DBNameDir = "dbName" SchemaDir = "schema" DefaultSchemaDir = "defaultSchema" InterningLayer = "__internedStrings" // InterningLayerValue is the interning directory's constant value. InterningLayerValue = "IL" )
Names of the keyspace directories (RelationalKeyspaceProvider).
const ( SysName = "__SYS" CatalogName = "CATALOG" // StatsName roots collected planner statistics (RFC-236). It is a SIBLING // of every schema subspace, never a child, because a schema subspace IS a // record store subspace and that namespace belongs to Java — // FDBRecordStoreKeyspace defines 0-10 and is (UNSTABLE). Statistics are // a Go-side optimization and must not add a byte inside it. StatsName = "__STATS" )
Variables ¶
This section is empty.
Functions ¶
func ParseDBPath ¶
ParseDBPath breaks a URI-style database path like "/domain/db" into its path components, stripping the leading slash. Returns an error if the path is invalid.
func RegisterDomainIfNotExists ¶
func RegisterDomainIfNotExists(name string)
RegisterDomainIfNotExists adds a domain to the process's keyspace, Java's RelationalKeyspaceProvider.instance().registerDomainIfNotExists. Afterwards /name/DB is a valid database path for every connection of the process.
func RegisteredDomains ¶
func RegisteredDomains() []string
RegisteredDomains returns the registered domains in registration order.
Types ¶
type DatabasePath ¶
DatabasePath is a resolved database path: the system database, or a domain's database.
func ToDatabasePath ¶
func ToDatabasePath(uri string) (DatabasePath, error)
ToDatabasePath resolves a database URI path against the keyspace, Java's RelationalKeyspaceProvider.toDatabasePath over KeySpaceUtils.toKeySpacePath: the path must be /__SYS or /DOMAIN/DATABASE under a registered domain, and anything else is INVALID_PATH "<path> is an invalid database path".
type RelationalKeyspace ¶
type RelationalKeyspace struct {
// contains filtered or unexported fields
}
RelationalKeyspace provides FDB subspace resolution for the relational layer. Construct one with a root subspace (e.g. the empty subspace or a tenant-specific prefix), then call CatalogSubspace / SchemaSubspace to get per-object subspaces.
func New ¶
func New(root subspace.Subspace) *RelationalKeyspace
New returns a RelationalKeyspace rooted at root.
func (*RelationalKeyspace) CatalogSubspace ¶
func (k *RelationalKeyspace) CatalogSubspace() subspace.Subspace
CatalogSubspace returns the subspace for the system catalog record store: __SYS (NULL) / __SYS (NULL) / CATALOG (LONG 0).
func (*RelationalKeyspace) LookupSchemaSubspace ¶
func (k *RelationalKeyspace) LookupSchemaSubspace(ctx context.Context, db *recordlayer.FDBDatabase, dbPath, schemaName string) (subspace.Subspace, error)
LookupSchemaSubspace resolves a schema's store subspace without creating any mapping (readInTransaction): a domain, database or schema name that was never interned names no store, and is UNDEFINED_SCHEMA.
func (*RelationalKeyspace) SchemaSubspace ¶
func (k *RelationalKeyspace) SchemaSubspace(rctx *recordlayer.FDBRecordContext, dbPath, schemaName string) (subspace.Subspace, error)
SchemaSubspace resolves a schema's record store subspace, Java's toDatabasePath(dbUri).schemaPath(schemaName) resolved: the domain's directory-layer long, then the database and schema names interned in the domain's scope (created on first use, each in a transaction of its own, as Java's resolveWithMetadata does).
func (*RelationalKeyspace) SchemaSubspaceIn ¶
func (k *RelationalKeyspace) SchemaSubspaceIn(ctx context.Context, db Runner, dbPath, schemaName string) (subspace.Subspace, error)
SchemaSubspaceIn is SchemaSubspace for a caller outside a transaction: a resolved schema comes from the keyspace's cache, otherwise it is resolved in a transaction of the database's.
func (*RelationalKeyspace) StatisticsSubspace ¶
func (k *RelationalKeyspace) StatisticsSubspace() subspace.Subspace
StatisticsSubspace returns the root under which collected planner statistics live (RFC-236). Statistics for a given store are keyed BELOW this by that store's own subspace prefix, which is what makes the scheme layout-agnostic: a store is its prefix, whether it came from a relational schema, a hand-built store, or a Java-authored layout.
It deliberately takes no (dbPath, schema): the per-store keying happens one level down, so one root serves every store in this keyspace and the collector needs no relational concepts at all.
TENANTS: FDB tenants are separate keyspaces, so a store's prefix is only meaningful within its tenant — two tenants may hold byte-identical prefixes for different stores. A tenant-scoped deployment must therefore build its RelationalKeyspace on a root inside that tenant, which it already does, since `root` is whatever the caller opened. Nothing here can mix tenants that the caller has not already mixed.
type Runner ¶
type Runner interface {
Run(ctx context.Context, fn func(*recordlayer.FDBRecordContext) (any, error)) (any, error)
}
Runner runs fn in an auto-commit transaction: an *recordlayer.FDBDatabase, or a connection's runner that configures each transaction from its options.