Connection
Field Manual Section 3 - Supply Lines
Welcome to the armored convoy, commander. Before you can unleash Tank's firepower, you have to secure your supply lines. Open a Connection to your database, and when the mission escalates, lock operations inside a Transaction. No connection, no combat. It's that simple.
Operations Briefing
prepare("SELECT..."): Compile a raw SQL string into a reusableQuery<Driver>object without firing it. Use when the same statement will be dispatched multiple times.run(query): StreamsQueryResultitems (RoworAffected). Useful for multi‑statement batches (if supported by the database driver).fetch(query): Streams onlyQueryResult::Row, discardingQueryResult::Affected.execute(query): Aggregates allQueryResult::Affectedcounts into oneRowsAffected. Rows are ignored.append(query): Bulk insert entities, using driver fast‑path when available.begin(): Borrow the connection and start a transaction. Issue any of the above operations against the transactional executor, thencommitorrollback. Uncommitted drop triggers a rollback and gives back the connection.
Connection Lifecycle
- Establish: Call
driver.connect("dbms://...").await?with your database URL. - Deploy: Use the connection for queries, inserts, updates, and deletes.
- Lock (optional): Start a transaction with
connection.begin().await?, this borrows the connection. All operations route through the transactional executor untilcommit()orrollback(). - Maintain: Current drivers expose a single underlying session (DuckDB shares process instance; Postgres spawns one async connection; SQLite opens one handle).
- Terminate: Connections close automatically when dropped. Disconnection is ensured after a call to
disconnect().await.
Connect
Every database connection abstraction implements the Connection trait. This is your communication link to the database server. Call driver.connect("dbms://...") with a URL to let Tank establish the line. Every driver is its own crate. Load only what you need for the operation. Check the drivers to see the available connections.
Once the line is open, the connection exposes both the Connection and Executor interfaces, enabling you to prepare statements, run multiple queries, execute commands, fetch rows and orchestrate transactions.
Postgres
Postgres is your heavy artillery: powerful, networked, built for sustained campaigns with multiple units coordinating strikes.
use tank::Driver;
use tank_postgres::{PostgresConnection, PostgresDriver};
async fn establish_postgres_connection() -> Result<PostgresConnection> {
let driver = PostgresDriver::new();
let connection = driver
.connect("postgres://tank-user:armored@127.0.0.1:32790/military?sslmode=require&sslrootcert=ROOT_PATH&sslcert=CERT_PATH&sslkey=KEY_PATH".into())
.await?;
Ok(connection)
}URL Format:
postgres://user:pass@host:5432/database
Parameters:
sslmode: How a secure SSL TCP/IP connection will be negotiated with the server. Falls back to the environment variablePGSSLMODE, otherwisedisable. This parameter is passed totokio_postgres, for this reason only the following alternatives are supported (even though Postgres supports more modes):disablepreferrequire
sslrootcert: CA certificate path (falls back to environment variablePGSSLROOTCERTor~/.postgresql/root.crt).sslcert: Client certificate path (falls back to environment variablePGSSLCERTor~/.postgresql/postgresql.crt).sslkey: Client private key path (falls back to environment variablePGSSLKEYor~/.postgresql/postgresql.key).
SQLite
SQLite is the lone wolf operative, deep behind enemy lines: lightweight, reliable, zero configuration. Deploy anywhere, anytime.
use tank::Driver;
use tank_sqlite::{SQLiteConnection, SQLiteDriver};
async fn establish_sqlite_connection() -> Result<SQLiteConnection> {
let driver = SQLiteDriver::new();
let connection = driver
.connect("sqlite://../target/database.sqlite?mode=rwc".into())
.await?;
Ok(connection)
}URL Format:
- File:
sqlite://path/to/database.sqlite?mode=rwc - Memory:
sqlite://:memory:orsqlite://database?mode=memory
Modes:
mode=ro: read-only access (fails if the file doesn’t exist)mode=rw: read-write access (fails if the file doesn’t exist)mode=rwc: read-write access (creates the file if it doesn’t exist)mode=memory: in-memory access (temporary database that lives only for the duration of the connection)
Additional URL parameters are passed directly to the SQLite API. See the full list of supported options on the SQLite website.
MySQL/MariaDB
MySQL is the battle-hardened workhorse of the digital front: widely deployed, solid transactional engine, broad tooling ecosystem.
use tank::Driver;
use tank_mysql::{MySQLConnection, MySQLDriver};
async fn establish_mysql_connection() -> Result<MySQLConnection> {
let driver = MySQLDriver::new();
let connection = driver
.connect("mysql://tank-mysql-user@localhost:33231/operations_db?require_ssl=true&ssl_ca=/home/user/Git/tank/tank-mysql/tests/assets/ca.pem&ssl_cert=/home/user/Git/tank/tank-mysql/tests/assets/client.p12&ssl_pass=my%26pass%3Fis%3DP%40%24%24".into())
.await?;
Ok(connection)
}URL Format:
mysql://user@host:port/database?require_ssl=true&ssl_ca=CA_PATH&ssl_cert=CERT_PATH&ssl_pass=CERT_PASS
Parameters:
require_ssl (bool): Require secure connection, defaults to false.ssl_ca: CA certificate path (falls back to environment variableMYSQL_SSL_CA).ssl_cert: Client certificate path (falls back to environment variableMYSQL_SSL_CERT).
Additional URL parameters are passed directly to the mysql_async API. See the full list of supported options from options structure Opts.
DuckDB
DuckDB is your embedded artillery piece: fast, local, and always ready. Perfect for rapid deployment scenarios and testing under fire.
use tank::Driver;
use tank_duckdb::{DuckDBConnection, DuckDBDriver};
async fn establish_duckdb_connection() -> Result<DuckDBConnection> {
let driver = DuckDBDriver::new();
let connection = driver
.connect("duckdb://../target/debug/database.duckdb?mode=rw".into())
.await?;
Ok(connection)
}URL Format:
- File:
duckdb://path/to/database.duckdb?mode=rw - Memory:
duckdb://:memory:orduckdb://database?mode=memory
Modes:
mode=ro: read-only access (fails if the file doesn’t exist)mode=rw: read-write access (creates the file if it doesn’t exist)mode=rwc: alias forrwmode=memory: in-memory access (temporary database that lives only for the duration of the connection)
The mode parameter provides a common syntax for specifying connection access, similar to SQLite. The values map respectively to access_mode=READ_ONLY, access_mode=READ_WRITE, access_mode=READ_WRITE and the special duckdb://:memory: path. Additional URL parameters are passed directly to the DuckDB C API. See the full list of supported options on the DuckDB website.
MongoDB
MongoDB is your Guerrilla special forces unit operating in the "fog of war" gathering intel in whatever format it arrives.
use tank::Driver;
use tank_mongodb::{MongoDBConnection, MongoDBDriver};
async fn establish_mongodb_connection() -> Result<MongoDBConnection> {
let driver = MongoDBDriver::new();
let connection = driver
.connect("mongodb://127.0.0.1:27017/database".into())
.await?;
Ok(connection)
}ScyllaDB/Cassandra
ScyllaDB is the rapid‑response strike force: distributed, built to swarm data with relentless, low‑latency fire.
use tank::Driver;
use tank_scylladb::{ScyllaDBConnection, ScyllaDBDriver};
async fn establish_scylla_connection() -> Result<ScyllaDBConnection> {
let driver = ScyllaDBDriver::new();
let connection = driver
.connect("scylladb://127.0.0.1:9042/keyspace".into())
.await?;
Ok(connection)
}URL Format:
scylla://host1,host2:9042/keyspace?consistency=quorum&compression=Lz4
Parameters:
consistency: Query consistency level (examples:one,quorum,all).timeout_ms: Request timeout in milliseconds.
Lock, commit, advance. Dismissed.