On 2012-10-28 02:31, BLM768 wrote:
I've recently been working with Ruby's ActiveRecord as part of my job,
and I realized that D was powerful enough to make a similar abstraction
layer. I've been playing with the idea for a little while, and I've put
up some code at https://github.com/blm768/adbi. It isn't nearly as
comprehensive as ActiveRecord, but it captures the basic idea of
representing database structures as objects/structs.
Using it is something like this:
module main;
import std.stdio;
import adbi.model;
import adbi.sqlite3.database;
struct Test {
mixin Model!"test";
const(char)[] name;
double num;
mixin reference!("test2", "test2", Test2);
}
struct Test2 {
mixin Model!"test2";
int value;
}
int main(string[] args) {
auto db = new Sqlite3Database("test.db");
auto q = db.query("SELECT * FROM test;");
Test.updateSchema(db);
Test2.updateSchema(db);
auto range = ModelRange!Test(q);
foreach(value; range) {
writeln(value);
}
auto q2 = db.query("SELECT * FROM test, test2 WHERE test2_id =
test2.id");
auto r2 = ModelRange!(Join!(Test, Test2))(q2);
foreach(j; r2) {
writeln(j);
}
return 0;
}
This code prints out every entry in the "test" table, then prints the
results of a join on the "test" and "test2" tables. The calls to
updateSchema() set up some static members of Test and Test2; after these
calls, the library does not perform any operations with the column
names, which should make retrieving a record noticeably faster than in a
system like ActiveRecord. The downside is that these functions must be
called every time the database schema changes in a way that affects
column order, but that should happen very rarely, if ever, in a typical
application.
The code is far from complete, but it's an interesting toy and might
actually be useful for simple applications once some of the issues are
ironed out.
Looking at the API used in this example it would say that it's not very
interesting and not very ActiveRecrod like. I think this looks more
interesting and more like ActiveRecrod:
class Person : Model
{
}
void main ()
{
auto p = new Person;
p.name = "John Doe";
p.save();
p = Person.where!(x => x.name == "John Doe");
}
But when you start to use associative it won't be as nice looking as
ActiveRecord due to the not so nice mixin syntax. What we need is AST
macros and user defined attributes/annotations. With that, associations
could potentially look like this:
class Foo : Model {}
class Person : Model
{
@hasMany Foo;
}
--
/Jacob Carlborg