mirror of https://github.com/adamdruppe/arsd.git
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:
parent
f24955f273
commit
00c327f57e
52
database.d
52
database.d
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue