2
0

db_manager.go 3.2 KB

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