On 19/03/12 01:54, Brian Palmer wrote:
I'm working on a DSL for generating SQL queries, based loosely on
Python's SQLAlchemy and Ruby's Sequel. One nice thing about the DSL is
the compact syntax for specifying WHERE clauses. With some fiddling, I
got it working for opEquals, a simplified example:

foreach(network; db["networks"].each) {
writefln("network: %s", network.name);
foreach(host; db["hosts"].where(db.c.id == network.id)) {
writefln("\thost: %s", host.address);
}
}

This works because db.c.id returns a struct which defines an opEquals
which returns a "Filter" struct, rather than an int. I'm not positive
that it should really be allowed by the compiler, but it works:

struct Filter { ... }
struct Column {
Filter opEquals(T)(T rhs) { ... }
}

Then the .where call takes a filter, and uses it to output a snippet of
sql like "id = 5"

However, this won't work for comparison operators like < and >, which
all map to opCmp, or for != (since that's rewritten to !(a == b))

I guess I have two questions, one, am I going to shoot myself in the
foot by going down this path, because it only happens to work due to the
compiler being too lax? And is there interest in extending D to allow
the rest of the operators to return non-boolean results? I'm thinking
something like falling back to opBinary!("<"), etc, if opCmp isn't
defined for a struct.

I don't think this is EVER what you really want.
I believe that if you think you want this feature, 100% of the time, what you really want is a syntax tree of the entire expression. That is, either you want ">" to be a comparison, and "+" to be an addition, OR you want a syntax tree.



Reply via email to