-
Notifications
You must be signed in to change notification settings - Fork 3
[2] Entity MapWrapper
- Add it in your root build.gradle at the end of repositories:
buildscript {
repositories {
maven { url 'https://jitpack.io' }
}
}
...
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
- Add gradle dependency
implementation 'com.github.Kaufland.andcouchbaseentity:couchbase-entity-api:3.1.0'
kapt 'com.github.Kaufland.andcouchbaseentity:couchbase-entity:3.1.0'
- Optionally, if you use Couchbase 2.x.x (provides already implemented connector)
implementation 'com.github.Kaufland.andcouchbaseentity:couchbase-entity-connector:3.1.0@aar'
NOTE: For custom connectors see
- Configure library
- Add the following code in your Application.kt
@Override
public void onCreate() {
super.onCreate();
PersistenceConfig.configure(object : Couchbase2Connector() {
override fun getDatabase(name: String): Database {
if (DB == name) {
//for better performance when using queries may consider create some Indexes
return database!!
}
throw RuntimeException("wrong db name defined!!")
}
})
}
NOTE: For other databases implement your own connector
- Annotate classes to generate entities (all generated classes have the suffix Entity or Wrapper (used for child entities or map wrapping)
@Entity(database = Application.DB)
@Fields(
Field(name = "type", type = String::class, defaultValue = "product", readonly = true),
Field(name = "name", type = String::class),
Field(name = "comments", type = UserComment::class, list = true),
Field(name = "image", type = Blob::class),
Field(name = "identifiers", type = String::class, list = true)
)
@Queries(
Query(fields = ["type"])
)
open class Product{
companion object{
@GenerateAccessor
fun someComplexQuery(param1 : String){
//do some heavy logic here
}
}
}
- Use generated classes and be happy :-)
- Example 1: use fluent API to modify multiple properties.
ProductEntity.create().builder()
.setName("Wodka")
.setComments(listOf(UserCommentWrapper
.create().builder()
.setComment("feeling like touch the sky")
.exit())).setImage(Blob("image/jpeg", resources.openRawResource(R.raw.ic_kaufland_placeholder)))
.exit().save()
- Example 2: get / set data via kotlin property syntax
var data = ProductEntity.create()
data.name = "Tomatoes"
data.comments = listOf(UserCommentWrapper.create().builder().setComment("don't like there color").exit(),
UserCommentWrapper.create().builder().setComment("worst experience ever!!").exit())
data.image = Blob("image/jpeg", resources.openRawResource(R.raw.ic_kaufland_placeholder))
data.save()
NOTE : To modify child entities it's neccessary to invoke the setter before saving the parent entity
final List<UserCommentWrapper> data = getParentEntity().getComments();
data.remove(position);
try {
ProductEntity entity = getParentEntity();
entity.setComments(mComments);
entity.save();
} catch (PersistenceException e) {
Log.e(TAG, "failed to save Entity", e);
}
By using the @Query annotation the Framework automatically generates static methods to execute this queries and returns the resulted entities
@Fields(
Field(name = "type", type = String::class, defaultValue = "product", readonly = true),
Field(name = "name", type = String::class)
)
@Queries(
Query(fields = ["type"]),
Query(fields = ["type", "name"])
)
Above Code generates Methods which can be used like
val resultByType = MyEntity.findByType()
val resultByTypeAndName = MyEntity.findbyTypeAndName("beer")
The Query generation may not fit all needs for this cases you can define a query by yourself and use the @GenerateAccessor annotation to make it available in the GeneratedEntity
@Entity(database = "mydb_db")
//Fields and Queries add them here
open class Product{
companion object{
@GenerateAccessor
fun someComplexQuery(param1 : String){
//do some heavy logic here
}
}
}
ProductEntity.someComplexQuery("Foo")
By using the @SchemaClass
annotation the Framework automatically generates a class that contains all the fields as properties.
The fields are mapped to one of four types, determined by the parameters provided for each field, along with a generic derived from the "type" parameter.
The type is determined based on the following criteria:
- CMList: When the "list" parameter is marked as true.
-
CMObject: If the "type" parameter is assigned to another class that also has the
@SchemaClass
annotation. -
CMObjectList: When both the "list" parameter is true and the "type" parameter is set to a class that is annotated with
@SchemaClass
. - CMField: When none of the above apply.
If a defaultValue is given, it also creates a default property for this field.
@SchemaClass
@Fields(
Field(name = "type", type = String::class, defaultValue = "product", readonly = true),
Field(name = "name", type = String::class)
)
class Product
The Code above generates a class like this:
open class ProductSchema(
path: String = ""
) : Schema {
val DEFAULT_TYPE: String = "product"
val type: CMField<String> = CMField("type", path)
val name: CMField<String> = CMField("name", path)
}