Database Connections
Introduction
Establishing a connection to a database is the first step in using Velocity. The framework provides flexible connection mechanisms that work with all supported database systems while maintaining a consistent API across vendors.
The Manager class serves as the central entry point for all Velocity operations. For connected operations, a Manager must be created with a database connection. Velocity supports two primary approaches for creating connections:
- DatasourceConnection Objects - Strongly-typed connection objects with properties (recommended)
- Connection Strings - Standard ADO.NET connection strings with additional context settings
Note
A Manager can also be created without a database connection using the parameterless constructor new Manager(). This is only for disconnected operations such as reading and writing schema files. See Disconnected Operations for details.
Connection Approaches
Approach 1: DatasourceConnection Objects (Recommended)
The recommended approach is to use database-specific connection classes. This approach provides:
- Type safety and IntelliSense support
- Clear, self-documenting connection parameters
- Built-in validation
- Access to database-specific advanced and context settings
DB2 Connection
DB2DatasourceConnection provides connection configuration for IBM DB2:
var connection = new DB2DatasourceConnection
{
Hostname = "db2.example.com",
Port = 50000,
Username = "db2admin",
Password = "password",
Database = "MYDB"
};
// Set context settings individually
connection.ImportTimeout = 120;
connection.ImportBatchSize = 10000;
connection.UpdateFrequency = "d(0,1,2,3,4,5,6) h(0,12) m(0)";
connection.UpdateMinimum = 5;
using (var manager = new Manager(connection))
{
var schema = manager.LoadSchema("myschema");
}
MySQL Connection
MySqlDatasourceConnection provides connection configuration for MySQL:
var connection = new MySqlDatasourceConnection
{
Hostname = "mysql.example.com",
Port = 3306,
Username = "root",
Password = "password",
Database = "myapp_db"
};
// Set advanced settings for MySQL-specific connection behavior
connection.AllowLoadLocalInfile = true;
connection.AllowUserVariables = true;
// Set context settings individually using strongly-typed properties
connection.ImportTimeout = 120;
connection.LengthUnit = "metre";
using (var manager = new Manager(connection))
{
var schema = manager.LoadSchema("myschema");
}
Oracle Connection
OracleDatasourceConnection provides connection configuration for Oracle Database:
var connection = new OracleDatasourceConnection
{
Hostname = "oracle.example.com",
Port = 1521,
Username = "system",
Password = "password",
Database = "ORCL"
};
// Set context settings using strongly-typed properties
connection.Tablespace = "USERS";
connection.ImportTimeout = 120;
connection.ImportBatchSize = 10000;
connection.Tolerance = 0.01f;
connection.UseBooleanDataType = false;
using (var manager = new Manager(connection))
{
var schema = manager.LoadSchema("myschema");
}
PostgreSQL Connection
PostgreSqlDatasourceConnection provides connection configuration for PostgreSQL:
var connection = new PostgreSqlDatasourceConnection
{
Hostname = "postgres.example.com",
Port = 5432,
Username = "postgres",
Password = "password",
Database = "myapp_db"
};
// Set context settings individually
connection.ImportTimeout = 120;
connection.DefaultSrid = 4326;
using (var manager = new Manager(connection))
{
var database = manager.LoadDatabase();
}
SQLite Connection
SqliteDatasourceConnection provides connection configuration for SQLite. SQLite uses a unique folder-based approach where the Database property represents a folder path rather than a database name:
var connection = new SqliteDatasourceConnection
{
Database = "./data" // Folder path, not a database file
};
// Set context settings
connection.ImportTimeout = 120;
using (var manager = new Manager(connection))
{
// Creates or opens ./data/main.db
var schema = manager.LoadSchema("main");
}
SQLite Multi-Schema Support:
SQLite implements schemas as separate database files within the folder:
main.db- The default schema{schemaname}.db- Additional schemas
Cross-schema operations use SQLite's ATTACH DATABASE feature automatically.
SQL Server Connection
SqlServerDatasourceConnection provides connection configuration for Microsoft SQL Server:
using YndigoBlue.Velocity.Engine;
using YndigoBlue.Velocity.Data.SqlServer;
using YndigoBlue.Velocity.Enums;
var connection = new SqlServerDatasourceConnection
{
Hostname = "sqlserver.example.com",
Port = 1433,
Username = "myuser",
Password = "mypassword",
Database = "myapp_db"
};
// Set context settings individually using strongly-typed properties
connection.ImportTimeout = 120; // Universal setting
connection.ImportBatchSize = 10000; // Universal setting
connection.DefaultSrid = 4326; // Universal setting
// SSL — see the SSL/TLS section below for the full set of options
connection.SslMode = SslMode.VerifyCA;
connection.SslCaPath = "./certs/ca-cert.pem";
using (var manager = new Manager(connection))
{
// Perform database operations
var schema = manager.LoadSchema("myschema");
}
Teradata Connection
TeradataDatasourceConnection provides connection configuration for Teradata Vantage:
var connection = new TeradataDatasourceConnection
{
Hostname = "teradata.example.com",
Port = 1025,
Username = "dbc",
Password = "password",
Database = "myapp_db"
};
// Set context settings individually using strongly-typed properties
connection.DefaultSrid = 1619;
connection.FullTextSearchClobs = false;
connection.FullTextSearchEnabled = false;
connection.IdentityStartValue = 1;
connection.ImportBatchSize = 1000;
connection.ImportCastClob = true;
connection.ImportCastGeo = true;
connection.NumberOfStagingTables = 4;
connection.PermanentSpace = 100000000;
connection.SelectCastClob = true;
connection.VarCharCastSize = 32000;
using (var manager = new Manager(connection))
{
var schema = manager.LoadSchema("myschema");
}
Approach 2: Connection Strings
Velocity also supports standard ADO.NET connection strings with optional context settings. The DatasourceType enum is used to specify the database type. This approach is useful when:
- Working with existing connection string configurations
- Loading connection parameters from configuration files
- Integrating with enterprise connection management systems
using YndigoBlue.Velocity.Engine;
using YndigoBlue.Velocity.Enums;
// SQL Server with connection string
string connectionString = "Data Source=server,1433;Initial Catalog=mydb;User ID=username;Password=pwd1234;Trust Server Certificate=True";
string contextSettings = "ImportTimeout=120;ImportBatchSize=10000;DefaultSrid=4326";
using (var manager = new Manager(DatasourceType.SQLServer, connectionString, contextSettings))
{
var schema = manager.LoadSchema("myschema");
}
Connection String Examples by Database
DB2:
string connectionString = "Server=localhost:50000;Database=MYDB;UID=db2admin;PWD=password";
using (var manager = new Manager(DatasourceType.DB2, connectionString))
{
// Operations
}
MySQL:
string connectionString = "Server=localhost;Port=3306;Database=mydb;Uid=root;Pwd=password;AllowLoadLocalInfile=True;AllowUserVariables=True";
using (var manager = new Manager(DatasourceType.MySQL, connectionString))
{
// Operations
}
Oracle:
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=system;Password=password;";
using (var manager = new Manager(DatasourceType.Oracle, connectionString))
{
// Operations
}
PostgreSQL:
string connectionString = "Host=localhost;Port=5432;Database=mydb;Username=postgres;Password=password";
using (var manager = new Manager(DatasourceType.PostgreSQL, connectionString))
{
// Operations
}
SQLite:
string connectionString = "Data Source=./data/main.db";
using (var manager = new Manager(DatasourceType.Sqlite, connectionString))
{
// Operations
}
SQL Server:
string connectionString = "Data Source=localhost,1433;Initial Catalog=mydb;User ID=sa;Password=password;Trust Server Certificate=True";
using (var manager = new Manager(DatasourceType.SQLServer, connectionString))
{
// Operations
}
Teradata:
string connectionString = "Data Source=localhost;Database=mydb;User ID=dbc;Password=password";
using (var manager = new Manager(DatasourceType.Teradata, connectionString))
{
// Operations
}
Understanding Settings: Advanced vs Context
Velocity uses two types of settings to configure database connections:
- AdvancedSettings: Database-specific connection parameters passed to the underlying ADO.NET provider
- ContextSettings: Velocity framework behavior settings that control how Velocity operates
Key Differences
| Aspect | AdvancedSettings | ContextSettings |
|---|---|---|
| Purpose | Configure ADO.NET provider behavior | Configure Velocity framework behavior |
| Scope | Passed to database driver | Used by Velocity operations |
| Examples | MultipleActiveResultSets, Application Name, Statement Cache Size |
ImportTimeout, DefaultSrid, ImportBatchSize |
| Where Used | Connection string to database | Velocity commands and operations |
| Timing | Applied during connection | Applied during operations |
AdvancedSettings
AdvancedSettings control the underlying database connection behavior by passing parameters directly to the ADO.NET provider. These are standard connection string parameters specific to each database vendor.
How AdvancedSettings Work
When you create a Manager with a DatasourceConnection, Velocity:
- Reads named properties (
Hostname,Port,Username,Password,Database,Pooling,ConnectTimeout,MaxPoolSize,MinPoolSize) - Merges them with AdvancedSettings to build the final connection string
- Passes the complete connection string to the ADO.NET provider
Reserved Settings are connection parameters that have corresponding named properties and cannot be overridden via SetAdvancedSettings():
- Connection Parameters:
Hostname/Host,Port,Username/UserID,Password,Database/InitialCatalog/DataSource - Universal Properties:
Pooling,ConnectTimeout,MaxPoolSize,MinPoolSize - SSL/TLS Properties:
SslMode,SslCaPath,SslCertificatePath,SslKeyPath - Authentication Properties:
UseIntegratedSecurityplus database-specific keys likeAuthentication,Encrypt,TrustServerCertificate,Server Certificate,AuthenticationMechanism,IntegratedSecurity(see Security: SSL/TLS and Authentication)
These reserved settings are always controlled through their strongly-typed properties to prevent conflicts and ensure consistency.
Setting AdvancedSettings
Use the SetAdvancedSettings() method to configure database-specific connection parameters:
var connection = new SqlServerDatasourceConnection
{
// Required connection parameters (reserved settings)
Hostname = "localhost",
Port = 1433,
Username = "sa",
Password = "password",
Database = "mydb",
// Universal properties (reserved settings)
Pooling = true,
ConnectTimeout = 15,
MaxPoolSize = 100,
MinPoolSize = 0
};
// Additional provider-specific settings (non-reserved). Note: SSL behaviour
// (Encrypt, TrustServerCertificate, Server Certificate) is controlled via the
// SslMode / SslCaPath properties — see the SSL/TLS section below.
connection.SetAdvancedSettings("MultipleActiveResultSets=True;Application Name=MyApp");
Important: If you try to override reserved settings via SetAdvancedSettings(), they will be ignored:
connection.Pooling = true;
connection.ConnectTimeout = 15;
connection.MaxPoolSize = 100;
connection.MinPoolSize = 0;
// These will be IGNORED - reserved settings use named properties
connection.SetAdvancedSettings("Pooling=False;Connect Timeout=30;MaxPoolSize=50;MinPoolSize=5");
// connection.Pooling is still true
// connection.ConnectTimeout is still 15
// connection.MaxPoolSize is still 100
// connection.MinPoolSize is still 0
Database-Specific Advanced Properties
Some databases expose additional advanced settings as strongly-typed properties:
var connection = new MySqlDatasourceConnection
{
Hostname = "localhost",
Port = 3306,
Username = "root",
Password = "password",
Database = "mydb"
};
// MySQL exposes these as strongly-typed properties
connection.AllowLoadLocalInfile = true; // Exposed as property
connection.AllowUserVariables = true; // Exposed as property
// Other settings via SetAdvancedSettings
connection.SetAdvancedSettings("SSL Mode=None;Default Command Timeout=30");
var connection = new OracleDatasourceConnection
{
Hostname = "localhost",
Port = 1521,
Username = "system",
Password = "password",
Database = "ORCL"
};
// Oracle has no database-specific strongly-typed advanced properties beyond universal settings
connection.MaxPoolSize = 100;
connection.MinPoolSize = 1;
// Additional settings via SetAdvancedSettings
connection.SetAdvancedSettings("Validate Connection=true;Statement Cache Size=10");
PostgreSqlDatasourceConnection:
var connection = new PostgreSqlDatasourceConnection
{
Hostname = "localhost",
Port = 5432,
Username = "postgres",
Password = "password",
Database = "mydb"
};
// PostgreSQL has no database-specific strongly-typed properties beyond universal settings
connection.MaxPoolSize = 100;
connection.MinPoolSize = 1;
// Additional settings via SetAdvancedSettings
connection.SetAdvancedSettings("SSL Mode=Prefer;Command Timeout=60");
SqlServerDatasourceConnection:
var connection = new SqlServerDatasourceConnection
{
Hostname = "localhost",
Port = 1433,
Username = "sa",
Password = "password",
Database = "mydb"
};
// SQL Server exposes TrustServerCertificate as a property
connection.TrustServerCertificate = true;
// Other settings via SetAdvancedSettings
connection.SetAdvancedSettings("Encrypt=False;MultipleActiveResultSets=True");
var connection = new SqliteDatasourceConnection
{
Database = "./data" // Folder path, not a database file
};
// SQLite has no database-specific strongly-typed advanced properties beyond universal settings
connection.MaxPoolSize = 100;
// Additional settings via SetAdvancedSettings
connection.SetAdvancedSettings("Cache=Shared;Foreign Keys=True");
var connection = new TeradataDatasourceConnection
{
Hostname = "localhost",
Port = 1025,
Username = "dbc",
Password = "password",
Database = "mydb"
};
// Teradata exposes SessionCharacterSet as a property
connection.SessionCharacterSet = "UTF8";
// Additional Teradata-specific connection parameters
connection.SetAdvancedSettings("Connect Function=1;Charset=UTF8");
Strongly-Typed Advanced Properties by Database
Some databases expose additional advanced settings as strongly-typed properties (in addition to the universal reserved settings like MaxPoolSize and MinPoolSize, and the SSL/auth properties documented in Security: SSL/TLS and Authentication):
DB2
DB2DatasourceConnection exposes:
AuthenticationMethod- DB2AuthenticationMethod selector whenUseIntegratedSecurity = true(Kerberos, GSS plugin, Client auth, etc.)
MySQL
MySqlDatasourceConnection exposes:
AllowLoadLocalInfile- Enable LOAD DATA LOCAL INFILE (required for imports)AllowUserVariables- Enable user variable support (required for some operations)
Oracle
OracleDatasourceConnection has no database-specific strongly-typed advanced properties beyond universal settings. Authentication mechanism (OS auth, Kerberos, RADIUS) is configured via sqlnet.ora on the client.
PostgreSQL
PostgreSqlDatasourceConnection has no database-specific strongly-typed advanced properties beyond universal settings. Authentication mechanism is server-driven via pg_hba.conf; Npgsql auto-negotiates SSPI / GSSAPI when no credentials are supplied.
SQL Server
SqlServerDatasourceConnection exposes:
TrustServerCertificate- Bypass server certificate validation. Automatically disabled whenSslModeisVerifyCAorVerifyFullAuthenticationMethod- SqlServerAuthenticationMethod selector whenUseIntegratedSecurity = true(Windows Integrated or any of seven Azure AD variants)
SQLite
SqliteDatasourceConnection has no database-specific strongly-typed advanced properties beyond universal settings. SQLite is file-based and has no network authentication.
Teradata
TeradataDatasourceConnection exposes:
SessionCharacterSet- Character set for sessionAuthenticationMethod- TeradataAuthenticationMethod selector whenUseIntegratedSecurity = true(LDAP, SPNEGO, TDNEGO, JWT, Bearer)
Context Settings
Context Settings are Velocity-specific settings that control how the framework operates, as opposed to AdvancedSettings which control the database connection itself. These settings affect Velocity's behavior when executing operations like imports, queries, and schema management.
How Context Settings Work
Context Settings are:
- Framework-Level: Applied to Velocity operations, not the database connection
- Operation-Specific: Used by Velocity commands (e.g.,
ImportTimeoutfor import operations,CommandTimeoutfor queries) - Cross-Database: Universal settings work the same across all database types
- Type-Safe: Always exposed as strongly-typed properties for compile-time checking
Key Difference from Advanced Settings:
ConnectTimeout(Advanced Setting) = time to establish connection to databaseCommandTimeout(Context Setting) = time for a database command to executeImportTimeout(Context Setting) = time for bulk import operations to complete
Setting Context Settings
Context settings can be configured in two ways:
1. Individual strongly-typed properties (Recommended):
var connection = new SqlServerDatasourceConnection
{
Hostname = "localhost",
Port = 1433,
Username = "sa",
Password = "password",
Database = "mydb"
};
// Set context settings using strongly-typed properties
connection.CommandTimeout = 30; // Default timeout for queries/commands
connection.ImportTimeout = 120; // Timeout for bulk import operations
connection.ImportBatchSize = 10000; // Rows per batch during imports
connection.DefaultSrid = 4326; // Default spatial reference ID
2. Connection string format using SetContextSettings():
var connection = new SqlServerDatasourceConnection
{
Hostname = "localhost",
Port = 1433,
Username = "sa",
Password = "password",
Database = "mydb"
};
// Set multiple context settings at once
connection.SetContextSettings("CommandTimeout=30;ImportTimeout=120;ImportBatchSize=10000;DefaultSrid=4326");
When using the connection string approach, context settings are passed as the third parameter to the Manager constructor:
string connectionString = "Data Source=localhost,1433;Initial Catalog=mydb;User ID=sa;Password=password";
string contextSettings = "CommandTimeout=30;ImportTimeout=120;ImportBatchSize=10000";
using (var manager = new Manager(DatasourceType.SQLServer, connectionString, contextSettings))
{
// Operations will use these timeouts
var schema = manager.LoadSchema("myschema"); // Uses CommandTimeout
manager.Import(importConfig, dataTable); // Uses ImportTimeout
}
Universal Context Settings
These settings are available on all DatasourceConnection classes and apply to all database types:
| Property | Type | Default | Description |
|---|---|---|---|
CommandTimeout |
int | 30 | Timeout in seconds for database commands (queries, DDL, DML) |
DefaultSrid |
int | 4326 | Default spatial reference identifier for geospatial operations |
ImportTimeout |
int | 120 | Timeout in seconds for bulk import operations |
ImportBatchSize |
int | 10000 | Number of rows per batch during bulk imports |
Example:
connection.CommandTimeout = 60; // Queries timeout after 60 seconds
connection.DefaultSrid = 3857;
connection.ImportTimeout = 180; // Imports timeout after 180 seconds
connection.ImportBatchSize = 5000;
// Or using SetContextSettings
connection.SetContextSettings("CommandTimeout=60;DefaultSrid=3857;ImportTimeout=180;ImportBatchSize=5000");
Understanding Timeouts:
ConnectTimeout(AdvancedSetting): Maximum time to establish database connectionCommandTimeout(ContextSetting): Maximum time for queries/DDL/DML to executeImportTimeout(ContextSetting): Maximum time for bulk import operations (often needs to be higher than CommandTimeout)
Database-Specific ContextSettings
Each database connection class exposes its context settings as strongly-typed properties for maximum type safety and IntelliSense support.
DB2
DB2DatasourceConnection exposes:
| Property | Type | Default | Description |
|---|---|---|---|
UpdateFrequency |
string | "d(0,1,2,3,4,5,6) h(0,12) m(0)" | Full-text index update frequency schedule |
UpdateMinimum |
int | 5 | Minimum number of changes before full text index update |
Example:
connection.UpdateFrequency = "d(0,1,2,3,4,5,6) h(0,12) m(0)";
connection.UpdateMinimum = 5;
// Or using SetContextSettings
connection.SetContextSettings("UpdateFrequency=d(0,1,2,3,4,5,6) h(0,12) m(0);UpdateMinimum=5");
MySQL
MySqlDatasourceConnection exposes:
| Property | Type | Default | Description |
|---|---|---|---|
LengthUnit |
string | "metre" | Unit for spatial length calculations |
Example:
connection.LengthUnit = "metre";
// Or using SetContextSettings
connection.SetContextSettings("LengthUnit=metre");
Oracle
OracleDatasourceConnection exposes:
| Property | Type | Default | Description |
|---|---|---|---|
EscapeIdentifiers |
bool | true | Quote all identifiers (table/column names) in generated SQL. Set to false when Oracle should use unquoted identifiers (names are then stored and compared in uppercase). |
Tablespace |
string | "" | Default tablespace for table creation |
Tolerance |
float | 0.01 | Tolerance for spatial operations |
UseBooleanDataType |
bool | false | Use Oracle 23c+ native boolean type (requires Oracle 23c+) |
SslCaPath |
string | "" | Path to the PEM-encoded CA certificate used to verify the server's certificate chain |
SslCertificatePath |
string | "" | Path to the PEM-encoded client certificate (mTLS only) |
SslKeyPath |
string | "" | Path to the PEM-encoded client private key (mTLS only) |
Note
EscapeIdentifiers is Oracle-only. All other databases always escape identifiers.
When EscapeIdentifiers=true (the default), Velocity wraps every identifier in double
quotes and Oracle preserves the declared case. When false, identifiers are unquoted and
Oracle uppercases them, which means schema/table/column names with spaces or mixed case
are not supported.
Important
Oracle SSL certificate paths are context settings, not advanced settings. ODP.NET has no
connection-string parameters for certificate configuration, so SslCaPath,
SslCertificatePath, and SslKeyPath cannot be passed via
SetAdvancedSettings. When using the connection-string approach, pass them via the
contextSettings parameter instead (e.g.
"SslMode=VerifyCA;SslCaPath=/certs/ca.pem"). When using an
OracleDatasourceConnection object directly, set them as properties as usual.
Example:
connection.EscapeIdentifiers = true; // Default — preserves declared case
connection.Tablespace = "USERS";
connection.Tolerance = 0.01f;
connection.UseBooleanDataType = false;
// Or using SetContextSettings
connection.SetContextSettings("EscapeIdentifiers=true;Tablespace=USERS;Tolerance=0.01;UseBooleanDataType=false");
// SSL via context settings (connection-string approach only — see note above)
connection.SetContextSettings("SslCaPath=/certs/ca.pem;SslCertificatePath=/certs/client.crt;SslKeyPath=/certs/client.key");
PostgreSQL
PostgreSqlDatasourceConnection has no database-specific context settings beyond the universal settings.
All context settings for PostgreSQL are available through the universal ImportTimeout, ImportBatchSize, and DefaultSrid properties.
SQL Server
SqlServerDatasourceConnection has no database-specific context settings beyond the universal settings.
All context settings for SQL Server are available through the universal ImportTimeout, ImportBatchSize, and DefaultSrid properties.
SQLite
SqliteDatasourceConnection has no database-specific context settings beyond the universal settings.
All context settings for SQLite are available through the universal ImportTimeout, ImportBatchSize, and DefaultSrid properties.
Teradata
TeradataDatasourceConnection exposes:
| Property | Type | Default | Description |
|---|---|---|---|
FullTextSearchClobs |
bool | false | Index CLOB columns in full-text indexes; if false, CLOBs are truncated at 32,000 characters (faster indexing) |
FullTextSearchEnabled |
bool | false | Enable full-text index and search support |
IdentityStartValue |
long | 1 | Starting value for identity columns |
ImportCastClob |
bool | true | Cast Clob columns to VARCHAR(VarCharCastSize) in staging tables during import |
ImportCastGeo |
bool | true | Cast Geometry/Geography columns to VARCHAR(VarCharCastSize) in staging tables during import |
NumberOfStagingTables |
int | 4 | Number of parallel staging tables used during bulk import |
PermanentSpace |
int | 100000000 | Permanent space allocation for newly created schemas/databases in bytes |
SelectCastClob |
bool | true | Cast Clob columns to VARCHAR(VarCharCastSize) on SELECT (affects queries and exports) |
SourceSpatialReference |
string | (WGS 84 WKT) | Source spatial reference for coordinate transformations |
TargetSpatialReference |
string | (NAD27 Albers WKT) | Target spatial reference for coordinate transformations |
VarCharCastSize |
int | 32000 | VARCHAR size used when casting Clob and Geometry/Geography columns |
Example:
connection.FullTextSearchClobs = false;
connection.FullTextSearchEnabled = false;
connection.IdentityStartValue = 1;
connection.ImportCastClob = true;
connection.ImportCastGeo = true;
connection.NumberOfStagingTables = 4;
connection.PermanentSpace = 100000000;
connection.SelectCastClob = true;
connection.VarCharCastSize = 32000;
// Or using SetContextSettings
connection.SetContextSettings("FullTextSearchEnabled=false;NumberOfStagingTables=4;PermanentSpace=100000000;VarCharCastSize=32000");
Security: SSL/TLS and Authentication
Velocity provides a unified, cross-platform abstraction for SSL/TLS and enterprise authentication. The same set of strongly-typed properties — backed by plain PEM files for trust material — works identically on Windows, Linux, and macOS, and across every supported database. The same code and the same certificate files can be deployed unchanged across all supported platforms.
Design philosophy
Every database driver exposes SSL and authentication very differently:
- DB2 uses IBM GSKit keystores (
.kdbfiles) - Oracle uses Oracle wallets created with
orapki - SQL Server uses the Windows Certificate Store on Windows
- MySQL and PostgreSQL accept paths to PEM files
- Teradata has its own TeraGSS configuration
Velocity wraps all of these into a single set of properties:
| Property | Purpose |
|---|---|
SslMode |
Encryption level and certificate verification mode |
SslCaPath |
PEM file containing the CA certificate used to verify the server's certificate |
SslCertificatePath |
PEM file containing the client certificate for mutual TLS |
SslKeyPath |
PEM file containing the client private key for mutual TLS |
UseIntegratedSecurity |
Replace username/password with enterprise authentication |
AuthenticationMethod |
Choose the specific mechanism when UseIntegratedSecurity = true (database-specific enum) |
Velocity then translates these into the keystore/wallet/PEM/store-specific machinery that the underlying driver expects. The goal is that the same configuration produces the same security posture against any supported database, given the appropriate server-side setup.
Escape hatches: when the built-in abstraction isn't enough
The file-based abstraction covers the most common cases. For anything outside this — OS trust stores, GSKit keystores, Oracle wallets, custom Kerberos config, Kubernetes ConfigMap-mounted secrets, identity-provider-specific knobs — there are two escape hatches:
1. Use a full connection string. Velocity passes the connection string verbatim to the underlying driver, so any driver-specific key is available:
using YndigoBlue.Velocity.Engine;
using YndigoBlue.Velocity.Enums;
string connectionString = "Server=mysrv;Database=mydb;Integrated Security=SSPI;Encrypt=Strict;HostNameInCertificate=mysrv.internal";
string contextSettings = "CommandTimeout=60";
using (var manager = new Manager(DatasourceType.SQLServer, connectionString, contextSettings))
{
// Driver receives the connection string unchanged
}
2. Use SetAdvancedSettings. Augment a DatasourceConnection with driver-specific keys
that Velocity doesn't expose natively:
var conn = new DB2DatasourceConnection
{
Hostname = "db2srv",
Database = "MYDB",
SslMode = SslMode.VerifyCA,
SslCaPath = "./ca-cert.pem"
};
// Layer a GSKit client keystore on top of Velocity's PEM-based trust
conn.SetAdvancedSettings("SSLClientKeystoreDB=C:\\DB2SSL\\client.kdb;SSLClientKeystash=C:\\DB2SSL\\client.sth");
Outside Velocity's responsibility
Velocity sets connection-string properties on behalf of the driver. The runtime authentication and trust infrastructure must be configured externally, and that configuration is the responsibility of the implementer:
- OS-level trust store maintenance (Windows Certificate Store, macOS Keychain, Linux CA bundle)
- Kerberos TGT acquisition, KDC configuration,
krb5.conf,kinit - Oracle wallet creation (
orapki) - IBM GSKit client keystore creation (
gsk8capicmd_64) - LDAP / Active Directory server configuration and user-to-identity mapping
- Azure AD tenant configuration, app registrations, managed identities
- Identity provider (OIDC / JWT issuer) registration and signing keys
- TLS server certificate installation, renewal, and rotation on each database server
If any of those is misconfigured, Velocity will surface the underlying driver's exception unchanged — it does not try to wrap or recover from infrastructure errors.
SslMode support matrix
| Mode | MySQL | PostgreSQL | SQL Server | Oracle | DB2 | Teradata | SQLite |
|---|---|---|---|---|---|---|---|
Disable |
❌¹ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A² |
Prefer |
✅ | ✅ | ❌ | ❌³ | ❌³ | ✅ | N/A² |
Require |
✅ | ✅ | ✅ | ❌³ | ❌³ | ✅ | N/A² |
VerifyCA |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A² |
VerifyFull |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | N/A² |
✅ = Supported. ❌ = Throws NotSupportedException at connection time.
¹ MySQL defaults to caching_sha2_password, which requires either an SSL connection
or RSA key exchange to protect credentials. There is no plaintext path. Use Prefer or
higher.
² SQLite is file-based — no network layer, so SSL does not apply.
³ Oracle's ODP.NET and IBM's GSKit always validate the server's certificate chain during
the TLS handshake. There is no "encrypt without verification" mode, so Prefer and
Require (both of which imply encrypt-without-verify) have no equivalent.
Mapping to driver-level settings
| Velocity property | SQL Server | PostgreSQL | MySQL | DB2 | Teradata | Oracle |
|---|---|---|---|---|---|---|
SslMode.Disable |
Encrypt=Optional |
sslmode=disable |
(rejected) | (no Security=SSL) |
sslmode=DISABLE |
PROTOCOL=TCP |
SslMode.Prefer |
(rejected) | sslmode=prefer |
SslMode=Preferred |
(rejected) | sslmode=PREFER |
(rejected) |
SslMode.Require |
Encrypt=Mandatory + TrustServerCertificate=true |
sslmode=require |
SslMode=Required |
(rejected) | sslmode=REQUIRE |
(rejected) |
SslMode.VerifyCA |
Encrypt=Mandatory + TrustServerCertificate=false + Server Certificate=... |
sslmode=verify-ca + Root Certificate=... |
SslMode=VerifyCA + SslCa=... |
Security=SSL + SSLClientHostnameValidation=Off + SSLServerCertificate=... |
sslmode=VERIFY-CA + sslca=... |
PROTOCOL=TCPS + injected OraclePEM |
SslMode.VerifyFull |
Encrypt=Strict + Server Certificate=... |
sslmode=verify-full + Root Certificate=... |
SslMode=VerifyFull + SslCa=... |
Security=SSL + SSLClientHostnameValidation=Basic + SSLServerCertificate=... |
sslmode=VERIFY-FULL + sslca=... |
PROTOCOL=TCPS + injected OraclePEM |
Mutual TLS (client certificate authentication)
When supported, set SslCertificatePath and SslKeyPath to PEM files on the client. The
server must trust the CA that signed the client certificate and must have a database user
whose external identity matches the certificate's subject DN.
| Database | Supported | Driver mechanism | Server-side user mapping |
|---|---|---|---|
| DB2 | ❌ | Net.IBM.Data.Db2 does not expose client cert parameters |
— |
| MySQL | ✅ | SslCert + SslKey connection string keys |
REQUIRE X509 clause on the user |
| Oracle | ✅ | ODP.NET OraclePEM API (injected at connection time) |
IDENTIFIED EXTERNALLY AS 'CN=...' |
| PostgreSQL | ✅ | SSL Certificate + SSL Key (Npgsql) |
cert method in pg_hba.conf |
| SQL Server | ❌ | SqlClient does not support client certificate authentication | — |
| SQLite | N/A | — | — |
| Teradata | ❌ | Teradata .NET driver has no SslCert/SslKey properties |
— |
Example: PostgreSQL with mutual TLS
var connection = new PostgreSqlDatasourceConnection
{
Hostname = "postgres.example.com",
Port = 5432,
Username = "yndigo_mtls",
// No Password — the cert is the credential
Database = "mydb",
SslMode = SslMode.VerifyCA,
SslCaPath = "./certs/ca-cert.pem",
SslCertificatePath = "./certs/client-cert.pem",
SslKeyPath = "./certs/client-key.pem",
};
Integrated Security and Authentication Methods
Setting UseIntegratedSecurity = true switches off username/password authentication.
AuthenticationMethod then selects the specific mechanism — it is a database-specific enum,
so each adaptor exposes only the values that its driver actually supports.
| Database | UseIntegratedSecurity |
AuthenticationMethod enum |
Values |
|---|---|---|---|
| DB2 | ✅ | DB2AuthenticationMethod | Client, Kerberos, KerberosServerEncrypt, GssPlugin, GssServerEncrypt |
| MySQL | ✅¹ | — | Server-driven. The plugin is negotiated automatically from the user account's IDENTIFIED WITH clause; no client-side mechanism selector is needed. |
| Oracle | ✅ | — | Single mechanism (User ID=/). The actual provider (OS auth, Kerberos, RADIUS) is configured in sqlnet.ora, not in the connection string. |
| PostgreSQL | ✅ | — | Server-driven via pg_hba.conf. Npgsql auto-negotiates SSPI on Windows or GSSAPI/Kerberos on Linux when no credentials are supplied. |
| SQL Server | ✅ | SqlServerAuthenticationMethod | WindowsIntegrated (SSPI) + 7 Azure AD variants |
| SQLite | N/A | — | — |
| Teradata | ✅ | TeradataAuthenticationMethod | Ldap, Spnego, Tdnego, Jwt, Bearer |
¹ MySQL Enterprise Edition only. Community Edition has no OS-level authentication plugins. The authentication mechanism is determined entirely by the server based on the user account's IDENTIFIED WITH configuration — there is no client-side enum selector.
Example: SQL Server with Azure Managed Identity
var connection = new SqlServerDatasourceConnection
{
Hostname = "myserver.database.windows.net",
Database = "mydb",
UseIntegratedSecurity = true,
AuthenticationMethod = SqlServerAuthenticationMethod.ActiveDirectoryManagedIdentity,
SslMode = SslMode.VerifyFull
};
Example: DB2 with Kerberos
var connection = new DB2DatasourceConnection
{
Hostname = "db2.example.com",
Database = "SAMPLE",
UseIntegratedSecurity = true,
AuthenticationMethod = DB2AuthenticationMethod.Kerberos
};
// A valid Kerberos TGT must already exist on the client machine
// (run `kinit user@REALM` first, or join the machine to the AD domain).
Example: Teradata with LDAP
var connection = new TeradataDatasourceConnection
{
Hostname = "teradata.example.com",
Database = "MYDB",
UseIntegratedSecurity = true,
AuthenticationMethod = TeradataAuthenticationMethod.Ldap
};
// The Teradata Gateway must be configured for LDAP, and the database user
// must be mapped to an LDAP identity:
// MODIFY USER dbuser AS EXTERNAL SECURITY DOMAIN LdapDomain;
Example: PostgreSQL with integrated security
var connection = new PostgreSqlDatasourceConnection
{
Hostname = "postgres.example.com",
Database = "mydb",
UseIntegratedSecurity = true
// No AuthenticationMethod — Npgsql negotiates SSPI/GSSAPI automatically
// based on the OS and pg_hba.conf.
};
Example: Oracle with OS authentication
var connection = new OracleDatasourceConnection
{
Hostname = "oracle.example.com",
Database = "ORCL",
UseIntegratedSecurity = true
// The DB user must be created with IDENTIFIED EXTERNALLY, and the OS user
// must match (subject to OS_AUTHENT_PREFIX), or Kerberos must be configured
// in sqlnet.ora on both client and server.
};
Round-tripping connection strings
The full connection-string overload of Manager participates in the same SSL/auth model.
When you pass a connection string in, Velocity parses it back into the strongly-typed
properties on a DatasourceConnection:
Encrypt,TrustServerCertificate,Server Certificate→SslMode+SslCaPathsslmode,Root Certificate,SSL Certificate,SSL Key→SslMode+SslCaPath/SslCertificatePath/SslKeyPathSslMode,SslCa,SslCert,SslKey→ dittoSecurity=SSL+SSLClientHostnameValidation+SSLServerCertificate→ dittoIntegrated Security=SSPIorAuthentication=...→UseIntegratedSecurity = true+ correspondingAuthenticationMethod- Oracle
User ID=/→UseIntegratedSecurity = true - Teradata
IntegratedSecurity=trueorAuthenticationMechanism=...→UseIntegratedSecurity = true+ correspondingAuthenticationMethod
This means the two approaches (DatasourceConnection vs connection string) are interchangeable for SSL and authentication — the same configuration is reachable from either side.
Connection Management Best Practices
1. Always Use Using Statements
Manager objects should always be wrapped in using statements to ensure proper disposal of database connections:
using (var manager = new Manager(connection))
{
// Perform operations
var schema = manager.LoadSchema("myschema");
} // Connection automatically closed and disposed
2. Store Connection Parameters Securely
Never hardcode credentials in source code. Use configuration files, environment variables, or secure credential stores:
using Microsoft.Extensions.Configuration;
// Load from configuration
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();
var connection = new SqlServerDatasourceConnection
{
Hostname = config["Database:Hostname"],
Port = int.Parse(config["Database:Port"]),
Username = config["Database:Username"],
Password = config["Database:Password"],
Database = config["Database:Database"]
};
appsettings.json:
{
"Database": {
"Hostname": "localhost",
"Port": "1433",
"Username": "myuser",
"Password": "mypassword",
"Database": "mydb"
}
}
3. Configure Appropriate Timeouts
Set timeouts based on your operational requirements. All connection types support CommandTimeout and ImportTimeout:
// Development environment - shorter timeouts for faster feedback
connection.ConnectTimeout = 5; // AdvancedSetting: quick connection timeout
connection.CommandTimeout = 30; // ContextSetting: standard query timeout
connection.ImportTimeout = 120; // ContextSetting: moderate import timeout
connection.ImportBatchSize = 1000; // Smaller batches for development
// Production environment - longer timeouts for reliability
connection.ConnectTimeout = 15; // AdvancedSetting: allow more time for connection
connection.CommandTimeout = 60; // ContextSetting: longer query timeout
connection.ImportTimeout = 300; // ContextSetting: extended import timeout
connection.ImportBatchSize = 10000; // Larger batches for performance
Timeout Guidelines:
- ConnectTimeout (AdvancedSetting): Usually 5-15 seconds
- CommandTimeout (ContextSetting): 30-60 seconds for most queries
- ImportTimeout (ContextSetting): 120-300+ seconds depending on data volume
4. Use Context Settings for Environment-Specific Behavior
Separate connection parameters from operational settings:
// Development environment
connection.ImportBatchSize = 1000;
connection.ImportTimeout = 60;
// Production environment
connection.ImportBatchSize = 10000;
connection.ImportTimeout = 300;
5. Test Connections Before Operations
Use the GetDatabaseInfo method on Manager to verify database connectivity:
var connection = new PostgreSqlDatasourceConnection
{
Hostname = "postgres.example.com",
Port = 5432,
Username = "postgres",
Password = "password",
Database = "mydb"
};
try
{
using (var manager = new Manager(connection))
{
var info = manager.GetDatabaseInfo();
Console.WriteLine($"Vendor: {info.Vendor}");
Console.WriteLine($"Name: {info.Name}");
Console.WriteLine($"Edition: {info.Edition}");
Console.WriteLine($"Version: {info.MajorVersion}.{info.MinorVersion}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
}
6. Prefer Strongly-Typed Properties Over String Parsing
When possible, use the strongly-typed properties for better type safety and compile-time checking. Universal settings like ImportTimeout and ImportBatchSize are available on all connection types:
// Preferred: Type-safe, compile-time checked
connection.ImportTimeout = 120;
connection.ImportBatchSize = 10000;
connection.DefaultSrid = 4326;
// Alternative: Useful when loading from configuration
connection.SetContextSettings("ImportTimeout=120;ImportBatchSize=10000;DefaultSrid=4326");
Disconnected Operations
For operations that don't require a database connection (reading and writing Schema files using ReadSchemaFromFile and WriteSchema), use the parameterless Manager constructor:
using (var manager = new Manager())
{
// Load schema from file without connecting to database
Schema schema = manager.ReadSchemaFromFile("schema.json", ConfigType.Json);
// Modify schema programmatically
schema.CreateTable("new_table").AddColumn("id", DataType.Long);
// Write back to file
manager.WriteSchema(schema, "modified_schema.json", ConfigType.Json);
}
Note: Attempting to perform connected operations (like LoadSchema, LoadDatabase, etc.) with a disconnected Manager will throw an exception.
Connection String vs DatasourceConnection Tradeoffs
Use DatasourceConnection When:
- Building new applications
- You want type safety and IntelliSense
- Connection parameters are constructed programmatically
- You need clear, self-documenting code
- Advanced validation is beneficial
Use Connection Strings When:
- Integrating with existing systems
- Connection strings are managed externally
- Working with configuration management systems
- You need maximum flexibility in connection parameters
- Migrating from legacy ADO.NET code
Both approaches are fully supported and provide identical functionality—choose based on your application architecture and requirements.
Summary
Velocity provides flexible connection mechanisms to suit different application architectures:
- DatasourceConnection objects offer type safety with strongly-typed properties (recommended for new development)
- Connection strings provide compatibility with existing configuration systems
- AdvancedSettings control ADO.NET provider behavior (passed to database connection string):
- Set via
SetAdvancedSettings()method - Map to database-specific connection string properties
- Reserved settings (
Pooling,ConnectTimeout, etc.) use named properties - Cannot override reserved settings via
SetAdvancedSettings() - Some databases expose common settings as strongly-typed properties
- Set via
- ContextSettings configure Velocity framework behavior (used by Velocity operations):
- Set via strongly-typed properties or
SetContextSettings()method - Control how Velocity executes operations (
CommandTimeout,ImportTimeout, etc.) - Universal settings work across all database types
- Applied to Velocity commands, not the connection itself
- Set via strongly-typed properties or
- Understand timeout types:
ConnectTimeout(AdvancedSetting) = time to establish connectionCommandTimeout(ContextSetting) = time for queries/DDL/DMLImportTimeout(ContextSetting) = time for bulk imports
- SSL/TLS and authentication (see Security: SSL/TLS and Authentication):
- Cross-platform PEM-file abstraction via
SslMode,SslCaPath,SslCertificatePath,SslKeyPath - Enterprise authentication via
UseIntegratedSecurity+ a database-specificAuthenticationMethodenum (DB2, SQL Server, Teradata) - For anything outside this model, drop down to a full connection string or
SetAdvancedSettings - OS trust stores, Kerberos infrastructure, Oracle wallets, GSKit keystores, and identity provider configuration are the implementer's responsibility, not Velocity's
- Cross-platform PEM-file abstraction via
- Always use
usingstatements for proper resource management - Store credentials securely outside source code
- Configure timeouts and batch sizes appropriate to your environment
- Prefer strongly-typed properties over string parsing when possible
By understanding the distinction between AdvancedSettings (connection behavior) and ContextSettings (framework behavior), you can build robust, secure, and performant database applications with Velocity.