db_manager.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package storage
  2. import (
  3. "fmt"
  4. "log"
  5. "sync"
  6. )
  7. // DatabaseInstance represents a single database with its own schema and table managers.
  8. type DatabaseInstance struct {
  9. Name string
  10. Schema *SchemaManager
  11. Table *TableManager
  12. }
  13. // DatabaseManager manages multiple database instances.
  14. type DatabaseManager struct {
  15. pool *KVPool
  16. defaultDatabase string
  17. databases map[string]*DatabaseInstance
  18. autoCreate bool
  19. mu sync.RWMutex
  20. }
  21. // DatabaseManagerConfig holds configuration for the database manager.
  22. type DatabaseManagerConfig struct {
  23. DefaultDatabase string
  24. AutoCreate bool // Auto-create databases on first access
  25. }
  26. // NewDatabaseManager creates a new database manager.
  27. func NewDatabaseManager(pool *KVPool, config *DatabaseManagerConfig) *DatabaseManager {
  28. if config == nil {
  29. config = &DatabaseManagerConfig{
  30. DefaultDatabase: "pizzasql",
  31. AutoCreate: true,
  32. }
  33. }
  34. dm := &DatabaseManager{
  35. pool: pool,
  36. defaultDatabase: config.DefaultDatabase,
  37. databases: make(map[string]*DatabaseInstance),
  38. autoCreate: config.AutoCreate,
  39. }
  40. // Pre-create the default database instance
  41. dm.getOrCreateDatabase(config.DefaultDatabase)
  42. return dm
  43. }
  44. // GetDatabase returns the database instance for the given name.
  45. // If name is empty, returns the default database.
  46. // If autoCreate is enabled and the database doesn't exist, it will be created.
  47. func (dm *DatabaseManager) GetDatabase(name string) (*DatabaseInstance, error) {
  48. originalName := name
  49. if name == "" {
  50. name = dm.defaultDatabase
  51. log.Printf("[DEBUG] GetDatabase: empty name, using default: %q", name)
  52. }
  53. dm.mu.RLock()
  54. db, exists := dm.databases[name]
  55. dm.mu.RUnlock()
  56. if exists {
  57. log.Printf("[DEBUG] GetDatabase: found existing database %q (requested: %q), schema.database=%q",
  58. name, originalName, db.Schema.GetDatabaseName())
  59. return db, nil
  60. }
  61. if !dm.autoCreate {
  62. return nil, fmt.Errorf("database not found: %s", name)
  63. }
  64. log.Printf("[DEBUG] GetDatabase: creating new database %q (requested: %q)", name, originalName)
  65. return dm.getOrCreateDatabase(name), nil
  66. }
  67. // getOrCreateDatabase creates a new database instance if it doesn't exist.
  68. func (dm *DatabaseManager) getOrCreateDatabase(name string) *DatabaseInstance {
  69. dm.mu.Lock()
  70. defer dm.mu.Unlock()
  71. // Double-check after acquiring write lock
  72. if db, exists := dm.databases[name]; exists {
  73. return db
  74. }
  75. schema := NewSchemaManager(dm.pool, name)
  76. table := NewTableManager(dm.pool, schema, name)
  77. db := &DatabaseInstance{
  78. Name: name,
  79. Schema: schema,
  80. Table: table,
  81. }
  82. dm.databases[name] = db
  83. return db
  84. }
  85. // DefaultDatabase returns the default database name.
  86. func (dm *DatabaseManager) DefaultDatabase() string {
  87. return dm.defaultDatabase
  88. }
  89. // ListDatabases returns a list of all active database names.
  90. func (dm *DatabaseManager) ListDatabases() []string {
  91. dm.mu.RLock()
  92. defer dm.mu.RUnlock()
  93. names := make([]string, 0, len(dm.databases))
  94. for name := range dm.databases {
  95. names = append(names, name)
  96. }
  97. return names
  98. }
  99. // DatabaseExists checks if a database instance exists (is loaded).
  100. func (dm *DatabaseManager) DatabaseExists(name string) bool {
  101. dm.mu.RLock()
  102. defer dm.mu.RUnlock()
  103. _, exists := dm.databases[name]
  104. return exists
  105. }
  106. // GetPool returns the underlying KV pool.
  107. func (dm *DatabaseManager) GetPool() *KVPool {
  108. return dm.pool
  109. }
  110. // SetAutoCreate enables or disables auto-creation of databases.
  111. func (dm *DatabaseManager) SetAutoCreate(autoCreate bool) {
  112. dm.mu.Lock()
  113. defer dm.mu.Unlock()
  114. dm.autoCreate = autoCreate
  115. }