oracle-native 0.2.0: a native Oracle Database client in pure D
Vadim Lopatin
coolreader.org at gmail.com
Tue Nov 3 17:25:22 UTC 2026
I'd like to announce **oracle-native**, a client for Oracle
Database written entirely in D. It speaks Oracle's own network
protocols (Oracle Net / TNS and TTC) directly over TCP, so it
needs no Oracle Instant Client, no OCI, no ODBC and no C
libraries at build time. Version 0.2.0 is out. It adds the newer
types (JSON, VECTOR, BOOLEAN) to what 0.1.0 already had.
- Code: https://github.com/buggins/oracle-native
- Package: https://code.dlang.org/packages/oracle-native
```json
"dependencies": {
"oracle-native": "~>0.2.0"
}
```
```d
import oracle;
import std.stdio;
void main()
{
auto conn = new
Connection("oracle://scott:tiger@localhost:1521/FREEPDB1");
scope (exit) conn.close();
conn.exec("INSERT INTO notes VALUES (:1, :2)", 1, "first");
conn.commit();
foreach (row; conn.query("SELECT id, text FROM notes WHERE id
> :1", 0))
writeln(row.getLong(0), " ", row.getString(1));
}
```
**Features**
- Oracle Database 12.1 and newer, tested on 23ai Free, 21c XE and
18c XE.
- Password logins (11g and 12c verifiers), TLS with certificate
verification, failover over several addresses. Addresses can be
`oracle://` URLs, Easy Connect strings or connect descriptors.
- Bind variables (`:1`, `:name` or `?`) and a statement cache.
Also array DML with batch errors, PL/SQL OUT and IN OUT
parameters, `RETURNING INTO`, implicit results, REF cursors,
cancelling from another thread or task, and transactions.
- The common types, read and written exactly:
- `NUMBER` as exact decimals, `BINARY_FLOAT`/`BINARY_DOUBLE`,
`VARCHAR2`/`NVARCHAR2`, `RAW`;
- `DATE`, and `TIMESTAMP` with nanoseconds and time zones
(offsets and named regions);
- intervals, `ROWID`, `LONG`;
- LOBs (`CLOB`, `NCLOB`, `BLOB`, `BFILE`), either as values or
as locators.
- New in 0.2.0:
- **JSON** columns (21c and newer). The client decodes Oracle's
binary JSON format (OSON) itself. `getString` gives the same text
as the server's `JSON_SERIALIZE`; `getJson` gives a `std.json`
value.
- **VECTOR** columns and parameters (23ai). FLOAT32, FLOAT64,
INT8 and BINARY vectors, dense or sparse. `float[]` and
`double[]` parameters are sent as vectors, so `VECTOR_DISTANCE`
queries work with plain D arrays.
- Native **BOOLEAN** columns and parameters (23ai), PL/SQL
`BOOLEAN` parameters included. Older servers get `NUMBER` 1/0.
- End-to-end attributes for monitoring (module, action, client
identifier, client info), and the 23ai column metadata (SQL
domains, annotations).
- A connection pool and struct mapping (`query!T`,
`queryValue!T`, `insert`).
- Works in ordinary threads and in vibe.d tasks (vibe-core 1.22
to 2.x); in a task, waiting for the server suspends only that
task.
- D frontend 2.097 and newer (DMD 2.097+, LDC 1.27+), on Linux,
Windows and macOS.
**ddbc driver**
[ddbc](https://github.com/buggins/ddbc) 0.10.0 has a driver built
on oracle-native: use the `ORACLE` configuration and `oracle://`
URLs. It provides all getters and setters (exact decimals),
result set metadata and prepared statements with `?`
placeholders. `executeUpdate(sql, insertId)` returns the value of
a `RETURNING id INTO ?` clause. Auto-commit and the isolation
levels work too.
```json
"dependencies": {
"ddbc": "~>0.10.0"
},
"subConfigurations": {
"ddbc": "ORACLE"
}
```
```d
import ddbc;
import std.stdio;
auto conn =
createConnection("ddbc:oracle://localhost:1521/FREEPDB1?user=scott,password=tiger");
auto stmt = conn.createStatement();
auto rs = stmt.executeQuery("SELECT id, text FROM notes");
while (rs.next())
writeln(rs.getLong(1), " ", rs.getString(2));
```
**Not yet supported:** Native Network Encryption (servers that
require it are refused with a clear error; use TLS instead),
`tnsnames.ora` aliases and wallets, proxy authentication, and
pipelining. A hibernated dialect is planned next.
oracle-native shares its building blocks with clickhoused and
mssql-native through [dbwire](https://github.com/buggins/dbwire):
the thread and fiber I/O layer, TLS with OpenSSL loaded at run
time, the cryptography for the password exchange, and exact
decimals.
This is an unofficial project, not affiliated with Oracle. Oracle
has not published a specification of its network protocol.
oracle-native was written from the observable behaviour of real
servers and from facts documented by open-source clients, without
copying their code.
Bug reports and feedback are welcome on GitHub.
More information about the Digitalmars-d-announce
mailing list