Documentation
¶
Overview ¶
Package driver provides the foundational interfaces for implementing multitenancy support within database systems. It outlines the necessary components for managing tenant lifecycles, including onboarding, offboarding, and handling shared resources. These interfaces serve as a contract for database management systems (DBMS) to ensure consistent multitenant operations, abstracting the complexities of tenant-specific data handling.
Index ¶
Constants ¶
const PublicSchemaEnvVar = "GMT_PUBLIC_SCHEMA_NAME"
PublicSchemaEnvVar is the environment variable that contains the name of the public schema.
Variables ¶
var ( ErrInvalidTenantTableName = errors.New("invalid table name for model labeled as tenant table") )
Errors returned during model registration validation.
var ErrInvalidMigration = errors.New(
"invalid migration: use MigrateSharedModels or MigrateTenantModels instead of calling AutoMigrate directly",
)
ErrInvalidMigration is returned when an invalid migration is detected.
Functions ¶
func ModelsToInterfaces ¶
func ModelsToInterfaces(models []TenantTabler) []any
ModelsToInterfaces converts a slice of TenantTabler models to a slice of any.
func PublicSchemaName ¶
func PublicSchemaName() string
PublicSchemaName returns the name of the public schema as defined by the PublicSchemaEnvVar environment variable, defaulting to "public" if the variable is not set. This schema name is used to identify shared models.
Types ¶
type DBFactory ¶
type DBFactory interface {
// RegisterModels registers GORM model structs for multitenancy support within a specific database.
// It prepares models for tenant-specific operations and is idempotent. Returns an error if registration fails.
RegisterModels(ctx context.Context, db *gorm.DB, models ...TenantTabler) error
// maintaining integrity and compatibility of shared data across tenants. Returns an error if migration fails.
MigrateSharedModels(ctx context.Context, db *gorm.DB) error
// MigrateTenantModels prepares and updates data structures for a specific tenant within a specific database,
// handling onboarding and ongoing schema evolution. Returns an error if setup or migration fails.
MigrateTenantModels(ctx context.Context, db *gorm.DB, tenantID string) error
// OffboardTenant cleans up the database for a removed tenant, supporting clean
// offboarding. Returns an error if the process fails.
OffboardTenant(ctx context.Context, db *gorm.DB, tenantID string) error
// UseTenant configures the database for operations specific to a tenant, abstracting
// database-specific tenant context configuration. Returns a reset function to revert
// the database context and an error if the operation fails.
UseTenant(ctx context.Context, db *gorm.DB, tenantID string) (reset func() error, err error)
// CurrentTenant returns the identifier for the current tenant context within a specific database or an empty string
// if no context is set.
CurrentTenant(ctx context.Context, db *gorm.DB) string
}
DBFactory defines operations for managing the lifecycle of tenants within a multitenant database architecture. It abstracts tenant-specific operations such as onboarding, offboarding, and managing shared resources.
type ModelRegistry ¶
type ModelRegistry struct {
TenantModels []TenantTabler // TenantModels contains the models that are specific to a tenant.
}
ModelRegistry holds the models registered for multitenancy support, categorizing them into shared and tenant-specific models. Not intended for direct use in application code.
func NewModelRegistry ¶
func NewModelRegistry(models ...TenantTabler) (*ModelRegistry, error)
NewModelRegistry creates and initializes a new ModelRegistry with the provided models, categorizing them into shared and tenant-specific based on their characteristics. It returns an error if any model fails validation.
type TenantTabler ¶
type TenantTabler interface {
schema.Tabler
// it does not belong to a single tenant.
IsSharedModel() bool
}
TenantTabler defines an interface for models within a multi-tenant architecture, extending schema.Tabler. Models must define their table name and indicate if they are shared across tenants. Crucial for differentiating between shared and tenant-specific data.
Example of a shared model:
func (User) TableName() string { return "public.users" }
func (User) IsSharedModel() bool { return true }
Example of a tenant-specific model:
func (Product) TableName() string { return "products" }
func (Product) IsSharedModel() bool { return false }