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