robotoworks / mechanoid

Eclipse plugin providing a set of DSL's for the rapid development of Android apps
58 stars 26 forks source link

Combine MechanoidNet and MechanoidDB #193

Closed hannesa2 closed 11 years ago

hannesa2 commented 11 years ago

Hi, is there a elegant way to combine both tools. Meaning by request a REST call, the result is filled to SQlite automatically. And backwards too.

thank you

fluxtah commented 11 years ago

Hi @hannesa2 its a good idea and it did cross my mind before but the way I use Mechanoid currently would introduce a bit of complexity since after parsing a JSON response we often to some processing and sanitisation of the data before committing it to the database.

Also a lot of our REST responses have hierarchical data so there would be some requirement to specify the mapping to database columns, and even if we could do this automatically based on the relationships of the generated mechnet model that would introduce complexity as far as unique key (index) mapping and what not.

Maybe there might be some way to make an easy API that would automatically map from the Mech NET entities to Mech DB builders or something.

hannesa2 commented 11 years ago

Hi, I know about the possible complexity with structure objects. But some of us should make a 'offline-ability' app, this means a almost 1:1 structure on REST and SQlite. For this simple requirement, I see an PK on SQLite and a PK on REST like this:

    create table tab1 (
        _id integer primary key autoincrement,
        restID integer, //PK from REST
        changedate integer,
        fieldABC text,
        ....

REST:

get getValuesForTab1 /somethingTab1.php {
    params changedate : int
    response extends BaseResponse {
        data : TabREST1[]
    }
}

entity TabREST1 {
    restID : long, //PK in REST
    changedate : int,
    fieldXYZ : String,
    .....

My idea is mayby an additional info like

entity TabREST1 as SQLitetab:Tab1 {
    restID : long (sqlite:restID), //PK in REST
    changedate : int (sqlite:changedate),
    fieldXYZ : String ((sqlite:fieldABC)),
    .....

with this information a easy MechNet internal Tab1Record.get(id) with .save() or .insert() can be done.

##############

An absolute other way for me is to do it manually like

for(TabREST1 tab1: response.getData()) {    
    Tab1Record record = TabRecord1.get(field.getValue(tab1.getRestId()); //new or edit
    for(Restfields field: tab1.fieldlist) { //fill any field from REST to Sqlite
        record.setValue(field.getFieldName(), field.getValue()).
    }
    record.save();
}

but for this, I miss at least on MechDB the anonymous getter/setter record.setValue(String value, String fieldname) and in MechNET (maybe, I didn't check till now) the same anonymous getter/setter.

I hope I wrote it understandable for you

Thank you

fluxtah commented 11 years ago

If your mechnet entities correspond to your mechdb table column names then it could be possible to have an automatic mapper since all you need to do is build ContentValues for your tables then use the content provider to insert records, take a look at the generated record builder classes in the contract for each table, they use content values underneath.

I can look into this a bit more later to see if there is something I can do,

hannesa2 commented 11 years ago

It sounds good, but I didn't found a way for the NET record to get ContentValues. I miss it, like in DB record. Where can I find it ?

fluxtah commented 11 years ago

Unfortunately mechnet does not currently output the key names but it probably should, I will try and add this at some point.

fluxtah commented 10 years ago

So now key names are being output with entities, but entities now need a toContentValues() method.

fluxtah commented 10 years ago

Key names and toContentValues() methods are now being generated for net entities, there is also an overload to provide your own key mapping, ie if you have a JSON key mapped in an entity

entity PersonEntity {
    fname:String,
    last_name:String
}

but in your db its:

create table people (
    first_name text,
    last_name text
)

You can override the mapping, ie:-

Person person = new Person();

Map<String, String> map = new HashMap<String,String>();
map.put(PersonEntity.KEY_FNAME, People.FIRST_NAME);

ContentValues values = person.toContentValues(map);