Friday, October 25, 2013

ORMapping in Dart

A persistence support using relational DB is very basic requirement for any real world applications.
Right now, there seems no such tools available in Dart.
but there are a few DB driver for SQL server.
in this situation, what we can do in simplest way would be following.
  1.  delegate generating db scheme to JPA. In order  to do this, we use the same annotation as JPA in Dart class. and from this dart class, using reflection, we generate Java source code with the same JPA annotation defined in the dart class. The rest of generating scheme in db can be automated in some script.
  2.  Once we had a db scheme, we can access db. one way is to use Java itself to access db and Dart will access the object as Json through web API, but this approach may make system complicated since Dart needs Java server. So if we avoid intermediate Java and can directly access DB, that would be more simple approach.Since Dart class has already annotations, so it should be possible to provide reflection based plumbing to map row data to entity properties.
 Normally we will need to start from defining abstract(interface) class for db entity(table).
then we need to provide the implementation class for this interface.
But manual implementation of such implementation class are tedious and mechanical. It should be automated. One way is just to generate such an implementation class from the interface classes. But code generation approach often create more problem for maintenance etc. So it is better to avoid this approach. Also code generation bloat the code size, and it will not good approach for running on client side.

but if we define abstract class we need to define another class implementing the methods, so in this approach, we cannot avoid code generation.
So we need to define a concrete class which has no db mapping codes.

The simple solution for this is just using inheritance.

@Entity()
@Table(name: "A")
class A extends Persistence {
    @Id()
    @Basic(optional: false)
    @Column(name: "id")
    String _id;

    @Basic(optional: false)
    @Column(name: "i")
    int _i;
    
    @ManyToOne()
    B _b;

    @OneToMany(mappedBy: "a")
    List<C> _cs;
    
    String get id => get(const Symbol("id"));
    void set id(String v)=>set(const Symbol("id"), v);

    int get i => get(const Symbol("i"));
    void set i(int v)=>set(const Symbol("i"), v);

    B get b => get(const Symbol("b"));
    void set b(B v)=>set(const Symbol("b"), v);

    List<C> get cs => get(const Symbol("cs"));
    void set cs(List<C> v)=>set(const Symbol("cs"), v);
}
we define persistence root class called Persistence. This class will use reflection for intercepting getter/setter to access database. The only annoyance is we needs to define getter/setter calling methods get/set defined in the Persistence class. This would be a reasonable compromise. If dart has a build-in intercepting mechanism for getter/setter, we may further skip this definitions, and it may be a good proposal for Dart language..

The basic idea required to implement the Persistent class is the same as Monitor class, but it uses different annotation(JPA style), and will have SQL Driver access codes.

Another aspect of OR mapping is query. Often they introduce new query language mainly to avoid join operation. So we may create such query language or implement some standard query language in Dart, but we may just use ordinary SQL for this purpose. if it uses many-to-many relationship,  JPA creates intermediate table so writing query require such knowledge, but other relationships , the db table representation is simple. (and it is better to avoid many-to-may to simplify the db scheme).

So I think I will just go with SQL query based approach.
 But still some idea from https://github.com/polux/parsers, may be used to implement simple query language.

No comments:

Post a Comment