d-dbapi ALPHA-2 released
Myron Alexander
someone at somewhere.com
Mon Jun 11 09:49:02 PDT 2007
Christian Kamm wrote:
> You can use 'static' foreach, however. If you use foreach with tuples, it is
> expanded at compile time.
Thanks Christian. Works like a charm. Here is the final spike. I am
passing in args to make it more "dynamic" and to factor out the compile
time function effect. I have not looked at CTFs yet so I don't know if
my method does actually simulate a database lookup. I guess I will only
find out once I have implemented the real code.
Thanks again,
Myron.
> import std.stdio;
> import std.traits;
> import std.conv;
>
> /* Example value object.
> */
> struct ValueStruc {
> char[] name;
> int age;
> char[] addr1;
> char[] addr2;
> char[] addr3;
> double balance;
> }
>
> struct OtherValue {
> int type;
> char[] dirname;
> char[] filename;
> }
>
> struct ValueStrucWNull {
> char[] name;
> int age;
> char[] addr1;
> char[] addr2;
> char[] addr3;
> double balance;
>
> bool[6] nullFlag;
> }
>
> struct OtherValueWNull {
> int type;
> char[] dirname;
> char[] filename;
>
> bool[3] nullFlag;
> }
>
> /* Typesafe database row object.
> */
> struct Row(T ...) {
> T t;
> bool[T.length] nullFlag;
> }
>
> char[][] args;
>
> int getInt (int i) {
> return toInt (args[i+1]);
> }
>
> char[] getString (int i) {
> return args[i+1];
> }
>
> double getDouble (int i) {
> return toDouble(args[i+1]);
> }
>
> // This works
> T getRowElement(T) (uint i) {
> static if (is (T == int)) {
> return getInt (i);
> } else static if (is (T == char[])) {
> return getString (i);
> } else static if (is (T == double)) {
> return getDouble (i);
> } else {
> static assert (0);
> }
> }
>
> // So do these when the index is uint. If you use void getElem (int i, .....
> // then it fails as it does not know how to differentiate between "int value"
> // and "double value" signatures.
> void getElem (uint i, ref int value) {
> value = getInt (i);
> }
>
> void getElem (uint i, ref char[] value) {
> value = getString (i);
> }
>
> void getElem (uint i, ref double value) {
> value = getDouble (i);
> }
>
> /* Simulate a typesafe fetch from the database.
> *
> * With thanks to Chris Nicholson-Sauls, Lutger Blijdestijn, and Christian Kam
> * who provided code and information on how to make this possible.
> *
> * Thanks to Kirk McDonald for for the type-safe fetch idea.
> */
> Row!(T) fetchone(T ...) () {
> Row!(T) r;
>
> foreach (i, val; r.t) {
> r.t[i] = getRowElement!(typeof(r.t[i]))(i);
>
> // Works too
> //getElem (i, r.t[i]);
> }
>
> static if (T.length == 6) {
> //~ r.t[0] = "Myron";
> //~ r.t[1] = 10;
> //~ r.t[2] = "addr1";
> //~ r.t[3] = "addr2";
> //~ r.t[4] = "addr3";
> //~ r.t[5] = 100001.10;
> r.nullFlag[0] = true;
> r.nullFlag[1] = false;
> r.nullFlag[2] = false;
> r.nullFlag[3] = true;
> r.nullFlag[4] = false;
> r.nullFlag[5] = false;
> }
>
> static if (T.length == 3) {
> //~ r.t [0] = 34;
> //~ r.t [1] = r"c:\dir1\dir2\dir2\";
> //~ r.t [2] = "filename";
> r.nullFlag[0] = false;
> r.nullFlag[1] = true;
> r.nullFlag[2] = false;
> }
>
> return r;
> }
>
> /* Fetch a typesafe record from the database and populate the struct.
> *
> * With thanks to Chris Nicholson-Sauls, Lutger Blijdestijn, and Christian Kam.
> */
> T fetchstruc(T) () {
>
> static if (is (T == struct)) {
> auto r = fetchone!(FieldTypeTuple!(T))();
> T t;
> foreach (i, v; r.t) {
> // According to Christian, using v may not work every time.
> t.tupleof[i] = r.t[i];
> }
> return t;
>
> } else {
> static assert (0);
> }
> }
>
> /* Fetch a typesafe record from the database, populate the struct and set
> * null field flags.
> */
> T fetchnullstruc(T) () {
>
> static if (is (T == struct)) {
> auto r = fetchone!(FieldTypeTuple!(T)[0..length-1])();
> T t;
> foreach (i, v; r.t) {
> // According to Christian, using v may not work every time.
> t.tupleof[i] = r.t[i];
> }
> foreach (i, nullFlagValue; r.nullFlag) {
> t.nullFlag[i] = nullFlagValue;
> }
> return t;
>
> } else {
> static assert (0);
> }
> }
>
>
> void main (char[][] args) {
>
> .args = args;
>
> auto x = fetchstruc!(ValueStruc) ();
> writefln ("%s, %s, %s, %s, %s, %#.2f", x.name, x.age, x.addr1, x.addr2, x.addr3, x.balance);
>
> auto y = fetchstruc!(OtherValue) ();
> writefln ("%s, %s, %s", y.type, y.dirname, y.filename);
>
> auto a = fetchnullstruc!(ValueStrucWNull) ();
> writefln ("%s, %s, %s, %s, %s, %#.2f, %s", a.name, a.age, a.addr1, a.addr2, a.addr3, a.balance, a.nullFlag);
>
> auto b = fetchnullstruc!(OtherValueWNull) ();
> writefln ("%s, %s, %s, %s", b.type, b.dirname, b.filename, b.nullFlag);
> }
More information about the Digitalmars-d-announce
mailing list