Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve toStruct #191

Open
Abscissa opened this issue Feb 25, 2019 · 0 comments
Open

Improve toStruct #191

Abscissa opened this issue Feb 25, 2019 · 0 comments

Comments

@Abscissa
Copy link

From @jpf91 over on PR #188:

mysql-native's toStruct is quite limited currently (e.g. when compared to mysql-lited or vibe.data serialization). A better implementation is blocked mainly by the fact, that the Row does currently not know the column names. Only indices are available (but these depend on the sql query string, so it's also not easily possible to recover field names from these ids).

This PR simply exposes the names of the columns. A basic toStruct mapper could then look like this:

T parse(T)(const Row row)
{
    T result;
    row.parse(result);
    return result;
}

void parse(T)(const Row row, ref T result)
{
    foreach (size_t i, name; row.names)
    {
        result.setField(name, row[i]);
    }
}

void setField(T)(ref T result, string name, Variant value)
{
    import std.traits;

    foreach (idx, member; result.tupleof)
    {
        enum mname = T.tupleof[idx].stringof;
        if (name == mname)
        {
            alias FieldType = typeof(__traits(getMember, result, mname));
            convertField!FieldType(__traits(getMember, result, mname), value);
        }
    }
}

void convertField(T)(ref T field, Variant value)
{
    import std.traits, std.datetime;
    alias UT = Unqual!T;

    // Convert between varian of possily typeof(null) and Nullable!T
    static if (is(typeof(UT.nullify)))
    {
        if (value.type == typeid(typeof(null)))
            field.nullify();
        else
            field = value.coerce!(Unqual!(ReturnType!(UT.get)));
    }
    else static if (is(UT == DateTime))
    {
        field = value.get!UT;
    }
    // All other types
    else
    {
        field = value.coerce!UT;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants