Saturday, April 14, 2012

ORMLite

After finishing creating everything with generic classes, I was trying to upgrade my design, so that the developer could create multiple tables and relations between them. While documenting, I walked into ORMLite. This is the ORM for SQLite. I found it so easy to use and developer friendly, that I thought of giving it a try.

You can add it very easily to your project - just download the 2 needed jars from ormlite.com (ormlite-core.jar and ormlite-android.jar - version 4.39 at the time of this post) and everything will work like a charm. What you need to do is Annotate your Classes using ORMLite Annotations or javax.persistence Annotations. The next step is to configure a DAO, but for more examples and information use this link.

What got me thinking about ORMLite is the size of it - approximately 250KB. Since I don't really need all the options that ORMLite offers, I started working on my own ORM (very simple one). I created some custom Annotations for my classes, but what I am working now on is dealing with Content Provider, which is mostly used with databases with single tables, and even if you have multiple tables, the most common way to distinguish between them is through URIs. I cannot do this, because I only have the name and number of the tables at run-time, when the Content Provider has already been initialized.

Currently I can create the query for creating a new table, but I don't get the chance to use it. I will write in the future about the solution I found. I hope I will find something better than rawQuery.

The steps I want to follow in the near future are:

  • Update the Content Provider so that it can work with multiple tables 
    • create tables at run-time
    • update the needed URIs used in Content Provider
  • Use C2DM to update the SQLite database. Currently I am only receiving "Hello world" messages from the server. 

Tuesday, April 3, 2012

Future requirements - API

I was preoccupied by the graphics of the application, although this was not the main idea behind this project. I should focus more on creating the needed API, than some fancy application. The developer using my API should be able to create, read, update and delete some data from the SQLite Database, and the backup to Google App Engine will be made transparently by the API.

So I created a new application, which simulates the creation of a developer and uses it to back everything up to Google App Engine. I use Generic Classes, so no matter what fields the developer's class will have, everything will work just fine. I do this by creating a JSON file with the fields of the class:

private <T> String createJsonFile(Class<T> Kind) {
    String json;

    /*Get all fields, including the private ones*/
    Field[] fields = Kind.getDeclaredFields();
    int fieldsNo = fields.length;

    /*For each field, add to the JSON String the field's name*/
    for (Field field : fields) {
        fieldsNo--;
        json += "\"" + field.getName() + "\"";
        if (fieldsNo != 0)
            json += ",";
    }
    return json;
}
So these are the steps that I should follow while redesigning the application:
  • Create JSON file from Class.
  • Create SQLite Database with this structure (the table should have the same fields).
  • Update the server concerning the schema.
    • POST the JSON file
  • Add one item to SQLite Database.
  • Read/Modify/Delete items from SQLite Database.
  • Synchronize the server when needed. 

These are small steps which I began already to implement. The last step can be further divided into smaller steps, but this is what I plan for now. It shouldn't be to difficult to implement, considering that most of it I already have, but I need to reorganize things.

An image with how should all look like is this one:

Sunday, March 25, 2012

Use Case and ACLs

These last two weeks I have been working mostly on the design of the application. This is what I currently have:

  • One activity where the user can select between two different google accounts - this has to be modified, so that the application can only use one account. 
  • One tab layout with two tabs, each of them being an activity.
    • The first tab allows the user to see what they have in the database - also has for each entry an ImageButton, which, when clicked, deletes the selected entry. 
    • The second tab allows the user to add an entry to the database. It contains of one simple EditText, one multiline EditText and one DatePicker
Next, I am going to demonstrate an Use Case - Add and Delete of a task. 
The user has in the database two tasks, a Meeting and an Exam. In the next step I add a task, named Conference.


The new Task is now visible in the first tab. Next I delete the task named Meeting by clicking on the ImageButton.

This what the user has in the database at the end.

I had a hard time creating a multiline EditText, but I realized the problem was that I was disabling the virtual keyboard:
/*Get the EditText for task description*/
note = (EditText) findViewById(R.id.note);
/*Hide virtual keyboard*/
note.setInputType(InputType.TYPE_NULL);
When the virtual keyboard is disabled, the EditText will be singleline (setting the inputType to textMultiLine has no effect in this case). I solved this by removing the code which disables the keyboard, and adding in the xml file android:editable="false".
<EditText
    android:id="@+id/note"
    android:hint="Description..."
    android:layout_width="fill_parent"
    android:layout_height="100dip"
    android:gravity="top|left"
    android:inputType="textMultiLine"
    android:editable="false">
</EditText>
For next week, I discussed with my colleague and we are going to start implementing Access Control Lists. On the server side, he currently has implemented namespaces, but only the basic approach - every user has one namespace. We are going to allow users to create groups and add other members to the group. For this, I am going to have an Administrator option in the menu, where the user can create new groups.

Another important thing about this approach is that the users must have assigned roles. For example, the owner of the group will be able to add and delete tasks from the common database of the group. He is going to be the group administrator. Simple members cannot delete or add tasks. In the future, we are thinking about enabling administrators to add another administrators to the group. 

All members of one group share the same namespace, so they share the data from the database. This feature is very important for companies for example, which prefer to have a common database for all employees. Monitoring the activity and maintenance is a lot easier.

Tuesday, March 13, 2012

This week's future work

Writing the goals for a week and then checking the result is a great way to monitor the progress of what I do. This is exactly what I am going to do, so that efficiency is maximum. What I want to accomplish this week is:

Finish the client application design. I currently have an application which displays the google accounts that the user has in his phone, and when one of them is clicked, an activity creates two tabs.

