Merge branch 'master' of github.com:adamdruppe/arsd

This commit is contained in:
Adam D. Ruppe 2021-05-07 16:17:43 -04:00
commit b4ef822ad1
2 changed files with 94 additions and 7 deletions

View File

@ -1468,5 +1468,57 @@ struct varchar(size_t max) {
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

@ -341,11 +341,28 @@ void insert(O)(ref O t, Database db) {
foreach(row; db.query("SELECT max(id) FROM " ~ toTableName(O.stringof)))
t.id.value = to!int(row[0]);
} else {
foreach(row; builder.execute(db, "RETURNING id")) // FIXME: postgres-ism
t.id.value = to!int(row[0]);
static if (__traits(hasMember, O, "id"))
{
foreach(row; builder.execute(db, "RETURNING id")) // FIXME: postgres-ism
t.id.value = to!int(row[0]);
}
else
{
builder.execute(db);
}
}
}
// Check that insert doesn't require an `id`
unittest
{
static struct NoPK
{
int a;
}
alias test = insert!NoPK;
}
///
class RecordNotFoundException : Exception {
this() { super("RecordNotFoundException"); }
@ -378,11 +395,9 @@ auto find(alias T)(Database db, int id) {
private void populateFromDbRow(T)(ref T t, Row record) {
foreach(field, value; record) {
sw: switch(field) {
static foreach(memberName; __traits(allMembers, T)) {
case memberName:
static if(is(typeof(__traits(getMember, T, memberName)))) {
populateFromDbVal(__traits(getMember, t, memberName), value);
}
static foreach(const idx, alias mem; T.tupleof) {
case __traits(identifier, mem):
populateFromDbVal(t.tupleof[idx], value);
break sw;
}
default:
@ -414,6 +429,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.