-
Notifications
You must be signed in to change notification settings - Fork 1
add support for multiple db #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,44 @@ import ( | |
| _ "github.com/lib/pq" | ||
| ) | ||
|
|
||
| // ConnectDB establishes a connection to the PostgreSQL database. | ||
| // ConnectDBs establishes connections to multiple PostgreSQL databases. | ||
| func ConnectDBs(configs map[string]Config) (map[string]*sql.DB, error) { | ||
| dbs := make(map[string]*sql.DB) | ||
| var firstErr error | ||
|
|
||
| for name, config := range configs { | ||
| connStr := fmt.Sprintf( | ||
| "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", | ||
| config.Host, config.Port, config.User, config.Password, config.Name, config.SSLMode, | ||
| ) | ||
|
|
||
| db, err := sql.Open("postgres", connStr) | ||
| if err != nil { | ||
| if firstErr == nil { | ||
| firstErr = fmt.Errorf("failed to connect to database %s: %v", name, err) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and errBag = append(errBag, fmt.Errorf(...)) here |
||
| } | ||
| continue | ||
| } | ||
|
|
||
| if err := db.Ping(); err != nil { | ||
| db.Close() | ||
| if firstErr == nil { | ||
| firstErr = fmt.Errorf("failed to ping database %s: %v", name, err) | ||
| } | ||
| continue | ||
| } | ||
|
|
||
| dbs[name] = db | ||
| } | ||
|
|
||
| if len(dbs) == 0 && firstErr != nil { | ||
| return nil, firstErr | ||
| } | ||
|
|
||
| return dbs, firstErr | ||
| } | ||
|
|
||
| // ConnectDB establishes a connection to a single PostgreSQL database. | ||
| func ConnectDB(config *Config) (*sql.DB, error) { | ||
| connStr := fmt.Sprintf( | ||
| "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,20 +10,29 @@ import ( | |
| ) | ||
|
|
||
| func main() { | ||
| // Load configuration | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be a file if the environment variable is undefined There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. `Yes, it could be a file, but in general it supposed to work with environmental variables provided by the tool using the server (Roo Code, Cline etc) |
||
| cfg, err := config.LoadConfig() | ||
| // Load configurations | ||
| configs, err := config.LoadConfigs("POSTGRES_DBS") | ||
| if err != nil { | ||
| log.Fatalf("Failed to load configuration: %v", err) | ||
| log.Fatalf("Failed to load configurations: %v", err) | ||
| } | ||
|
|
||
| // Connect to the database | ||
| db, err := config.ConnectDB(cfg) | ||
| // Connect to all databases | ||
| dbs, err := config.ConnectDBs(configs) | ||
| if err != nil { | ||
| log.Fatalf("Failed to connect to the database: %v", err) | ||
| log.Printf("Warning: some database connections failed: %v", err) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe %+v here for better representation for bag of error |
||
| if len(dbs) == 0 { | ||
| log.Fatal("No database connections established") | ||
| } | ||
| } | ||
| defer db.Close() | ||
|
|
||
| log.Println("Successfully connected to the PostgreSQL database!") | ||
| // Close all connections on exit | ||
| defer func() { | ||
| for _, db := range dbs { | ||
| db.Close() | ||
| } | ||
| }() | ||
|
|
||
| log.Printf("Successfully connected to %d PostgreSQL database(s)!", len(dbs)) | ||
|
|
||
| // Initialize the MCP server | ||
| s := server.NewMCPServer( | ||
|
|
@@ -32,11 +41,11 @@ func main() { | |
| server.WithLogging(), | ||
| ) | ||
|
|
||
| // Register the PostgreSQL tools | ||
| tools.RegisterExecuteTool(s, db) | ||
| tools.RegisterQueryTool(s, db) | ||
| tools.RegisterSchemaTool(s, db) | ||
| tools.RegisterTransactionTool(s, db) | ||
| // Register the PostgreSQL tools with all databases | ||
| tools.RegisterExecuteTool(s, dbs) | ||
| tools.RegisterQueryTool(s, dbs) | ||
| tools.RegisterSchemaTool(s, dbs) | ||
| tools.RegisterTransactionTool(s, dbs) | ||
|
|
||
| // Start the server | ||
| log.Println("Starting MCP server...") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to have a bag of errors here (var errBag []error) to process a case when more than one DB is throwing an error.