| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package storage
- import (
- "fmt"
- "log"
- "sync"
- )
- // DatabaseInstance represents a single database with its own schema and table managers.
- type DatabaseInstance struct {
- Name string
- Schema *SchemaManager
- Table *TableManager
- }
- // DatabaseManager manages multiple database instances.
- type DatabaseManager struct {
- pool *KVPool
- defaultDatabase string
- databases map[string]*DatabaseInstance
- autoCreate bool
- mu sync.RWMutex
- }
- // DatabaseManagerConfig holds configuration for the database manager.
- type DatabaseManagerConfig struct {
- DefaultDatabase string
- AutoCreate bool // Auto-create databases on first access
- }
- // NewDatabaseManager creates a new database manager.
- func NewDatabaseManager(pool *KVPool, config *DatabaseManagerConfig) *DatabaseManager {
- if config == nil {
- config = &DatabaseManagerConfig{
- DefaultDatabase: "pizzasql",
- AutoCreate: true,
- }
- }
- dm := &DatabaseManager{
- pool: pool,
- defaultDatabase: config.DefaultDatabase,
- databases: make(map[string]*DatabaseInstance),
- autoCreate: config.AutoCreate,
- }
- // Pre-create the default database instance
- dm.getOrCreateDatabase(config.DefaultDatabase)
- return dm
- }
- // GetDatabase returns the database instance for the given name.
- // If name is empty, returns the default database.
- // If autoCreate is enabled and the database doesn't exist, it will be created.
- func (dm *DatabaseManager) GetDatabase(name string) (*DatabaseInstance, error) {
- originalName := name
- if name == "" {
- name = dm.defaultDatabase
- log.Printf("[DEBUG] GetDatabase: empty name, using default: %q", name)
- }
- dm.mu.RLock()
- db, exists := dm.databases[name]
- dm.mu.RUnlock()
- if exists {
- log.Printf("[DEBUG] GetDatabase: found existing database %q (requested: %q), schema.database=%q",
- name, originalName, db.Schema.GetDatabaseName())
- return db, nil
- }
- if !dm.autoCreate {
- return nil, fmt.Errorf("database not found: %s", name)
- }
- log.Printf("[DEBUG] GetDatabase: creating new database %q (requested: %q)", name, originalName)
- return dm.getOrCreateDatabase(name), nil
- }
- // getOrCreateDatabase creates a new database instance if it doesn't exist.
- func (dm *DatabaseManager) getOrCreateDatabase(name string) *DatabaseInstance {
- dm.mu.Lock()
- defer dm.mu.Unlock()
- // Double-check after acquiring write lock
- if db, exists := dm.databases[name]; exists {
- return db
- }
- schema := NewSchemaManager(dm.pool, name)
- table := NewTableManager(dm.pool, schema, name)
- db := &DatabaseInstance{
- Name: name,
- Schema: schema,
- Table: table,
- }
- dm.databases[name] = db
- return db
- }
- // DefaultDatabase returns the default database name.
- func (dm *DatabaseManager) DefaultDatabase() string {
- return dm.defaultDatabase
- }
- // ListDatabases returns a list of all active database names.
- func (dm *DatabaseManager) ListDatabases() []string {
- dm.mu.RLock()
- defer dm.mu.RUnlock()
- names := make([]string, 0, len(dm.databases))
- for name := range dm.databases {
- names = append(names, name)
- }
- return names
- }
- // DatabaseExists checks if a database instance exists (is loaded).
- func (dm *DatabaseManager) DatabaseExists(name string) bool {
- dm.mu.RLock()
- defer dm.mu.RUnlock()
- _, exists := dm.databases[name]
- return exists
- }
- // GetPool returns the underlying KV pool.
- func (dm *DatabaseManager) GetPool() *KVPool {
- return dm.pool
- }
- // SetAutoCreate enables or disables auto-creation of databases.
- func (dm *DatabaseManager) SetAutoCreate(autoCreate bool) {
- dm.mu.Lock()
- defer dm.mu.Unlock()
- dm.autoCreate = autoCreate
- }
|