database_generation: Don't assign to functions, ... in populateFromDbRow

Using `tupleof` instead of `__traits(allMembers, ...)` skips over all
nested declarations that are not actual fields.
This commit is contained in:
MoonlightSentinel 2021-05-07 21:33:40 +02:00
parent f75590c1f4
commit d86bc412fc
No known key found for this signature in database
GPG Key ID: 1A1A60AECDC956AB
2 changed files with 75 additions and 5 deletions

View File

@ -1468,5 +1468,57 @@ struct varchar(size_t max) {
alias asString this; alias asString this;
} }
version (unittest)
{
/// Unittest utility that returns a predefined set of values
package (arsd) final class PredefinedResultSet : ResultSet
{
string[] fields;
Row[] rows;
size_t current;
this(string[] fields, Row[] rows)
{
this.fields = fields;
this.rows = rows;
foreach (ref row; rows)
row.resultSet = this;
}
int getFieldIndex(const string field) const
{
foreach (const idx, const val; fields)
if (val == field)
return cast(int) idx;
assert(false, "No field with name: " ~ field);
}
string[] fieldNames()
{
return fields;
}
@property bool empty() const
{
return current == rows.length;
}
Row front() @property
{
assert(!empty);
return rows[current];
}
void popFront()
{
assert(!empty);
current++;
}
size_t length() @property
{
return rows.length - current;
}
}
}

View File

@ -378,11 +378,9 @@ auto find(alias T)(Database db, int id) {
private void populateFromDbRow(T)(ref T t, Row record) { private void populateFromDbRow(T)(ref T t, Row record) {
foreach(field, value; record) { foreach(field, value; record) {
sw: switch(field) { sw: switch(field) {
static foreach(memberName; __traits(allMembers, T)) { static foreach(const idx, alias mem; T.tupleof) {
case memberName: case __traits(identifier, mem):
static if(is(typeof(__traits(getMember, T, memberName)))) { populateFromDbVal(t.tupleof[idx], value);
populateFromDbVal(__traits(getMember, t, memberName), value);
}
break sw; break sw;
} }
default: default:
@ -414,6 +412,26 @@ private void populateFromDbVal(V)(ref V val, string value) {
} }
} }
unittest
{
static struct SomeStruct
{
int a;
void foo() {}
int b;
}
auto rs = new PredefinedResultSet(
[ "a", "b" ],
[ Row([ "1", "2" ]) ]
);
SomeStruct s;
populateFromDbRow(s, rs.front);
assert(s.a == 1);
assert(s.b == 2);
}
/++ /++
Gets all the children of that type. Specifically, it looks in T for a ForeignKey referencing B and queries on that. Gets all the children of that type. Specifically, it looks in T for a ForeignKey referencing B and queries on that.