Allow computed fields based on database fields (HIDE in compiler)
See original GitHub issueA way I have found that works pretty well with sqldelight is to have two different models separated, one for the database model and another for the data that comes from network. Thus sqldelight forces you to some types based on the database logic (that can be different to the presentation logic) with autovalue it gets a bit messy to mix Database, network and presentation in the same model.
Said that, now when we have a factory, this factory needs a generic class that extends your SomethingModel, but what if I want to have a FACTORY object that provides me the mapping between the presentation and the database without creating a new instance of the database object, that will avoid huge memory allocations with big lists.
Let me show an example. I have two classes: Comment and CommentDb. Comment is my presentation which can have an id null and CommentDb is my database layer.
Comment.java
@AutoValue
public abstract class Comment {
@Nullable
public abstract Long id();
@NonNull
public abstract Long postId();
@NonNull
public abstract String name();
@NonNull
public abstract String email();
@NonNull
public abstract String body();
@NonNull
public abstract Long createdAt();
@Nullable
public abstract Long updatedAt();
@Nullable
public abstract Long deletedAt();
public abstract boolean needsSync();
@NonNull
public ContentValues marshal(){
return CommentDb.FACTORY.marshal()
._id(id())
._postId(postId())
._name(name())
._body(body())
._email(email())
._createdAt(createdAt())
._updatedAt(updatedAt())
._deletedAt(deletedAt())
._needsSync(needsSync())
.asContentValues();
}
@NonNull
public static Builder builder() {
return new AutoValue_Comment.Builder();
}
@NonNull
public static Builder builder(@NonNull Comment comment) {
return builder()
.postId(comment.postId())
.id(comment.id())
.name(comment.name())
.email(comment.email())
.body(comment.body())
.createdAt(comment.createdAt())
.updatedAt(comment.updatedAt())
.deletedAt(comment.deletedAt())
.needsSync(comment.needsSync());
}
@AutoValue.Builder
public static abstract class Builder {
@NonNull
public abstract Builder id(@Nullable Long id);
@NonNull
public abstract Builder postId(@NonNull Long postId);
@NonNull
public abstract Builder name(@NonNull String name);
@NonNull
public abstract Builder email(@NonNull String email);
@NonNull
public abstract Builder body(@NonNull String body);
@NonNull
public abstract Builder createdAt(@NonNull Long createdAt);
@NonNull
public abstract Builder updatedAt(@Nullable Long updatedAt);
@NonNull
public abstract Builder deletedAt(@Nullable Long deletedAt);
@NonNull
public abstract Builder needsSync(@Nullable boolean needsSync);
@NonNull
public abstract Comment build();
}
}
CommentDb.java
@AutoValue
public abstract class CommentDb implements CommentModel {
public static final Factory<CommentDb> FACTORY = new Factory<>(new CommentModel.Creator<CommentDb>() {
@Override
public CommentDb create(long id, long postId, String name, String body, String email, long createdAt, Long updatedAt, Long deletedAt, boolean needsSync) {
return new AutoValue_CommentDb(id, postId, name, body, email, createdAt, updatedAt, deletedAt, needsSync);
}
});
public static final RowMapper<CommentDb> COMMENTS_POST_MAPPER = FACTORY.selectCommentsPostMapper();
public static final RowMapper<CommentDb> SYNC_POSTS_MAPPER = FACTORY.selectSyncCommentsMapper();
}
Said that, I would like to be able to do something like:
public static final Factory<Comment> FACTORY = new Factory<>(new CommentModel.Creator<Comment>() {
@Override
public Comment create(long id, long postId, String name, String body, String email, long createdAt, Long updatedAt, Long deletedAt, boolean needsSync) {
//build here my comment based on the database info
}
});
Issue Analytics
- State:
- Created 7 years ago
- Comments:13
Top GitHub Comments
Ok, then just a good documentation for it will be needed and a detailed explanation for what you can use it. 👍 Go for the
HIDE
hey @AlecStrong! I had to re-read the whole issue since I completely forgot what was it about 😄 Yeah I can understand the timings, it is indeed a major change. Sounds good to me, this way the mapping will be way more flexible and also computing fields can be done in an easier way than including more syntax to the database creation.
Thanks for the good work