Changeset 0.21.1.1 (#87)
This commit is contained in:
@@ -43,6 +43,10 @@ func connectPostgres(dsn string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Log the database name for operational clarity (never log credentials).
|
||||
dbName = extractDBName(dsn)
|
||||
log.Printf("Connecting to Postgres database %q ...", dbName)
|
||||
|
||||
var err error
|
||||
DB, err = sql.Open("postgres", dsn)
|
||||
if err != nil {
|
||||
@@ -57,7 +61,7 @@ func connectPostgres(dsn string) error {
|
||||
}
|
||||
|
||||
CurrentDialect = DialectPostgres
|
||||
log.Println("✅ Database connected (postgres)")
|
||||
log.Printf("✅ Database connected (postgres, db=%s)", dbName)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -104,6 +108,7 @@ func connectSQLite(dsn string) error {
|
||||
// Verify WAL mode took effect (some in-memory modes ignore it).
|
||||
var mode string
|
||||
DB.QueryRow("PRAGMA journal_mode").Scan(&mode)
|
||||
dbName = dsn
|
||||
log.Printf("✅ Database connected (sqlite, journal_mode=%s, path=%s)", mode, dsn)
|
||||
|
||||
CurrentDialect = DialectSQLite
|
||||
@@ -125,6 +130,32 @@ func detectDriver(dsn string) string {
|
||||
return "postgres"
|
||||
}
|
||||
|
||||
// extractDBName pulls the database name from a DSN for logging.
|
||||
// Handles both URL-style (postgres://user:pass@host/dbname) and
|
||||
// keyword-style (host=... dbname=...) formats. Never returns creds.
|
||||
func extractDBName(dsn string) string {
|
||||
// URL style: postgres://user:pass@host:port/dbname?params
|
||||
if strings.Contains(dsn, "://") {
|
||||
idx := strings.LastIndex(dsn, "/")
|
||||
if idx >= 0 && idx < len(dsn)-1 {
|
||||
name := dsn[idx+1:]
|
||||
if q := strings.Index(name, "?"); q >= 0 {
|
||||
name = name[:q]
|
||||
}
|
||||
if name != "" {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
// Keyword style: host=... dbname=xyz ...
|
||||
for _, part := range strings.Fields(dsn) {
|
||||
if strings.HasPrefix(part, "dbname=") {
|
||||
return strings.TrimPrefix(part, "dbname=")
|
||||
}
|
||||
}
|
||||
return "(unknown)"
|
||||
}
|
||||
|
||||
// Close gracefully shuts down the connection pool.
|
||||
func Close() {
|
||||
if DB != nil {
|
||||
@@ -139,3 +170,11 @@ func IsConnected() bool {
|
||||
}
|
||||
return DB.Ping() == nil
|
||||
}
|
||||
|
||||
// dbName holds the database name extracted at connect time.
|
||||
var dbName string
|
||||
|
||||
// Name returns the database name (extracted from the DSN at connect time).
|
||||
func Name() string {
|
||||
return dbName
|
||||
}
|
||||
|
||||
16
server/database/migrations/010_v0211_workspace_bindings.sql
Normal file
16
server/database/migrations/010_v0211_workspace_bindings.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
-- v0.21.1: Workspace bindings for channels and projects
|
||||
--
|
||||
-- Channels and projects can optionally bind to a workspace.
|
||||
-- Resolution chain: channel workspace_id > project workspace_id.
|
||||
|
||||
-- Channel workspace binding
|
||||
ALTER TABLE channels
|
||||
ADD COLUMN IF NOT EXISTS workspace_id UUID REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_channels_workspace ON channels(workspace_id) WHERE workspace_id IS NOT NULL;
|
||||
|
||||
-- Project workspace binding
|
||||
ALTER TABLE projects
|
||||
ADD COLUMN IF NOT EXISTS workspace_id UUID REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_projects_workspace ON projects(workspace_id) WHERE workspace_id IS NOT NULL;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- v0.21.1: Workspace bindings for channels and projects (SQLite)
|
||||
|
||||
ALTER TABLE channels ADD COLUMN workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_channels_workspace ON channels(workspace_id);
|
||||
|
||||
ALTER TABLE projects ADD COLUMN workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_projects_workspace ON projects(workspace_id);
|
||||
Reference in New Issue
Block a user