Skip to main content

Crate rsfbclient

Crate rsfbclient 

Source
Expand description

Rust Firebird Client

§How to use it

§1. Start by choosing the lib variation you want

// To use the offcial ('native') Firebird client .dll/.so/.dylib
// (needs to find dll at build time)
rsfbclient::builder_native().with_dyn_link()
// Or using dynamic loading
rsfbclient::builder_native().with_dyn_load("/my/firebird/here/lib/libfbclient.so")
// Or using the pure rust implementation
rsfbclient::builder_pure_rust()

§2. Set your connection params

// For a remote server, using a dynamically linked native client
let mut conn = rsfbclient::builder_native()
    .with_dyn_link()
    .with_remote()
    .host("my.host.com.br")
    .db_name("awesome.fdb")
    .connect()?
// Or if you need a embedded/local only access
let mut conn = rsfbclient::builder_native()
    .with_dyn_link()
    .with_embedded()
    .db_name("/path/to/awesome.fdb")
    .connect()?

You also can choose a string connection configuration

// Using the native Firebird client
rsfbclient::builder_native()
    .from_string("firebird://SYSDBA:masterkey@my.host.com.br:3050/awesome.fdb?charset=ascii")
// Or using the pure rust implementation
rsfbclient::builder_pure_rust()
    .from_string("firebird://SYSDBA:masterkey@my.host.com.br:3050/awesome.fdb?charset=ascii")

§3. Now you can use the lib

let rows = conn.query_iter("select col_a, col_b, col_c from test", ())?;
...

§Simple Connection/Transaction

Sometimes you will need store the Connection and Transaction types into a struct field without care about Firebird Client variation. To do this, you can use the SimpleConnection and SimpleTransaction types.

To use, you only need use the From trait, calling the into() method. Example:

let mut conn: SimpleConnection = rsfbclient::builder_native()
    .with_dyn_link()
    .with_remote()
    .host("my.host.com.br")
    .db_name("awesome.fdb")
    .connect()?
    .into();

§Services API

With the native client (linking or dynamic_loading features) the services module can attach to a server’s service manager — the administration channel that gbak and the other command-line tools use — to query the server version and run backups and restores, with the verbose gbak log streamed back line by line while the action runs:

use rsfbclient::services::{ServiceManager, SvcBackupOptions};

let mut svc = ServiceManager::builder()
    .host("localhost")
    .user("SYSDBA")
    .pass("masterkey")
    .attach()?;
println!("{}", svc.server_version()?);
svc.backup_with_output("/data/db.fdb", "/data/db.fbk",
    SvcBackupOptions::default(), |line| println!("{}", line))?;

All paths given to service actions are server paths: the backup file is written on the server, by the server. The pure-rust wire implementation does not carry the service protocol, so this module needs one of the native features.

§Transactions

Every Connection keeps one default transaction, started lazily by the first query/execute call with the configuration given at connect time (the builder’s transaction(...)/with_transaction(...) options; the defaults are ReadCommited + record version, Wait without timeout, read-write). Outside of an explicit begin_transaction, every statement is committed automatically.

Two properties of the default transaction are worth knowing:

  • Connection::commit and Connection::rollback are retaining operations: they end the current unit of work but keep the same physical transaction alive. Its configuration — and, for TrIsolationLevel::Concurrency (SNAPSHOT), the snapshot it started with — persists for the whole life of the connection.
  • Because the physical transaction is reused, begin_transaction_config only applies its configuration if the default transaction has not started yet (i.e. before the first statement on the connection).

When you need a transaction with its own isolation level, lock policy or lifetime — e.g. a SNAPSHOT reader beside a NO WAIT writer — create an explicit transaction object: Transaction for a typed connection, or SimpleTransaction for a SimpleConnection. Explicit objects take a TransactionConfiguration and offer a real, consuming commit()/rollback() (plus _retaining variants):

