SlideShare a Scribd company logo
1 of 61
Download to read offline
s t d . d a t a b a s e
( a p ro p o s e d i n t e r f a c e & i m p l e m e n t a t i o n )
D C O N F 2 0 1 6
Erik Smith
T H E R E L AT I O N A L M O D E L
P E R S O N
I D
I N T
L A S T _ N A M E
VA R C H A R ( 3 0 )
F I R S T _ N A M E
VA R C H A R ( 3 0 )
B I R T H D AT E
D AT E
1 Yo k o m o t o A k i k o 1 9 9 0 - 0 5 - 0 3
2 G re e n M a r j o r i e 1 9 7 2 - 0 2 - 0 6
3 H o ff m a n P a u l 1 9 9 5 - 0 7 - 0 1
SQL query
columns
select last_name from person
where birthdate <“1991-01-01”
Table
rows
T H E C L I E N T S TA C K
std.database
client
C client libraries
Driver Layer
TCP
sockets
Front Layer
Application
Code
DB
Utilities
ORM
libraries
Application Code
Query
Builder
std.eventvibe.d
T H E T Y P E S
Database top level context (shared)
Connection connection to server (per thread)
Statement
query execution, prepared statements, input
binding
ColumnSet Column container, input-range
Column meta data for result column
RowSet RowContainer, input-range
Row row accessor
Field field accessor, type conversion.
E X A M P L E
no explicit types
import std.database.mysql;
auto db = createDatabase("mysql://server/db");
db
.query("select * from person”)
.rows
.writeRows;
E X A M P L E I N E X PA N D E D F O R M
auto db = createDatabase("mysql://server/db");
auto con = db.connection;
auto stmt = con.statement("select * from person“);
auto rows = stmt.query.rows;
foreach (row; rows) {
for(int c = 0; c != row.width; c++) {
auto field = row[c];
writeln(“value: “, field);
}
writeln;
}
E X A M P L E U S I N G C O L U M N
auto db = createDatabase("mysql://server/db");
auto con = db.connection;
auto stmt = con.statement("select * from person");
auto rows = stmt.query.rows;
foreach (row; rows) {
foreach (column; columns) {
auto field = row[column];
writeln("name: ", column.name, ", value: “, field);
}
writeln;
}
R E F E R E N C E T Y P E S
auto getCustomers(string zip) {
auto db = createDatabase(“mysql://server/db”)
db
.query(“select from person where name=?“, zip)
.rows;
}
auto localCustomers = getCustomers(“92122”);
D ATA B A S E
auto db = createDatabase;
auto db = createDatabase(“mysql://server/db"); // default URI
auto con = database.connection; // uses default URI
auto con = database.connection(“mysql://server2/db”); // specific URI
auto con = database.connection(“server”); // named source
auto con = database.createConnection; // new connection
auto con = database.createConnection(“mysql://server2/db”);
db.query(“insert into person values(1, ‘joe’);
connection: returns same connection per thread
createConnection: new connection for same thread
C O N N E C T I O N S T R I N G
db.connection(“mysql://server/db?username=app”)
db.connection(“mysql”) "databases": [
{
"name": "mysql",
"type": "mysql",
"server": "127.0.0.1",
"database": "test",
"username": "",
"password": ""
},
Custom Resolver
URI based string
Named source
config file
C O N N E C T I O N
auto db = connection.database; // parent
connection.autoCommit(false); // for transactions
connection.begin;
connection.save;
connection.commit;
connection.rollback;
connection.isolationLevel;
T R A N S A C T I O N S A N D S C O P E
auto con1 = db.connection("server1").autoCommit(false);
auto con2 = db.connection("server2").autoCommit(false);
scope(failure) con1.rollback;
scope(failure) con2.rollback;
con1.begin.query("insert into account(id,amount) values(1,-500000)”);
con2.begin.query("insert into account(id,amount) values(2, 500000)");
con1.commit;
con2.commit;
S TAT E M E N T
auto stmt = con
.query(“insert into person(id, name) values(?,?)“);
stmt.query(1,”Doug”);
stmt.query(2,”Cathy”);
stmt.query(3,”Robert”);
Prepared Query / Input Binding
S TAT E M E N T
stmt.rows // a RowSet
stmt.results // a range of RowSets
stmt.into
F L E X I B L E
db.query("select * from t”)
db.connection.query(“select * from t”)
db.connection.statement(“select * from t”).query
db.connection.statement(“select * from t”).rows
these are equivalent
hard to get wrong
R O W S E T
row.width // number of columns in row set
row.columns // range of Columns
row.length // number of results (if materialized)
bool empty()
Row front()
void popFront()
a RowSet is an InputRange
R O W
auto field = row[0]; // by column index
auto field = row[“FIRST_NAME”]; // by column name
auto field = row[“first_name”]; // case insensitive
auto field = row[column]; // by column
F I E L D
field.toString
field.as!T // type T
field.as!int // int
field.as!long // long
field.as!string // string
field.as!Date // as std.datetime.Date
field.as!Variant // as std.variant.Variant (nothrow)
field.get // as Nullable!T (nothrow)
field.option // as Option!T (nothrow)
F I E L D A C C E S S O R S
field.isNull // is the value null
field.name // name of column
field.type // type enumeration
S I N G L E R O W Q U E R I E S W I T H i n t o
string a;
int b;
Date d;
Variant d;
db
.query("select a,b,c,d from table”)
.into(a,b,c,d);
R O W I N D E X I N G
auto field = row[“name”]; // easy but less efficient
auto field = row[1]; // efficient but less readable
M I X I N H E L P
mixin(rows.scatterColumns);
foreach(row; rows) {
auto id = row[lastNameIndex];
auto name = row[idIndex];
}
auto idIndex = rows.columns[“id”];
auto nameIndex = rows.columns[“last_name”];
mixin expansion
R O W L E V E L i n t o
auto rows =
.query(“select id.name from person”)
.rows;
int id;
string name;
foreach (row; rows) row.into(id, name);
M O R E I N T O
query.into(range); // output-range
query.into(myStruct); // serialization
// with UFCS
P O LY M O R P H I C I N T E R FA C E
import std.database.mysql;
auto db = createDatabase;
auto con = db.connection("mysql://server/db");
Direct Interface
import std.database;
auto db = createDatabase;
auto con1 = db.connection(“mysql://server/db");
auto con2 = db.connection(“sqlite://file.sqlite”);
Poly Interface
P O LY: A D D I N G D R I V E R S
import std.database;
Database.register!(std.database.sqlite.Database)();
Database.register!(std.database.mysql.Database)();
Database.register!(std.database.oracle.Database)();
H A N D L E A C C E S S O R S
auto con = db.connection;
auto mysql = connection.handle; // typed as MYSQL*
auto mysql = db.connection.handle; // lifetime fail
T E S T S U I T E
• Templated test framework
• Runs test twice: once direct, ones through poly
driver
• Runs carefully in sandbox database
import std.database.mysql;
import std.database.testsuite;
alias DB = Database!DefaultPolicy;
testAll!DB("mysql");
O U T P U T B I N D I N G
• A C level buffer interface
• RowSet handles internally
I D N A M E
2 J O E
A R R AY O U T P U T B I N D I N G
203 ms
1000 row table
A
I N T
B
I N T
0 1
1 2
2 3
… …
9 9 9 1 0 0 0
auto rs = con
.query("select * from t1");
int sum;
foreach(r;rs)
sum += r[0].as!int + r[1].as!int;
A R R AY O U T P U T B I N D I N G
1000 row table
A
I N T
B
I N T
0 1
1 2
2 3
… …
9 9 9 1 0 0 0
auto rs = con
.rowArraySize(100)
.query("select * from t1");
int sum;
foreach(r;rs)
sum += r[0].as!int + r[1].as!int;
32 ms
A R R AY O U T P U T B I N D I N G
2 ms
1000 row table
A
I N T
B
I N T
0 1
1 2
2 3
… …
9 9 9 1 0 0 0
auto rs = con
.rowArraySize(500)
.query("select * from t1");
int sum;
foreach(r;rs)
sum += r[0].as!int + r[1].as!int;
A R R AY O U T P U T B I N D I N G
601 µs
2M rows / sec
400X improvement
auto rs = con
.rowArraySize(1000)
.query("select * from t1");
int sum;
foreach(r;rs)
sum += r[0].as!int + r[1].as!int;
S K I P PA R A M E T E R S
• Optional driver level binding mode that “stripes” bind
arrays into contiguous memory
D E TA C H E D R O W S E T S
• RowSet is detachable when all rows are resident
• Detachable RowSets detach from connection
• RowSet upgraded to random-access-range
• No additional copying
• RowSet caching enabler
I N P U T B I N D I N G / P R E PA R E D Q U E RY
auto db = createDatabase(“mysql://server/db”)
auto stmt = db
.query(“insert into table(id, name) values(?,?)”);
foreach(d; data) stmt.query(d.id, d.name);
I N P U T A R R AY B I N D I N G
auto db = createDatabase(“mysql://server/db”)
auto stmt = db
.rowArraySize(1000)
.query(“insert into table(id, name) values(?,?)”);
foreach(d; data) stmt.query(d.id, d.name);
huge performance win
T Y P E C O N V E R S I O N
• Two layers (driver & front end)
• Native driver binding is default
P O L I C I E S
• Custom allocators
• Pluggable connection pool
• assert on release build for cross/illegal type conversions
• Scoped types (no RC)
• Omit handle accessors
struct MyPolicy {…}
auto db = Database!MyPolicy;
auto inventory = db.createConnection
.query(“select id,* inventory”).rows;
auto orders = db.createConnection
.query("select * from orders order by id”).rows;
auto parts = db.createConnection
.query("select * from parts order by id”).rows;
auto joinedRows = naturalJoin(inventory, orders, parts);
foreach(r; joinedRows) {
int id, orderId, PartId;
inventory.into(id,...);
orders.into(orderId,...);
parts.into(partId,...);
}
U T I L I T Y E X A M P L E : J O I N
inventory
orders
parts
1-n
1-n
an approach to the “multiple hierarchies” problem
I M P L E M E N TAT I O N D E TA I L S
T W O L AY E R D E S I G N
• Handles reference counting details for all types
• Defines all interface functions
• Consolidates calls to the driver
• Manages state
• Connection pooling
Front End
•
Driver
• Implement driver specific details
D R I V E R I N T E R FA C E
module std.database.mysql.database;
alias Database(Policy) = BasicDatabase!(Driver!Policy,Policy);
auto createDatabase()() {return Database!DefaultPolicy();}
struct Driver(Policy) {
struct Database {…}
struct Connection {…}
struct Statement {…}
struct Result {…}
}
Type name correspondence
between layers
D R I V E R I N T E R FA C E
struct Driver(Policy) {
struct Database {…}
struct Connection {
this(Database *db, Source src, Allocator *a) {…}
}
struct Statement {
this(Connection *con, string sql, Allocator *a) {…}
}
struct Result {
this(Statement *stmt, Allocator *a) {…}
}
}
P O LY D R I V E R : V TA B L E
struct StmtVTable {
void[] function(void*, string sql) create;
void function(void*) destroy;
void function(void* stmt) query;
}
struct StmtGenerate(Driver) {
static auto create(void* con, string sql) {...}
static void destroy(void* stmt) {...}
static void query(void* stmt) {toTypedPtr!Statement(stmt).query;}
}
table = StmtGenerate!Driver.vtable;
void* stmt;
void query() {vtable.query(stmt);}
P O LY D R I V E R : VA R I A D I C Q U E RY D I S PAT C H
struct Statement {
void* stmt;
StmtVtable* vtable;
this(Connection* con, string sql) {...}
void query() {
vtable.query(stmt, args);
}
void query(A...) (A args) {
vtable.query(stmt, args);
}
}
problem
prepared version
C H A L L E N G E
Need to transport arguments from one
templates query call to another at run time
Run time Compile Time
C H A L L E N G E # 2
Avoid requiring the drivers to
handle Variant arguments
A P P R O A C H
V ! s t r i n g V ! i n t V ! D a t e
(V!string,V!int,V!Date)
stmt.query(“joe”, Date(2015,2,1), 42)Front End
Driver
Array!V
alias V = Variant;
callVariadic
unpackVariants (string,int,Date)
stmt.query(“joe”, Date(2015,2,1), 42)
PA C K I N T O VA R I A N T A R R AY
void query(A...) (A args) {
auto a = Array!Variant(args);
bindArgs.reserve(a.length);
foreach(arg; args) a ~= Variant(arg);
driver.stmtVtable.variadicQuery(stmt, a);
}
static void variadicQuery(void[] stmt, ref BindArgs a) {
auto s = toTypedPtr!Statement(stmt);
callVariadic!F(a, s);
}
A R R AY T O VA R I A D I C C A L L
static void callVariadic(alias F,S,A...) (ref S s, A a) {
switch (s.length) {
case 0: break;
case 1: F(a,s[0]); break;
case 2: F(a,s[0],s[1]); break;
case 3: F(a,s[0],s[1],s[2]); break;
case 4: F(a,s[0],s[1],s[2],s[3]); break;
case 5: F(a,s[0],s[1],s[2],s[3],s[4]); break;
default: throw new Exception(“arg overload");
}
}
U N PA C K VA R I A N T S
static void unpackVariants(alias F, int i=0, A...)(A a) {
alias Types = AliasSeq!(byte, ubyte, string, char, dchar, int, uint, long, ulong, Date);
static void call(int i, T, A...)(T v, A a) {
unpackVariants!(F,i+1)(a[0..i], v, a[(i+1)..$]);
}
static if (i == a.length) {
F(a);
} else {
foreach(T; Types) {
if (a[i].convertsTo!T) {
call!i(a[i].get!T,a);
return;
}
}
throw new Exception("unknown type: " ~ a[i].type.toString);
}
}
i n t i n t V ! D a t e
i
a[0..i] v a[(i+1)..$]
R E A L I T Y C H E C K
P(10,5) = 30240
Drivers must implement an additional call
two options:
query(ref Array!Variant args)
query(Args..)(A.. args) // accept variants
F i b e r b a s e d D r i v e r A p p ro a c h e s
1) Modify socket calls in driver source, if available, to
use a D (or vibe.d) non-blocking socket layer.
2) Implement from scratch a non-blocking driver using
a known wire protocol
3) Adapt an existing non-blocking interface for use
with vibe.d / std.event.
F I B E R A S Y N C Q U E RY E X A M P L E
auto descriptor = con.descriptor();
auto event = createFileDescriptorEvent(
descriptor, FileDescriptorEvent.Trigger.any);
nonBlockingQuery(sql);
while (true) {
if (poll) {
bool complete = readData;
if (complete) break;
}
event.wait(FileDescriptorEvent.Trigger.read);
}
}
vibe.d calls
async driver calls
N O N - B L O C K I N G M Y S Q L C L I E N T
“We're Gonna Need A Bigger Database”
S U P P O R T E D D ATA B A S E S
current support (WIP)
Up next
U P C O M I N G W O R K
• Fiber based drivers for Postgres & Webscalesql
• Asynchronous push models (Observables)
• Query builder
• Schema metadata
• Callable statements
• Blob support
• Operation timing
• Simulated binding (freetds)
• Quote escaping
• Expose more features of underlying drivers
• Multiple result support
• NoSql support
• Test suite improvement
• Utilities
• More…
G E T T I N G S TA R T E D ( O S X )
$ b re w i n s t a l l d m d d u b m y s q l
$ m k d i r - p ~ / s rc / d e m o & & c d ~ / s rc / d e m o
i m p o r t s t d . d a t a b a s e . m y s q l ;
i m p o r t s t d . d a t a b a s e . u t i l ;
v o i d m a i n ( ) {
a u t o d b = c re a t e D a t a b a s e ( " m y s q l : / / 1 2 7 . 0 . 0 . 1 / t e s t " ) ;
d b . q u e r y ( " s e l e c t * f ro m p e r s o n ” ) . ro w s . w r i t e R o w s ;
}
$ d u b
{
" n a m e " : " d e m o " ,
" l i b s " : [ " m y s q l c l i e n t " ] ,
" d e p e n d e n c i e s " : { " d s t d d b " : " * " } ,
" t a rg e t Ty p e " : “ e x e c u t a b l e ” ,
" v e r s i o n s " : [ “ S t d L o g g e r D i s a b l e L o g g i n g " ]
}
d u b . j s o n
d e m o . d
Q U E S T I O N S
https://github.com/cruisercoder/dstddb
DUB: dstddb

More Related Content

What's hot

Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...ssuserd6b1fd
 
Swift internals
Swift internalsSwift internals
Swift internalsJung Kim
 
Rootkit on Linux X86 v2.6
Rootkit on Linux X86 v2.6Rootkit on Linux X86 v2.6
Rootkit on Linux X86 v2.6fisher.w.y
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeGanesh Samarthyam
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийAndrey Akinshin
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointerLei Yu
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...ssuserd6b1fd
 
RxSwift 활용하기 - Let'Swift 2017
RxSwift 활용하기 - Let'Swift 2017RxSwift 활용하기 - Let'Swift 2017
RxSwift 활용하기 - Let'Swift 2017Wanbok Choi
 
Collection v3
Collection v3Collection v3
Collection v3Sunil OS
 

What's hot (20)

OpenXR 0.90 Overview Guide
OpenXR 0.90 Overview GuideOpenXR 0.90 Overview Guide
OpenXR 0.90 Overview Guide
 
OpenXR 1.0 Reference Guide
OpenXR 1.0 Reference GuideOpenXR 1.0 Reference Guide
OpenXR 1.0 Reference Guide
 
OpenGL ES 3.2 Reference Guide
OpenGL ES 3.2 Reference GuideOpenGL ES 3.2 Reference Guide
OpenGL ES 3.2 Reference Guide
 
Sql
SqlSql
Sql
 
c programming
c programmingc programming
c programming
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
 
OpenGL ES 3.1 Reference Card
OpenGL ES 3.1 Reference CardOpenGL ES 3.1 Reference Card
OpenGL ES 3.1 Reference Card
 
Swift internals
Swift internalsSwift internals
Swift internals
 
OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference GuideOpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
 
Rootkit on Linux X86 v2.6
Rootkit on Linux X86 v2.6Rootkit on Linux X86 v2.6
Rootkit on Linux X86 v2.6
 
C programs
C programsC programs
C programs
 
Why Learn Python?
Why Learn Python?Why Learn Python?
Why Learn Python?
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean Code
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложений
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointer
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
 
RxSwift 활용하기 - Let'Swift 2017
RxSwift 활용하기 - Let'Swift 2017RxSwift 활용하기 - Let'Swift 2017
RxSwift 활용하기 - Let'Swift 2017
 
Collection v3
Collection v3Collection v3
Collection v3
 
Sycl 1.2 Reference Card
Sycl 1.2 Reference CardSycl 1.2 Reference Card
Sycl 1.2 Reference Card
 

Similar to DConf 2016 std.database (a proposed interface & implementation)

Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212Mahmoud Samir Fayed
 
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDYDATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDYMalikireddy Bramhananda Reddy
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful weddingStéphane Wirtel
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloadingkinan keshkeh
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184Mahmoud Samir Fayed
 
Data Structure in C Programming Language
Data Structure in C Programming LanguageData Structure in C Programming Language
Data Structure in C Programming LanguageArkadeep Dey
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
CS 542 Database Index Structures
CS 542 Database Index StructuresCS 542 Database Index Structures
CS 542 Database Index StructuresJ Singh
 
Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6scuhurricane
 
Advanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsAdvanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsRobert Treat
 
Write a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfWrite a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfarchanaemporium
 

Similar to DConf 2016 std.database (a proposed interface & implementation) (20)

3 database-jdbc(1)
3 database-jdbc(1)3 database-jdbc(1)
3 database-jdbc(1)
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212
 
greenDAO
greenDAOgreenDAO
greenDAO
 
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDYDATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
C program
C programC program
C program
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
.net progrmming part2
.net progrmming part2.net progrmming part2
.net progrmming part2
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184
 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184
 
Data Structure in C Programming Language
Data Structure in C Programming LanguageData Structure in C Programming Language
Data Structure in C Programming Language
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
PostThis
PostThisPostThis
PostThis
 
CS 542 Database Index Structures
CS 542 Database Index StructuresCS 542 Database Index Structures
CS 542 Database Index Structures
 
Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6
 
Advanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsAdvanced Int->Bigint Conversions
Advanced Int->Bigint Conversions
 
Write a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfWrite a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdf
 

Recently uploaded

%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 

Recently uploaded (20)

%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

DConf 2016 std.database (a proposed interface & implementation)

  • 1. s t d . d a t a b a s e ( a p ro p o s e d i n t e r f a c e & i m p l e m e n t a t i o n ) D C O N F 2 0 1 6 Erik Smith
  • 2. T H E R E L AT I O N A L M O D E L P E R S O N I D I N T L A S T _ N A M E VA R C H A R ( 3 0 ) F I R S T _ N A M E VA R C H A R ( 3 0 ) B I R T H D AT E D AT E 1 Yo k o m o t o A k i k o 1 9 9 0 - 0 5 - 0 3 2 G re e n M a r j o r i e 1 9 7 2 - 0 2 - 0 6 3 H o ff m a n P a u l 1 9 9 5 - 0 7 - 0 1 SQL query columns select last_name from person where birthdate <“1991-01-01” Table rows
  • 3. T H E C L I E N T S TA C K std.database client C client libraries Driver Layer TCP sockets Front Layer Application Code DB Utilities ORM libraries Application Code Query Builder std.eventvibe.d
  • 4. T H E T Y P E S Database top level context (shared) Connection connection to server (per thread) Statement query execution, prepared statements, input binding ColumnSet Column container, input-range Column meta data for result column RowSet RowContainer, input-range Row row accessor Field field accessor, type conversion.
  • 5. E X A M P L E no explicit types import std.database.mysql; auto db = createDatabase("mysql://server/db"); db .query("select * from person”) .rows .writeRows;
  • 6. E X A M P L E I N E X PA N D E D F O R M auto db = createDatabase("mysql://server/db"); auto con = db.connection; auto stmt = con.statement("select * from person“); auto rows = stmt.query.rows; foreach (row; rows) { for(int c = 0; c != row.width; c++) { auto field = row[c]; writeln(“value: “, field); } writeln; }
  • 7. E X A M P L E U S I N G C O L U M N auto db = createDatabase("mysql://server/db"); auto con = db.connection; auto stmt = con.statement("select * from person"); auto rows = stmt.query.rows; foreach (row; rows) { foreach (column; columns) { auto field = row[column]; writeln("name: ", column.name, ", value: “, field); } writeln; }
  • 8. R E F E R E N C E T Y P E S auto getCustomers(string zip) { auto db = createDatabase(“mysql://server/db”) db .query(“select from person where name=?“, zip) .rows; } auto localCustomers = getCustomers(“92122”);
  • 9. D ATA B A S E auto db = createDatabase; auto db = createDatabase(“mysql://server/db"); // default URI auto con = database.connection; // uses default URI auto con = database.connection(“mysql://server2/db”); // specific URI auto con = database.connection(“server”); // named source auto con = database.createConnection; // new connection auto con = database.createConnection(“mysql://server2/db”); db.query(“insert into person values(1, ‘joe’); connection: returns same connection per thread createConnection: new connection for same thread
  • 10. C O N N E C T I O N S T R I N G db.connection(“mysql://server/db?username=app”) db.connection(“mysql”) "databases": [ { "name": "mysql", "type": "mysql", "server": "127.0.0.1", "database": "test", "username": "", "password": "" }, Custom Resolver URI based string Named source config file
  • 11. C O N N E C T I O N auto db = connection.database; // parent connection.autoCommit(false); // for transactions connection.begin; connection.save; connection.commit; connection.rollback; connection.isolationLevel;
  • 12. T R A N S A C T I O N S A N D S C O P E auto con1 = db.connection("server1").autoCommit(false); auto con2 = db.connection("server2").autoCommit(false); scope(failure) con1.rollback; scope(failure) con2.rollback; con1.begin.query("insert into account(id,amount) values(1,-500000)”); con2.begin.query("insert into account(id,amount) values(2, 500000)"); con1.commit; con2.commit;
  • 13. S TAT E M E N T auto stmt = con .query(“insert into person(id, name) values(?,?)“); stmt.query(1,”Doug”); stmt.query(2,”Cathy”); stmt.query(3,”Robert”); Prepared Query / Input Binding
  • 14. S TAT E M E N T stmt.rows // a RowSet stmt.results // a range of RowSets stmt.into
  • 15. F L E X I B L E db.query("select * from t”) db.connection.query(“select * from t”) db.connection.statement(“select * from t”).query db.connection.statement(“select * from t”).rows these are equivalent hard to get wrong
  • 16. R O W S E T row.width // number of columns in row set row.columns // range of Columns row.length // number of results (if materialized) bool empty() Row front() void popFront() a RowSet is an InputRange
  • 17. R O W auto field = row[0]; // by column index auto field = row[“FIRST_NAME”]; // by column name auto field = row[“first_name”]; // case insensitive auto field = row[column]; // by column
  • 18. F I E L D field.toString field.as!T // type T field.as!int // int field.as!long // long field.as!string // string field.as!Date // as std.datetime.Date field.as!Variant // as std.variant.Variant (nothrow) field.get // as Nullable!T (nothrow) field.option // as Option!T (nothrow)
  • 19. F I E L D A C C E S S O R S field.isNull // is the value null field.name // name of column field.type // type enumeration
  • 20. S I N G L E R O W Q U E R I E S W I T H i n t o string a; int b; Date d; Variant d; db .query("select a,b,c,d from table”) .into(a,b,c,d);
  • 21. R O W I N D E X I N G auto field = row[“name”]; // easy but less efficient auto field = row[1]; // efficient but less readable
  • 22. M I X I N H E L P mixin(rows.scatterColumns); foreach(row; rows) { auto id = row[lastNameIndex]; auto name = row[idIndex]; } auto idIndex = rows.columns[“id”]; auto nameIndex = rows.columns[“last_name”]; mixin expansion
  • 23. R O W L E V E L i n t o auto rows = .query(“select id.name from person”) .rows; int id; string name; foreach (row; rows) row.into(id, name);
  • 24. M O R E I N T O query.into(range); // output-range query.into(myStruct); // serialization // with UFCS
  • 25. P O LY M O R P H I C I N T E R FA C E import std.database.mysql; auto db = createDatabase; auto con = db.connection("mysql://server/db"); Direct Interface import std.database; auto db = createDatabase; auto con1 = db.connection(“mysql://server/db"); auto con2 = db.connection(“sqlite://file.sqlite”); Poly Interface
  • 26. P O LY: A D D I N G D R I V E R S import std.database; Database.register!(std.database.sqlite.Database)(); Database.register!(std.database.mysql.Database)(); Database.register!(std.database.oracle.Database)();
  • 27. H A N D L E A C C E S S O R S auto con = db.connection; auto mysql = connection.handle; // typed as MYSQL* auto mysql = db.connection.handle; // lifetime fail
  • 28. T E S T S U I T E • Templated test framework • Runs test twice: once direct, ones through poly driver • Runs carefully in sandbox database import std.database.mysql; import std.database.testsuite; alias DB = Database!DefaultPolicy; testAll!DB("mysql");
  • 29. O U T P U T B I N D I N G • A C level buffer interface • RowSet handles internally I D N A M E 2 J O E
  • 30. A R R AY O U T P U T B I N D I N G 203 ms 1000 row table A I N T B I N T 0 1 1 2 2 3 … … 9 9 9 1 0 0 0 auto rs = con .query("select * from t1"); int sum; foreach(r;rs) sum += r[0].as!int + r[1].as!int;
  • 31. A R R AY O U T P U T B I N D I N G 1000 row table A I N T B I N T 0 1 1 2 2 3 … … 9 9 9 1 0 0 0 auto rs = con .rowArraySize(100) .query("select * from t1"); int sum; foreach(r;rs) sum += r[0].as!int + r[1].as!int; 32 ms
  • 32. A R R AY O U T P U T B I N D I N G 2 ms 1000 row table A I N T B I N T 0 1 1 2 2 3 … … 9 9 9 1 0 0 0 auto rs = con .rowArraySize(500) .query("select * from t1"); int sum; foreach(r;rs) sum += r[0].as!int + r[1].as!int;
  • 33. A R R AY O U T P U T B I N D I N G 601 µs 2M rows / sec 400X improvement auto rs = con .rowArraySize(1000) .query("select * from t1"); int sum; foreach(r;rs) sum += r[0].as!int + r[1].as!int;
  • 34. S K I P PA R A M E T E R S • Optional driver level binding mode that “stripes” bind arrays into contiguous memory
  • 35. D E TA C H E D R O W S E T S • RowSet is detachable when all rows are resident • Detachable RowSets detach from connection • RowSet upgraded to random-access-range • No additional copying • RowSet caching enabler
  • 36. I N P U T B I N D I N G / P R E PA R E D Q U E RY auto db = createDatabase(“mysql://server/db”) auto stmt = db .query(“insert into table(id, name) values(?,?)”); foreach(d; data) stmt.query(d.id, d.name);
  • 37. I N P U T A R R AY B I N D I N G auto db = createDatabase(“mysql://server/db”) auto stmt = db .rowArraySize(1000) .query(“insert into table(id, name) values(?,?)”); foreach(d; data) stmt.query(d.id, d.name); huge performance win
  • 38. T Y P E C O N V E R S I O N • Two layers (driver & front end) • Native driver binding is default
  • 39. P O L I C I E S • Custom allocators • Pluggable connection pool • assert on release build for cross/illegal type conversions • Scoped types (no RC) • Omit handle accessors struct MyPolicy {…} auto db = Database!MyPolicy;
  • 40. auto inventory = db.createConnection .query(“select id,* inventory”).rows; auto orders = db.createConnection .query("select * from orders order by id”).rows; auto parts = db.createConnection .query("select * from parts order by id”).rows; auto joinedRows = naturalJoin(inventory, orders, parts); foreach(r; joinedRows) { int id, orderId, PartId; inventory.into(id,...); orders.into(orderId,...); parts.into(partId,...); } U T I L I T Y E X A M P L E : J O I N inventory orders parts 1-n 1-n an approach to the “multiple hierarchies” problem
  • 41. I M P L E M E N TAT I O N D E TA I L S
  • 42. T W O L AY E R D E S I G N • Handles reference counting details for all types • Defines all interface functions • Consolidates calls to the driver • Manages state • Connection pooling Front End • Driver • Implement driver specific details
  • 43. D R I V E R I N T E R FA C E module std.database.mysql.database; alias Database(Policy) = BasicDatabase!(Driver!Policy,Policy); auto createDatabase()() {return Database!DefaultPolicy();} struct Driver(Policy) { struct Database {…} struct Connection {…} struct Statement {…} struct Result {…} } Type name correspondence between layers
  • 44. D R I V E R I N T E R FA C E struct Driver(Policy) { struct Database {…} struct Connection { this(Database *db, Source src, Allocator *a) {…} } struct Statement { this(Connection *con, string sql, Allocator *a) {…} } struct Result { this(Statement *stmt, Allocator *a) {…} } }
  • 45. P O LY D R I V E R : V TA B L E struct StmtVTable { void[] function(void*, string sql) create; void function(void*) destroy; void function(void* stmt) query; } struct StmtGenerate(Driver) { static auto create(void* con, string sql) {...} static void destroy(void* stmt) {...} static void query(void* stmt) {toTypedPtr!Statement(stmt).query;} } table = StmtGenerate!Driver.vtable; void* stmt; void query() {vtable.query(stmt);}
  • 46. P O LY D R I V E R : VA R I A D I C Q U E RY D I S PAT C H struct Statement { void* stmt; StmtVtable* vtable; this(Connection* con, string sql) {...} void query() { vtable.query(stmt, args); } void query(A...) (A args) { vtable.query(stmt, args); } } problem prepared version
  • 47. C H A L L E N G E Need to transport arguments from one templates query call to another at run time Run time Compile Time
  • 48. C H A L L E N G E # 2 Avoid requiring the drivers to handle Variant arguments
  • 49. A P P R O A C H V ! s t r i n g V ! i n t V ! D a t e (V!string,V!int,V!Date) stmt.query(“joe”, Date(2015,2,1), 42)Front End Driver Array!V alias V = Variant; callVariadic unpackVariants (string,int,Date) stmt.query(“joe”, Date(2015,2,1), 42)
  • 50. PA C K I N T O VA R I A N T A R R AY void query(A...) (A args) { auto a = Array!Variant(args); bindArgs.reserve(a.length); foreach(arg; args) a ~= Variant(arg); driver.stmtVtable.variadicQuery(stmt, a); } static void variadicQuery(void[] stmt, ref BindArgs a) { auto s = toTypedPtr!Statement(stmt); callVariadic!F(a, s); }
  • 51. A R R AY T O VA R I A D I C C A L L static void callVariadic(alias F,S,A...) (ref S s, A a) { switch (s.length) { case 0: break; case 1: F(a,s[0]); break; case 2: F(a,s[0],s[1]); break; case 3: F(a,s[0],s[1],s[2]); break; case 4: F(a,s[0],s[1],s[2],s[3]); break; case 5: F(a,s[0],s[1],s[2],s[3],s[4]); break; default: throw new Exception(“arg overload"); } }
  • 52. U N PA C K VA R I A N T S static void unpackVariants(alias F, int i=0, A...)(A a) { alias Types = AliasSeq!(byte, ubyte, string, char, dchar, int, uint, long, ulong, Date); static void call(int i, T, A...)(T v, A a) { unpackVariants!(F,i+1)(a[0..i], v, a[(i+1)..$]); } static if (i == a.length) { F(a); } else { foreach(T; Types) { if (a[i].convertsTo!T) { call!i(a[i].get!T,a); return; } } throw new Exception("unknown type: " ~ a[i].type.toString); } } i n t i n t V ! D a t e i a[0..i] v a[(i+1)..$]
  • 53.
  • 54. R E A L I T Y C H E C K P(10,5) = 30240 Drivers must implement an additional call two options: query(ref Array!Variant args) query(Args..)(A.. args) // accept variants
  • 55. F i b e r b a s e d D r i v e r A p p ro a c h e s 1) Modify socket calls in driver source, if available, to use a D (or vibe.d) non-blocking socket layer. 2) Implement from scratch a non-blocking driver using a known wire protocol 3) Adapt an existing non-blocking interface for use with vibe.d / std.event.
  • 56. F I B E R A S Y N C Q U E RY E X A M P L E auto descriptor = con.descriptor(); auto event = createFileDescriptorEvent( descriptor, FileDescriptorEvent.Trigger.any); nonBlockingQuery(sql); while (true) { if (poll) { bool complete = readData; if (complete) break; } event.wait(FileDescriptorEvent.Trigger.read); } } vibe.d calls async driver calls
  • 57. N O N - B L O C K I N G M Y S Q L C L I E N T “We're Gonna Need A Bigger Database”
  • 58. S U P P O R T E D D ATA B A S E S current support (WIP) Up next
  • 59. U P C O M I N G W O R K • Fiber based drivers for Postgres & Webscalesql • Asynchronous push models (Observables) • Query builder • Schema metadata • Callable statements • Blob support • Operation timing • Simulated binding (freetds) • Quote escaping • Expose more features of underlying drivers • Multiple result support • NoSql support • Test suite improvement • Utilities • More…
  • 60. G E T T I N G S TA R T E D ( O S X ) $ b re w i n s t a l l d m d d u b m y s q l $ m k d i r - p ~ / s rc / d e m o & & c d ~ / s rc / d e m o i m p o r t s t d . d a t a b a s e . m y s q l ; i m p o r t s t d . d a t a b a s e . u t i l ; v o i d m a i n ( ) { a u t o d b = c re a t e D a t a b a s e ( " m y s q l : / / 1 2 7 . 0 . 0 . 1 / t e s t " ) ; d b . q u e r y ( " s e l e c t * f ro m p e r s o n ” ) . ro w s . w r i t e R o w s ; } $ d u b { " n a m e " : " d e m o " , " l i b s " : [ " m y s q l c l i e n t " ] , " d e p e n d e n c i e s " : { " d s t d d b " : " * " } , " t a rg e t Ty p e " : “ e x e c u t a b l e ” , " v e r s i o n s " : [ “ S t d L o g g e r D i s a b l e L o g g i n g " ] } d u b . j s o n d e m o . d
  • 61. Q U E S T I O N S https://github.com/cruisercoder/dstddb DUB: dstddb