The first tab is selected by default, and here it should appear the user's database from the cloud. Currently this is not happening. When the second tab is selected, the user should be able to add a Task to his database (and the server database should be updated). This also is not yet available.
  • When the first tab is selected, the application displays the user's database from the cloud. 
    • Find a way to return to the main Activity the authenticated HttpClient (so I can use it then with GET, POST or any method that the user tries to make).
    • When setListAdapter is called, the result should be displayed in the first tab activity in a pleasant way.
  • Make the graphic design for the second tab
    • Add 3 EditTexts and a button to add the Task.
    • The user should be able to select the date in a familiar way, something like Date Picker
    • When the button is clicked, the server database should be updated and the server database should also contain the new added Task.
My biggest problem last week was Authentication. A client can only call the GET method if he is authenticated (my colleague did the authentication with google accounts for the server). I tried different methods to authenticate, not knowing the best one. I also had troubles finding the best approach:
  • At the beginning I tried to authenticate in a different activity, but I realized this is not appropriate for what I am trying to do ( I don't need a new Activity, as the work should be done in background, without interacting with the user )
  • Next, I tried using a Service, but as I found out, a Service should be used if the background job is  some CPU intensive time consuming job.
  • What I am trying now is with AsyncTask. I am having problems sending results from the new thread to the UI thread, though. 
This issue is first on my To Do list, I will let you know my results. 

Thursday, March 1, 2012

Work breakdown structure

A work breakdown structure (WBS) is a decomposition of a project into smaller parts. This kind of structure is useful because it helps you keep track of your progress, and also with every little step you make you feel more confident and closer to the expected result. My project can be divided into these components:
  1. An application which at initialization synchronizes the local database with the cloud database automatically. Each time one client modifies a data, the client database stored on the server is updated accordingly, copying the whole database on the server.
    • initialize the local database when the client application starts - 1 hour
    • implement all the methods (POST, PUT, DELETE, GET) with AsyncTask, so with different threads - 2 hours
    • change the application design - from adding contacts to adding tasks - 3 hours
    • redo the graphic design - 1 day
  2. The difference between this application and the one before is that when a client modifies a data on the local database, the server copy is updated only with Delta updates (so it copies only the data that was modified, not the whole database). This will significantly save time and bandwidth. - 2 days
  3. The Internet connection is not always available, so the client must support offline work. When the connection becomes available, the databases are synchronized. - 1 day
This is only for the near future. When I finish these tasks I will update the blog, writing the next steps. 

Thursday, February 16, 2012

Requirements and restrictions

I made a list with the functional requirements of this project. Basically, this is what the system must do at the end:

  • The application is going to use the Internet connection, so the client should have one.
  • The client should have SQLite (it is already installed on every Android).
  • Database must be: scalable, replicable and accessible from cloud.
  • The user will be able to create/read/update/delete the data from the SQLite database.
  • The communication between the client and the server will be made through REST architecture.
  • The server will push information through C2DM, letting the client know that something has changed in the database. When receiving the message, the client will read the database from the server and modify his own accordingly.
  • The client will store only a part of the database which exists on the server (the most probable to be used data).
  • The system should make a difference between different connections
    • For example – when using GPRS the system should use cache and when using WiFi the system should not cache the data.
  • The user should be able to force relations between tables in the database.
  • The structure sent between the client and the server will be in JSON format.
    • The best way would probably be to use the GSON library to convert Java Objects in their JSON representation.
  • The client should support offline work.
    • When there is not an available Internet connection, the modifications will only be visible in the local database. When an Internet connection becomes available, the client should work with replication (send over the connection the modified data).
  • For solving the replication we chose the simplest approach, the client which last modified the data (the most recent timestamp) is the winner.

There are a number of restrictions that I will enforce at the beginning, so that I can cover the most simple application. When the most simple case is working, I will remove one restriction and go for a more complicated solution.
  1. The database stored in the cloud for one client fits entirely in the device memory.
  2. The cloud database can only be accessed by Android, so no other Operating System.
  3. There will not be 2 clients trying to modify the data at the same time - every time a client modifies something, the devices have time to synchronize.
  4. There will always be available an Internet connection.
  5. When a client modifies something in the local database, the whole database is copied on the server, so I will not use Delta updates.

Friday, February 10, 2012

SQLite

The Android framework uses a concept called Content Provider to allow applications to share and use data across the platform. Typically, this Content Provider is backed by a SQLite Database where the data is actually stored.

A few days ago I saw a presentation of SQLite, actually a Google TechTalk made by it's developer, Richard Hipp, on May 31, 2006. I really liked it, so I wrote down some important features of SQLite:

  • it's very small and compact (the code footprint has less than 250KB)
  • serverless (writes directly to the disk drive)
  • the database is contained in a single disk file
  • zero-configuration (there is no need of setup or administration)
  • you can read/write the database file with fopen(), fread(), fwrite()
  • transactions satisfy ACID (atomicity, consistency, isolation, durability)

There are also some unusual features of SQLite:
  • tends to ignore the data types (you can type whatever you want in every column - inspired by scripting languages)
  • type affinity
    • Example: If the type of a column is integer and you want to put there a string, if the string looks like an integer, it will be automatically converted, and if not, it will be stored as a string.
  • ability to talk to multiple databases simultaneously (you can join 2 tables from 2 databases)

I managed to create a simple application which adds a person's first name and last name in a database using Content Provider. The user can see the data in the database on the screen, delete or add items. It looked pretty simple at first, but it took a whole day to actually realize how everything worked. 

Next step for me concerning the development of the application is to try to store some pictures in the database (binary data) and to use the CRUD functions that are implemented by parallel thesis. Also I must describe the requirements for my project.