let snapshot = TransactionConfiguration {
    isolation: TrIsolationLevel::Concurrency,
    lock_resolution: TrLockResolution::NoWait,
    ..TransactionConfiguration::default()
};
let mut tr = SimpleTransaction::new(&mut conn, snapshot)?;
tr.execute("update accounts set balance = balance + 1 where id = 1", ())?;
tr.commit()?; // consuming: this transaction really ends here

See examples/isolation_levels.rs for the full demonstration (snapshot visibility and NO WAIT update conflicts, live).

§Data type mappings

Column values arrive through SqlType, which is deliberately coarse. The supported mappings:

Firebird typeRust type
SMALLINT, INTEGER, BIGINTi64 (or any smaller integer type via try_into)
FLOAT, DOUBLE PRECISION, NUMERIC, DECIMALf64 / f32
CHAR, VARCHARString (decoded with the connection charset)
BLOB SUB_TYPE TEXTString
BLOB SUB_TYPE BINARYVec<u8>
DATE, TIME, TIMESTAMPchrono::NaiveDate / NaiveTime / NaiveDateTime
BOOLEANbool (Firebird 3+)
any nullable columnOption<T>

The sharp edges:

  • NUMERIC/DECIMAL go through f64: scaled values whose integer form exceeds 2^53 lose precision silently (e.g. NUMERIC(18,2) storing 90071992547409.93 reads back as 90071992547409.92). When the exact digits matter, CAST the column to VARCHAR in SQL and parse, or keep the value in a wider text/integer form.
  • Firebird 4+ types are not supported by the row reader: selecting an INT128, DECFLOAT(16/34), TIMESTAMP WITH TIME ZONE or TIME WITH TIME ZONE column (or a blob with sub_type > 1) fails at describe time with “Unsupported column type”. CAST such columns to VARCHAR/BIGINT/plain TIMESTAMP in the SQL to move the conversion server-side.

See examples/type_mapping.rs for all of the above, live.

§Cargo features

All features can be used at the same time if needed.

§linking

Will use the dynamic library of the official fbclient at runtime and compiletime. Used in systems where there is already a firebird client installed and configured.

§dynamic_loading

Can find the official fbclient native library by path at runtime, does not need the library at compiletime. Useful when you need to build in a system without a firebird client installed.

§pure_rust

Uses a pure rust implementation of the firebird wire protocol, does not need the native library at all. Useful for cross-compilation and allow a single binary to be deployed without needing to install the firebird client.

Modules§

builders
prelude
services
Firebird Services API: server-side administration through the service_mgr endpoint — the same channel the gbak and fbtracemgr tools use.

Structs§

Column
Connection
A connection to a firebird database
ConnectionConfiguration
Generic aggregate of configuration data for firebird db Connections The data required for forming connections is partly client-implementation-dependent
NativeConnectionBuilder
A builder for a client using the official (‘native’) Firebird dll.
PureRustConnectionBuilder
A builder for a firebird client implemented in pure rust. Does not currently support embedded connections.
Row
A database row
SimpleConnection
A connection API without client types
SimpleTransaction
A transaction API without client types
Statement
Transaction

Enums§

Dialect
Firebird sql dialect
EngineVersion
FbError
ParamsType
Parameters type
SqlType
Sql parameter / column data

Traits§

ColumnToVal
Define the conversion from the buffer to a value
Execute
Implemented for types that can be used to execute sql statements
FirebirdClientFactory
A generic factory for creating multiple preconfigured instances of a particular client implementation Intended mainly for use by connection pool
FromRow
Implemented for types that represents a list of values of columns
IntoParam
Implemented for types that can be sent as parameters
IntoParams
Types with an associated boolean flag function, named() indiciating support for named or positional parameters.
Queryable
Implemented for types that can be used to execute sql queries
RemoteEventsManager
Firebird remote events manager
SystemInfos
Infos about the server, database, engine…

Functions§

builder_native
Get a new instance of NativeConnectionBuilder
builder_pure_rust
Get a new instance of PureRustConnectionBuilder

Type Aliases§

DynByString