Dinemic framework provides data mapper for C++ classes. Once you inherit DModel class, you will be able to use simple API to store and read fields and lists in your object. In this article you will learn how to use get/set properties (and similar), related to object. DField and DLists are described in separate document.

Inherit DModel class

In previous chapters you’ve read some basic information about DModel. LEt’s take a deep look into this class.

Constructors

Each class inheriting from DModel should implement all three constructors:

#include <libdinemic/dmodel.h>
class MyModel : public DModel
{
public:
    MyModel(StoreInterface *store,
           SyncInterface *sync,
           const std::vector &authorized_keys);
    MyModel(const std::string &db_id, StoreInterface *store, SyncInterface *sync, DModel *parent=NULL);
    MyModel(DModel *parent);
...

First constructor gets pointers to store and sync interfaces. This constructor should be used only in case, when we want to create new object in dinemic database. Calling it causes, that set of private/public keys are generated on host, that calls this constructor and stored in keystore. Then dinemic framework generates several notifications with information about new object and sends it over network to all other applications. Once object is created with this constructor, all network neighbors should know its database ID, public cryptographic key, and public signature key. Also, if you put list of authorized IDs as last parameter, all nodes in network should mark updates signed by that objects as valid. With this property you can define who can modify your object and who can read its encrypted data.

Second constructor is used only internally, to recreate child objects inside dinemic framerowk.

Third one is used to recreate objects. Imagine, that you are receiving information about new object created somewhere in cluster of dinemic nodes. Then, depending on context, you should be able to get such object with the same data inside, in your application/ Described in Chat tutorial DActions are using this constructor in this way. Once DAction is called, you probably will need to get into some interaction with such object. This constructor could be easily used to create such object temporarily:


...
my_model_id = config.get("my_important_object");

MyModel object(my_model_id);
...

Then you can execute gets/sets on this object to update its data. All updates should be visible soon in all neighbor nodes.

Simple get and set

The simplest way to update object’s data is to use its get and set properties. Once object is (re)created in you application, you can execute following code:


object.set("MyKey", "Some value");
...
object.get("MyKey");

Remember, that dinemic provides asynchronous data propagation. It means, that any changes in your objects, even local will appear with some delay. Your local instance of dinemic application should first process such chage and update object’s status in local database. Then change should be visible in your object. You can also use local variables instead, but remember, that non-dinemic fields will be visible only in your local object. Any other node with this object will not see such field.

Dinemic provides key-value database backend with no strict schema required. It means, that if you try to get non-existing value from key-value store, you will get empty string or passed as parameter, default value for get method. You should remember that, in context of data synchronization. In case of split brains of your application’s cluster your code might get not up to date values. Dealing with it should make your application more resistant for failures.

To get list of all fields you can call keys method on your object:


vector keys;

keys = object.keys();

Lists

Key-value store is not only data type. You are able to use lists in dinemic application. Let’s create one:


MyModel object("MyModel:12039ufrw...", store, sync);

object.list_append("first_list", "a");
object.list_append("first_list", "b");

As you see, it is not necessary to declare such list before using it. You can just append new values to it. No declaration means also, that there is no guarantee, that other instance of your model will not make the same list somewhere else in cluster. This is why list elements are indexed, but theirs primary index is in fact random string, internally.

You can use set method to tell explicit which element you want to set. If that is existing element, then it will be replaced:


object.list_set("first_list", 1, "x");

Finally, to get element of list you can call:


object.list_at("first_list", 0); // == "a"
object.list_length("first_list"); // == 2
object.list_index("first_list", "x"); // == 1, check above - we've just replaced b with x

Last thing what we might want to do with list is to remove one element:


object.list_delete("first_list", 0);