Abstract Database Interface

Jacob Carlborg doob at me.com
Sun Oct 28 05:04:35 PDT 2012


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


More information about the Digitalmars-d-announce mailing list