Skip to content

Improve toStruct #191

Open
Open
@Abscissa

Description

@Abscissa

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;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions