Realm-java: Possible to automatically generate wrapping class for directly accessing fields instead of String?

Created on 23 Jul 2016  ·  10Comments  ·  Source: realm/realm-java

Goal

Automatically generate wrapping classes upon building for fields so in query we can just access fields in wrapping classes.
This can increase reliability, reduce typo and unpredictable run time crashes.
DBFlow has this feature really like it.

Expected Results

Ex. I have a model theme using DBFlow. It generates a class Theme_Table and contains static field id.

@Table(database = DB.class)
public class Theme extends BaseModel {
    private int id;
}
public final class Theme_Table {
    public static final IntProperty id = new IntProperty(Theme.class, "id");
}
SQLite.select().from(Theme.class).where(Theme_Table.name.is("default));

Updated:

I noticed that in fact Realm already uses Gradle Transform API to generate same classes similarly.

Say if you have a class called Theme after built, you can see ThemeRealmProxy.ThemeColumnInfo class was generated and it contains all declared columns, and a field inside called private final ThemeColumnInfo columnInfo. However, we cannot access them because they are not public.

Since Realm already has the same things I wonder can Realm just provides access to them?

I would expect something like:
realm.where(Theme.class).equalTo(ThemeRealmProxy.ThemeColumnInfo.name , "default").findFirst()

T-Enhancement

Most helpful comment

@zeroarst, @spl

I'll put enhancement tag to have related discussion go on. I, too, believe it is doable. If this doesn't add much of benenfit but only makes API longer, I don't believe we'd pay more attention to it though.

Thanks for the suggestion!

All 10 comments

Technically I don't think it's impossible.

Personally I just write my own "generated metamodel" by hand, my realm objects tend to look like this

public class SomeObject extends RealmObject {
      @PrimaryKey
      private long id;

      @Index
      private String name;

      //getters setters

      public enum Fields {
           ID("id"), 
           NAME("name");

           private String field;

           private Fields(String name) {
                this.field = name;
           } 

           public String getField() {
                return field;
           } 
      } 
} 

And technically I do

 someObjectRepository.query(realm).contains(SomeObject.Fields.NAME.getField(), name).findAll();

(first part is essentially realm.where(SomeObject.class).)

I noticed that in fact Realm already generates such similarly.

Say if you have a class called User after built, you can see UserRealmProxy.UserColumnInfo class was generated and it contains all declared columns, and a field inside called private final UserColumnInfo columnInfo. However, we cannot access them because they are not public.

Can Realms just give the access to it?

I would expect something like:
realm.where(User.class).equalTo(UserRealmProxy.UserColumnInfo.name , "roy").findFirst()

So very long ¬¬

If anything, I would expect

realm.where(Employee.class).equalTo(EmployeeSchema.NAME, name).findAllSorted(EmployeeSchema.AGE, Sort.ASCENDING);

but that's just me. Personally as I said I just define my own enums for this.

I also write my own wrappers, but it would certainly be nice to have generated type-safe fields instead.

@zeroarst, @spl

I'll put enhancement tag to have related discussion go on. I, too, believe it is doable. If this doesn't add much of benenfit but only makes API longer, I don't believe we'd pay more attention to it though.

Thanks for the suggestion!

I must note that I've used the fact that the field name is provided by a string for dynamic queries before though.

@cmelchior created an annotation processor for this purpose: https://github.com/cmelchior/realmfieldnameshelper

It will work with soon-to-come SNAPSHOT release that contains this pull request (and it'll probably work with the next release)

Note it is still not properly released on BinTray yet. So JitPack would be required for now. BinTray should be done in the next couple of days.

1.0.0 of the library is now on BinTray: https://github.com/cmelchior/realmfieldnameshelper
Note, it only works with the latest 1.2.0-SNAPSHOT for now, but will work with the next proper release of Realm as well.

Realm Java v1.1.1 has just been released. https://github.com/cmelchior/realmfieldnameshelper will also work with that.

With regard to this issue, then we will not include generating these files as part of the standard Realm package. Mostly because creating user-facing files using the annotation processor is a bit error-prone and not friendly to beginners. E.g SQLBrite uses a custom IntelliJ for the same thing, and that might also be a direction we want to take, but nothing has been decided yet.

Since it is now possible for 3rd parties to write custom annotation processor plugins for these kind of things, I'll be closing this for now.

Was this page helpful?
0 / 5 - 0 ratings