db663cc82d
Adds a new ConnectionStrings section to ConfigManager allowing users to manage database connection strings with provider selection, connection testing, and visual feedback for connection state.
300 lines
12 KiB
Markdown
300 lines
12 KiB
Markdown
# ConnectionStrings Editor - Design Plan
|
|
|
|
## Overview
|
|
|
|
Add a ConnectionStrings section under Settings in the ConfigManager tree view. This section provides a master-detail editor for managing database connection strings with provider-specific field editing.
|
|
|
|
## Design Decisions
|
|
|
|
| Decision | Choice | Rationale |
|
|
|----------|--------|-----------|
|
|
| Storage location | appsettings.json | Consistent with existing settings pattern |
|
|
| Field editing | Provider-specific parsed fields | Better UX than raw connection string editing |
|
|
| Supported providers | Generic, Oracle, SqlServer | Covers existing JDE/CMS/MSSQL needs |
|
|
| SQL Server auth | SQL Authentication only | Windows auth not needed for this use case |
|
|
| Password display | Masked with reveal toggle | Security + usability balance |
|
|
| Edit workflow | Inline panel editing | Matches existing form patterns |
|
|
| Delete behavior | Confirmation dialog, immediate | Prevents accidents, clear feedback |
|
|
|
|
## Architecture
|
|
|
|
### Tree Structure
|
|
|
|
```
|
|
Settings/
|
|
├── DataSync
|
|
├── DataAccess
|
|
├── Auth
|
|
├── Ldap
|
|
├── Search
|
|
├── ExcelExport
|
|
└── ConnectionStrings <-- NEW
|
|
```
|
|
|
|
### Data Model
|
|
|
|
**ConnectionStringEntry** - represents a single connection string:
|
|
|
|
```csharp
|
|
public class ConnectionStringEntry
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public ConnectionProvider Provider { get; set; } = ConnectionProvider.Generic;
|
|
|
|
// SqlServer fields
|
|
public string? Server { get; set; }
|
|
public string? Database { get; set; }
|
|
public string? UserId { get; set; }
|
|
public string? Password { get; set; }
|
|
public string Encrypt { get; set; } = "True";
|
|
public bool TrustServerCertificate { get; set; }
|
|
public int ConnectionTimeout { get; set; } = 30;
|
|
public string? ApplicationName { get; set; }
|
|
|
|
// Oracle fields
|
|
public string? Host { get; set; }
|
|
public int Port { get; set; } = 1521;
|
|
public string? ServiceName { get; set; }
|
|
|
|
// Generic fields
|
|
public string? RawConnectionString { get; set; }
|
|
|
|
// Generates the final connection string based on Provider
|
|
public string GenerateConnectionString() { ... }
|
|
}
|
|
|
|
public enum ConnectionProvider
|
|
{
|
|
Generic,
|
|
SqlServer,
|
|
Oracle
|
|
}
|
|
```
|
|
|
|
**ConnectionStringsSection** - the config model section:
|
|
|
|
```csharp
|
|
public class ConnectionStringsSection
|
|
{
|
|
public List<ConnectionStringEntry> Entries { get; set; } = new();
|
|
}
|
|
```
|
|
|
|
### ViewModel Structure
|
|
|
|
```
|
|
ConnectionStringsFormViewModel
|
|
├── Connections : ObservableCollection<ConnectionStringEntryViewModel>
|
|
├── SelectedConnection : ConnectionStringEntryViewModel?
|
|
├── HasSelection : bool
|
|
├── AvailableProviders : IReadOnlyList<ConnectionProvider>
|
|
├── AddConnectionCommand
|
|
├── DeleteConnectionCommand
|
|
├── ValidateConnectionCommand
|
|
├── TestConnectionCommand
|
|
```
|
|
|
|
**ConnectionStringEntryViewModel** - wraps each entry for editing:
|
|
|
|
```csharp
|
|
public class ConnectionStringEntryViewModel : ViewModelBase
|
|
{
|
|
// All fields from ConnectionStringEntry exposed as properties
|
|
// Provider property triggers template switching
|
|
// GeneratedConnectionString property for preview
|
|
// IsPasswordVisible for password reveal toggle
|
|
}
|
|
```
|
|
|
|
### Connection String Formats
|
|
|
|
**SqlServer:**
|
|
```
|
|
Server={server};Database={database};User Id={userId};Password={password};Encrypt={encrypt};TrustServerCertificate={trust};Connection Timeout={timeout};Application Name={appName};
|
|
```
|
|
|
|
**Oracle (EZConnect):**
|
|
```
|
|
Data Source=//{host}:{port}/{serviceName};User Id={userId};Password={password};Connection Timeout={timeout};
|
|
```
|
|
|
|
**Generic:**
|
|
Raw connection string as entered by user.
|
|
|
|
## UI Design
|
|
|
|
### Layout Structure
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Connection Strings │
|
|
│ ──────────────────────────────────────────────────────── │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ ┌─────────────────────────────────────────────────────┐ │
|
|
│ │ Connections (3) │ │
|
|
│ │ ┌────────────┬──────────┬─────────────────────────┐ │ │
|
|
│ │ │ Name │ Provider │ Server │ │ │
|
|
│ │ ├────────────┼──────────┼─────────────────────────┤ │ │
|
|
│ │ │ jde │ Oracle │ jdeserver.company.com │ │ │
|
|
│ │ │ mssql │ SqlServer│ localhost\SQLEXPRESS │ │ │
|
|
│ │ │ cms │ Generic │ - │ │ │
|
|
│ │ └────────────┴──────────┴─────────────────────────┘ │ │
|
|
│ │ [+ Add] [Delete] │ │
|
|
│ └─────────────────────────────────────────────────────┘ │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ ┌─────────────────────────────────────────────────────┐ │
|
|
│ │ Edit Connection: mssql │ │
|
|
│ │ │ │
|
|
│ │ Name * Provider * │ │
|
|
│ │ [mssql ] [SqlServer ▼] │ │
|
|
│ │ ──────────────────────────────────────────────────── │ │
|
|
│ │ Server * Database * │ │
|
|
│ │ [localhost\SQLEXPRESS] [ScopingTool ] │ │
|
|
│ │ │ │
|
|
│ │ User Id Password │ │
|
|
│ │ [sa ] [•••••••• ] [👁] │ │
|
|
│ │ │ │
|
|
│ │ Encrypt ☐ Trust Server Certificate │ │
|
|
│ │ [True ▼] (Skip cert validation) │ │
|
|
│ │ │ │
|
|
│ │ Connection Timeout Application Name │ │
|
|
│ │ [30 ] [JdeScopingTool ] │ │
|
|
│ │ ──────────────────────────────────────────────────── │ │
|
|
│ │ CONNECTION STRING PREVIEW │ │
|
|
│ │ Server=localhost\SQLEXPRESS;Database=ScopingTool;... │ │
|
|
│ └─────────────────────────────────────────────────────┘ │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ ┌─────────────────────────────────────────────────────┐ │
|
|
│ │ [Validate] [Test Connection] │ │
|
|
│ └─────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Provider-Specific Forms
|
|
|
|
**SqlServer fields:**
|
|
- Server (text, required)
|
|
- Database (text, required)
|
|
- User Id (text)
|
|
- Password (password with reveal toggle)
|
|
- Encrypt (dropdown: True/False/Strict)
|
|
- TrustServerCertificate (checkbox)
|
|
- Connection Timeout (numeric, default 30)
|
|
- Application Name (text)
|
|
|
|
**Oracle fields:**
|
|
- Host (text, required)
|
|
- Port (numeric, default 1521)
|
|
- Service Name (text, required)
|
|
- User Id (text, required)
|
|
- Password (password with reveal toggle, required)
|
|
- Connection Timeout (numeric)
|
|
|
|
**Generic fields:**
|
|
- Connection String (multiline text, required)
|
|
|
|
### Button Behaviors
|
|
|
|
| Button | Action |
|
|
|--------|--------|
|
|
| Add | Creates new entry with default values, selects it |
|
|
| Delete | Shows confirmation dialog, removes entry on confirm |
|
|
| Validate | Validates connection string syntax (no network call) |
|
|
| Test | Attempts actual database connection, shows modal with result |
|
|
|
|
### State Transitions
|
|
|
|
```
|
|
No connections → Empty state with "Add First Connection" button
|
|
Connections exist, none selected → Table visible, placeholder in edit area
|
|
Connection selected → Edit form visible with provider-specific fields
|
|
Field changed → Entry marked dirty, generates preview string
|
|
Save (via main Save) → All changes persisted to appsettings.json
|
|
```
|
|
|
|
## Integration Points
|
|
|
|
### ConfigModel Integration
|
|
|
|
Add `ConnectionStrings` property to `ConfigModel`:
|
|
|
|
```csharp
|
|
public class ConfigModel
|
|
{
|
|
// Existing properties...
|
|
public ConnectionStringsSection ConnectionStrings { get; set; } = new();
|
|
}
|
|
```
|
|
|
|
### MainWindowViewModel Integration
|
|
|
|
- Add ConnectionStrings node to tree under Settings folder
|
|
- Handle node selection to load `ConnectionStringsFormViewModel`
|
|
- Mark node as modified when connection strings change
|
|
|
|
### Serialization
|
|
|
|
Connection strings serialize to appsettings.json as:
|
|
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"Entries": [
|
|
{
|
|
"Name": "mssql",
|
|
"Provider": "SqlServer",
|
|
"Server": "localhost\\SQLEXPRESS",
|
|
"Database": "ScopingTool",
|
|
"UserId": "sa",
|
|
"Password": "secretpassword",
|
|
"Encrypt": "True",
|
|
"TrustServerCertificate": true,
|
|
"ConnectionTimeout": 30,
|
|
"ApplicationName": "JdeScopingTool"
|
|
},
|
|
{
|
|
"Name": "jde",
|
|
"Provider": "Oracle",
|
|
"Host": "jdeserver.company.com",
|
|
"Port": 1521,
|
|
"ServiceName": "JDEPROD",
|
|
"UserId": "jde_readonly",
|
|
"Password": "oraclepassword",
|
|
"ConnectionTimeout": 60
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
|
|
1. **ConnectionStringEntry tests:**
|
|
- GenerateConnectionString produces correct format per provider
|
|
- Default values are correct
|
|
- Required field validation
|
|
|
|
2. **ConnectionStringEntryViewModel tests:**
|
|
- Property changes raise PropertyChanged
|
|
- Provider change clears irrelevant fields
|
|
- Password visibility toggle works
|
|
|
|
3. **ConnectionStringsFormViewModel tests:**
|
|
- Add creates new entry and selects it
|
|
- Delete removes selected entry
|
|
- Selection change updates form
|
|
- HasSelection reflects state correctly
|
|
|
|
### Integration Tests
|
|
|
|
1. **Serialization round-trip:**
|
|
- Save and reload preserves all fields
|
|
- Provider enum serializes correctly
|
|
|
|
2. **Connection testing:**
|
|
- SqlServer test connection works
|
|
- Oracle test connection works
|
|
- Error messages displayed correctly
|