main idea
This is how I do it. I assume that the client application does not make changes to the local database (unless it downloads the new version), so there are only a few possible versions of the database (one for each made a change on the server).
- Add a column to each table named
LastModified with a default value of NOW() . This means that every time you add something to your main copy, it gets an updated LastModified setting. You will need to make sure that your updates (and not inserts) also modify the LastModified field. - Store somewhere in the database (a
Settings table or something else) a field that tracks the publication date of this version of the database on the server (name it PublishDate ). - When a client wants to check the new version, he sends it to
PublishDate to the server. The server then checks each table and finds each row where LastModified appears after PublishDate . It sends SQL to the client to insert or update these rows on the client. It also sends a new PublishDate so that the client can update it in its local copy.
This applies to inserts and updates. This does not apply to deletion. Perhaps this is not a problem in your case; if they:
- Add a separate log deletion table, where you also track
LastModified so you can tell the client which rows to delete; or it is preferable to have a setting in which you never delete any lines, but simply update them so that they are marked as “deleted”.
Finally, this will not handle schema changes. Again, I hope this is not a problem in your case: I hope you have a stable circuit. But if you need to add or delete tables or indexes or something else, you need to do this separately:
- Create a
SchemaChanges table on your host and whenever you make structural changes, put the appropriate data in the SchemaChanges table along with the LastModified date LastModified that you can send it to the client on request too. If you do this, first you will want to first send the schema changes to the client, because they can affect the meaning of the other changes.
Now the good thing is to do this so that you can pre-process everything on the server (because there are only a few versions). For each old version, you can calculate the changes (based on the details above) that will use this old version until the new version, and then save the resulting SQL on the server. If you do this, you avoid the need to generate SQL on the fly: when the client sends PublishDate , you simply look at the SQL that you have already calculated, which will convert the version from this PublishDate to the latest version.
Alternative implementation
There is a good and easy way to push the changes that the above diagram gives you, even with a little simplification that does not require LastModified times, as well as no changes to your existing structure. On the server, where you already have the old version (because you have all the old versions) and the new version, you dump SQL for both databases, and then run diff on top of them to create a patch file that you can send client attachment. The client application will use the same Java library to dump the old version of SQL and then apply the diff patch to it to create a full SQL dump for the new version. At this point, he can delete the old database and create a new one from the SQL dump.
This will be very effective if the changes are not optional changes (in this case, you can simply click on the new .db file).
This is fairly easy to do with a SQLite binary call to dump. You will need to slightly change the approach for Android in accordance with this way of executing an external command.
You can use this Google library to calculate diff patches on the server and apply them on the client side.
source share