std.database
Erik Smith via Digitalmars-d
digitalmars-d at puremagic.com
Fri Mar 4 10:42:45 PST 2016
On Friday, 4 March 2016 at 16:43:00 UTC, Kagamin wrote:
> On Friday, 4 March 2016 at 14:44:48 UTC, Erik Smith wrote:
>> Actually I like this and I think it can work. I'm trying to
>> keep a single execute function name for both row/no-row
>> queries. I can still return the range proxy for no-row queries
>> that is either empty or throws on access.
>
> Yes, that's the idea.
>
>> I'm just waiting for the code to settle a bit in a basic
>> working state before I refactor into a two layer design.
>
> Another idea from previous attempts: rename `execute` to
> `query`.
> foreach(row; db.query("select * from t"))
> { ... }
> And name for package: std.sql
>
>>> The result set is even iterator/stream, i.e. conceptually has
>>> even less container properties than ranges themselves. Why
>>> would you think of it as a container? I think it's ok as
>>> input range. Anyway, this `execute` method is a frontend,
>>> i.e. it's replaceable without touching the driver.
>>
>> The range itself is an InputRange. The statement is acting as
>> a container only in that it is the source of the range and
>> holds the data. I agree that it is confusing to use the term
>> container although it seems to fit the definition of one.
>
> `execute` should not return a statement, but a result set
> reader, that would be a range. Yeah, the result set is indeed a
> range conceptually: it has a definite number of ordered rows, a
> beginning and an end.
On further thought, execute() should definitely return something
but I think it needs to return a Result (alternative name
RowSet), the actual container, rather than the range. This more
cleanly separates out the post execute state management into a
separate object from Statement. The user will often want other
things from the execute then just the range, such as meta-data (#
columns, columns names/types) describing the returned table and
RowSet provides convenient access to it. This also suggests that
execute should be explicit & once/only, which I think is better.
Here is an updated example to illustrate:
auto db = createDatabase("file:///testdb");
auto rowSet = db.connection().statement("select name,score
from score").execute;
foreach (r; rowSet) writeln(r[0].as!string,",",r[1].as!int);
I'll track query as an alternative name for execute() and std.sql
as alternative for std.database.
More information about the Digitalmars-d
mailing list