Common relational database interfaces.

Boost License 1.0.

Piotr Szturmaj

struct DBRow (Specs...);
Data row returned from database servers.

DBRow may be instantiated with any number of arguments. It subtypes base type which depends on that number:

Number of arguments Base type
0 Variant[]

It is default dynamic row, which can handle arbitrary number of columns and any of their types.
1 Specs itself, more precisely Specs[0]
    struct S { int i, float f }

    DBRow!int rowInt;
    DBRow!S rowS;
    DBRow!(Tuple!(string, bool)) rowTuple;
    DBRow!(int[10]) rowSA;
    DBRow!(bool[]) rowDA;
>= 2 Tuple!Specs
    DBRow!(int, string) row1; // two arguments
    DBRow!(int, "i") row2; // two arguments

If there is only one argument, the semantics depend on its type:

Type Semantics
base type, such as int Row contains only one column of that type
struct Row columns are mapped to fields of the struct in the same order
Tuple Row columns are mapped to tuple fields in the same order
static array Row columns are mapped to array items, they share the same type
dynamic array Same as static array, except that column count may change during runtime

String types are treated as base types.

There is an exception for RDBMSes which are capable of returning arrays and/or composite types. If such a database server returns array or composite in one column it may be mapped to DBRow as if it was many columns. For example:
struct S { string field1; int field2; }
DBRow!S row;
In this case row may handle result that either:
  • has two columns convertible to respectively, string and int
  • has one column with composite type compatible with S

DBRow's instantiated with dynamic array (and thus default Variant[]) provide additional bracket syntax for accessing fields:
auto value = row["columnName"];
There are cases when result contains duplicate column names. Normally column name inside brackets refers to the first column of that name. To access other columns with that name, use additional index parameter:
auto value = row["columnName", 1]; // second column named "columnName"

auto value = row["columnName", 0]; // first column named "columnName"
auto value = row["columnName"]; // same as above

Default untyped (dynamic) DBRow:
DBRow!() row1;
DBRow!(Variant[]) row2;

assert(is(typeof(row1.base == row2.base)));

auto cmd = new PGCommand(conn, "SElECT typname, typlen FROM pg_type");
auto result = cmd.executeQuery;

foreach (i, row; result)
    writeln(i, " - ", row["typname"], ", ", row["typlen"]);

DBRow with only one field:
DBRow!int row;
row = 10;
row += 1;
assert(row == 11);

DBRow!Variant untypedRow;
untypedRow = 10;
DBRow with more than one field:
struct S { int i; string s; }
alias Tuple!(int, "i", string, "s") TS;

// all three rows are compatible
DBRow!S row1;
DBRow!TS row2;
DBRow!(int, "i", string, "s") row3;

row1.i = row2.i = row3.i = 10;
row1.s = row2.s = row3.s = "abc";

// these two rows are also compatible
DBRow!(int, int) row4;
DBRow!(int[2]) row5;

row4[0] = row5[0] = 10;
row4[1] = row5[1] = 20;
Advanced example:
enum Axis { x, y, z }
struct SubRow1 { string s; int[] nums; int num; }
alias Tuple!(int, "num", string, "s") SubRow2;
struct Row { SubRow1 left; SubRow2[] right; Axis axis; string text; }

auto cmd = new PGCommand(conn, "SELECT ROW('text', ARRAY[1, 2, 3], 100),
                                ARRAY[ROW(1, 'str'), ROW(2, 'aab')], 'x', 'anotherText'");

auto row = cmd.executeRow!Row;

assert(row.left.s == "text");
assert(row.left.nums == [1, 2, 3]);
assert(row.left.num == 100);
assert(row.right[0].num == 1 && row.right[0].s == "str");
assert(row.right[1].num == 2 && row.right[1].s == "aab");
assert(row.axis == Axis.x);
assert(row.s == "anotherText");

void checkReceivedFieldCount (int fieldCount);
Checks if received field count matches field count of this row type.

This is used internally by clients and it applies only to DBRow types, which have static number of fields.

template isCompositeType (T)
Check if type is a composite.

Composite is a type with static number of fields. These types are:
  • Tuples
  • structs
  • static arrays

Page was generated with on Sun Apr 10 02:02:23 2011