greenDAO and data validation - android

I'm looking into using greenDAO for my Android app, but I noticed it doesn't seem to support any kind of data validation other than "not null", "unique", and foreign keys, either on the SQL level (constraints defined when creating tables) or the Java level (validation logic in setter methods). "Keep sections" don't seem like they would be helpful in this case because you can't have them within individual methods. Am I missing something, or would I really need to add yet another layer on top of the generated Java objects if I wanted to validate input data? (I'm somewhat confused how the framework could be useful without providing any place to include validation logic.)

1.
You can write a method
boolean check ();
in KEEP-SECTION of the entity which you call manually before INSERT or UPDATE.
2.
Another possibility is to extend the sourcecode of greendao generator to support checks: In property.java you could add a method to Property.Builder
public Property.Builder check (String expr) {
property.checkConditon = expr;
}
Of course you would have to introduce the String checkCondition = ""; and use it for generating the dao in the dao-template.
Problem:
With new versions of greendao your changes would be lost (but then again new version may already contain such a feature)
3.
A third possibility is to copy the generated CREATE TABLE statement, modify it to fit your needs and call your modified statement instead of the original one or to drop the original table and call your statement.
Problem:
If your table changes you will have to repeat this.

Related

greenDAO update and updateInTx not working

I'm using greenDAO 3.1 for one of my projects. Since I needed my id to be UUID I've decided to store it as ByteArray. Now the problem is I can't update my entities using update or updateInTx method and I have to use insertOrReplace or insertOrReplaceInTx method.
Can anybody tell me what is going on and why can't I update using update methods?
Is there any downside to using insertOrReplace methods instead of update methods?
This is my Entity's schema code:
Entity book = schema.addEntity("Book");
book.addByteArrayProperty("id").columnName("_id").primaryKey();
book.addStringProperty("title");
book.addByteProperty("edition");
book.addStringProperty("authors");
book.addStringProperty("desc");
book.addStringProperty("pic");
And here's my update code:
BookDao bookDao = daoSession.getBookDao();
List<Book> books = bookDao.loadAll();
for (Book book : books)
book.setDesc("It doesn't really matter!");
bookDao.updateInTx(books); //This isn't working
After a lot of searching and trouble I found the reason.
Since you can't query BLOB type in sqlite and since update methods use a condition over id in WHERE clause, the update method won't find the record I'm looking for. On the other hand when I use one of insertOrReplace methods, since the id field is unique it can't insert redundant id to the table and it completely replaces the old record with the one I'm trying to update. So, there was no problem with update methods, the real problem is with using ByteArray as id.
For the same reason, I also encountered an error when selecting using load method.

How to override the interface methods in the generated database table class?

I am using GreenDao in my Android project and i have generated my database schema successfully but I am stuck on one issue. My generated class needs to implement an interface that is not related to db. In the generator I have used the following method:
myEntity.implementsInterface("com.my.app.myinterface");
and then after generation the class has an implementation annotation of this interface in its header but there are no Override methods in the code of course. I tried putting a package with my interface in the generator project but still, methods are never there automatically. Shall I insert them manually within the
// KEEP METHODS - put your custom methods here
...
// KEEP METHODS END
section?
According GreenDAO documentation, you don't need to write any method because the classes are overriden on each run (that means each change you do will be erased), if you need an own behaviour you can use Keep Sections :
Keep sections
Entity classes are overwritten on each generator run. To allow adding custom code to your enities, greenDAO has “keep” sections. To enable them, use enableKeepSectionsByDefault() on the schema, or setHasKeepSections(true) on selected entities. Once enabled, three keep sections are generated in the entities:
// KEEP INCLUDES - put your custom includes here
// KEEP INCLUDES END
...
// KEEP FIELDS - put your custom fields here
// KEEP FIELDS END
...
// KEEP METHODS - put your custom methods here
// KEEP METHODS END
Now, you can put your custom code between KEEP […] and KEEP […] END. And don’t touch the KEEP comments. Code inside the keep section is kept during code generation. It’s a good idea to backup or commit your code in case something goes wrong unexpectedly.
Also take a look to this related question.

Easier way to set values in a class from UI

Often there's a scenario where there's a number of UI fields that have to be copied into Model objects. For instance, I'm currently writing a cart page that accepts credit card information in an Activity and I need to write all the inputted values to a CreditCard object.
I end up with blocks of code that look like the following:
CreditCard card = new CreditCard();
card.setFullName(txtFullName.getText().toString());
card.setAddress(txtStreetAddress.getText().toString());
card.setCity(txtCity.getText().toString());
card.setState((String) spinnerState.getSelectedItem());
card.setZip(txtZip.getText().toString());
card.setPhone(txtPhone.getText().toString());
card.setMonth(txtMonth.getText().toString());
card.setYear(txtYear.getText().toString());
card.setNumber(txtNum.getText().toString());
card.setCvv(txtcvv.getText().toString());
I've tried to come up with a way via UI tags in XML or other means to simplify/automate this process but I can't come up with an efficient means. Am I missing out on something?
Unfortunately, there isn't anything hard-wired into Android that will let you bind large chunks of data (as shown in your example) from UI in an elegant way, yet.
One thing you can do to make your code cleaner/more testable is "injecting" the fields i.e. "txtFullName.getText().toString()" into the CreditCard constructor. That way, you do not have superfluous "setter" code like you do in your example. However, you would still have a block of code when instantiating the Credit Card object:
CreditCard card = new CreditCard(arg1, arg2, arg3, arg4..etc)
Another thing you can do is use a dependency injection (DI) framework like Dagger. Dagger does the "injecting" of fields for you in Module(s) that you specify for your class(es), "behind the scene".
http://square.github.io/dagger/
EDIT: check out the new data binding feature released in Android Studio 1.3 (currently Beta)

android greendao update only specific fields in entity

i have been searching for a while for a solution to my problem without success.
I have an application in which I receive information for a particular entity in my database from different services, so I am using greenDAOs insertOrReplace methods so whenever the entity already exists in my DB it gets updated instead of recreated.
So far so good.
The problem is.. let's say for example sake my entity is called User, with fields id, title, and displayName.
So in the first call I get a JSON object containing a user with only its id and title fields, so I insert it into the DB and naturally the displayName gets inserted as NULL.
Afterwards from another service I get another JSON containing the same user (same id field), but it comes with the displayName as well, but doesn't include the title info at all.
So whenever I run the insertOrReplace on the DAO object automatically generated by greenDAO, the user gets updated but as the title info was not present, when it gets updated the title field gets reset to NULL, so I end up losing data.
Unfortunately I am unable to change the data being returned from the services, and haven't been able to fix this issue. I find it hard to believe there is no easy way to tell the DAO object to update only certain fields and no all of them.
I was looking at the code generated by greenDAO and in the dao objects generated there is a bindValues method which gets called before the query gets executed, and apparently it filters out the NULL properties from the object, but either way it gets updated with the NULL value.
I was able to come up with some sort of fix by modifying the final dao object being generated by adding some methods from the parent class, but I don't think this is a good solution because I would have to do this for all the dao objects. (I know it's possible to define a custom superclass but this only applies for the entity object and not the DAO one).
I would really appreciate if someone has any idea on how I could resolve this, and sorry for the long explanation, I just wanted to be clear on my issue.
Thanks.
First of all: I wouldn't tamper with the generated code unless you really know what you are doing. Modifications may have effects on caches and data-integrity.
Generally you are following this (insert-or)-update-approach if you are using a ORM-Framework (like greendao):
Try to get the entity, that you want to modify from the db (maybe it is already in cache, so this may not be a real database operation)
If you don't have such an entity: create it
Modify the entity according to your needs
Insert or Update it in database (in greendao you would use insertOrReplace)

xhange classes attributes in existing db4o in android

I'm considering to use db4o in my android project to store objects but my concern is if in the future I want to change one of the objects attributes how do i deal with the existing data of that object in the db4o file? I know in sqlite3 environment this can be done by altering the table structure in the onUpgrade() method, so how does db4o deal with this?
in db4o it really depends on what the changes are.
Adding field: You just add it. The new field will have the default value of that type. (null for references, 0 for numbers)
Removing a field: db4o will just ignore the removed field. You can access the old data of the removed field. As soon as you update the object the value of the old field will be removed.
Renaming fields and classes can be done with this call.
Changing the type of a field. That's like adding a new field. You need to copy the values over yourself. See here.
Adding interfaces has no effect on db4o.
Removing a type from the inheritance hirarchy: Not supported.
In general, take a look here.

Categories

Resources