A proposed standard database client interface and implementation for the D Language
Status: early stage project - unstable and minimally tested
Available in DUB, the D package registry
Add a dub.sdl file
name "demo"
libs "sqlite3"
dependency "dstddb" version="*"
versions "StdLoggerDisableLogging"
targetType "executable"
Add a simple example in src/demo.d
void main() {
import std.database.sqlite;
auto db = createDatabase("file:///testdb.sqlite");
auto con = db.connection;
con.query("drop table if exists score");
con.query("create table score(name varchar(10), score integer)");
con.query("insert into score values('Knuth',71)");
con.query("insert into score values('Dijkstra',82)");
con.query("insert into score values('Hopper',98)");
auto rows = con.query("select name,score from score").rows;
foreach (r; rows) writeln(r[0].as !string, ",", r[1].as !int);
}
Run it:
dub
- A database and driver neutral interface specification
- Reference counted value objects provide ease of use
- Templated implementations for Phobos compatibility
- Support for direct and polymorphic interfaces
- A range interface for query result sets
- Support a for fluent style interface
- URL style connection strings
- Reference implementations so far: ODBC, sqlite, mysql, oracle, postgres, freetds (MS SQL)
- Support for allocators
- Support for runtime driver registration
- Input variable binding support
- Array input/output binding support
- Connection pooling
import std.database.mysql;
auto db = createDatabase("mysql://database");
db.query("insert into table('name',123)");
import std.database.mysql;
auto db = createDatabase("mysql://127.0.0.1/test");
auto con = db.connection();
auto stmt = con.statement("select * from table");
auto rows = stmt.query.rows;
foreach (row; rows) {
for(size_t col = 0; col != row.width; ++col) write(row[col], " ");
writeln();
}
fluent style select
import std.database.sqlite;
createDatabase("file:///demo.sqlite")
.connection
.query("select * from t1")
.writeRows;
import std.database.sqlite;
auto db = createDatabase("file:///testdb");
auto rows = db.connection.query("select name,score from score").rows;
foreach (r; rows) {
writeln(r[0].as!string,",",r[1].as!int);
}
import std.database.sqlite;
int minScore = 50;
createDatabase("file:///demo.sqlite")
.connection
.query("select * from t1 where score >= ?", minScore)
.writeRows;
import std.database;
auto db = createDatabase("mydb");
auto con = db.connection();
auto stmt = con.statement("insert into table values(?,?)");
stmt.query("a",1);
stmt.query("b",2);
stmt.query("c",3);
import std.database.poly;
Database.register!(std.database.sqlite.Database)();
Database.register!(std.database.mysql.Database)();
Database.register!(std.database.oracle.Database)();
auto db = createDatabase("mydb");
- The reference implementations use logging (std.experimental.logger). To hide the info logging, add this line to your package.json file: "versions": ["StdLoggerDisableInfo"].
CPPSTDDB is a related project with similar objectives tailored to the constraints of the C++ language. The aim is for both projects to complement each other by proving the validity of specific design choices that apply to both and to draw on implementation correctness re-enforced from dual language development.