Android DataServices – SQLite

You’ve made your way through the Android ‘Notepad‘ tutorial, but find yourself wanting more?  Maybe you want to deal with Typed Objects instead of all of these strings everywhere? While this code isn’t generic enough to paste into your app and use as-is, it is simple enough to adapt to your own typed objects.  Using the Interface described here makes it super easy to change the way you are storing your data, without having to refactor your app itself (imagine a hybrid online/offline storage, or as we’ll see in the next post, an Object Oriented DataBase[OODB]).

If you’d like to follow along in eclipse, source code is found here: http://svn.hat6.com/hat6public/DataServiceExample/trunk.

We’re only looking at one file here, ReminderSQLiteImpl.java. I’ve tried to make certain that the comments explain everything, so I’m just dumping the code below. This class comes in at about twice the size of the Notebook’s DBAdapter class, but most of that comes from my class storing more columns of data.

/**... imports removed ...**/
public class ReminderSQLiteImpl implements IReminderDataService {
	/**
	 * Static variables describing our schema.  We use these variables so that we can refer to the
	 * constants instead of having to worry about refactoring when our schema changes.
	 */
	public static final String KEY_ROWID = "_id";
    public static final String KEY_TITLE = "title";
    public static final String KEY_ICON = "icon";
    public static final String KEY_STARTDATE = "startDate";
    public static final String KEY_ENDDATE = "endDate";
    public static final String KEY_MODIFIED = "modified";
    //TAG for logging.
    private static final String TAG = "ReminderSQLiteImpl";
    /**
     * Static variables holding information about our database itself.
     * NAME and TABLE are self explanatory.
     * VERSION allows our app to know if it has to perform any upgrades (right now it's
     * 		simply dropping the entire table and all associated data).
     * CREATE allows us to specify the SQL needed to create our DB.
     */
    private static final String DATABASE_NAME = "hatsixExamples";
    private static final String DATABASE_TABLE = "remindersDS";
    private static final int    DATABASE_VERSION = 1;
    private static final String DATABASE_CREATE =
        "create table " + DATABASE_TABLE + " (" + KEY_ROWID + " INTEGER primary key autoincrement, "
                + KEY_TITLE + " TEXT not null, "
                + KEY_STARTDATE + " TEXT, "
                + KEY_ENDDATE + " TEXT, "
                + KEY_MODIFIED + " DATE not null"
                + ");";

	/**
	 * Context is needed when interacting with the DB
	 */
	private final Context mCtx;
	/**
	 * DatabaseHelper is a private class, defined at the end of this file.
	 */
    private DatabaseHelper mDbHelper;
    /**
     * The actual Database.
     */
    private SQLiteDatabase mDb;

    /**
     * Constructor - takes the context to allow the database to be
     * opened/created
     *
     * @param ctx the Context within which to work
     */
    public ReminderSQLiteImpl(Context ctx) {
		mCtx = ctx;
		open();
	}

    /**
     * Open the database. If it cannot be opened, try to create a new
     * instance of the database. If it cannot be created, throw an exception to
     * signal the failure
     *
     * @return this (self reference, allowing this to be chained in an
     *         initialization call)
     * @throws SQLException if the database could be neither opened or created
     */
    public ReminderSQLiteImpl open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        mDbHelper.close();
    }

    /**
     * Create a new reminder record.  We pass in a Reminder, rather than just
     * some text values like in the Notepad Example. If the reminder is
     * successfully created return the new rowId for that reminder, otherwise return
     * a -1 to indicate failure.
     *
     * @param r the Reminder we want saved.
     * @return rowId or -1 if failed
     */
    public long createReminder(Reminder r) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_TITLE, r.getTitle());
        initialValues.put(KEY_STARTDATE, r.getStart());
        initialValues.put(KEY_ENDDATE, r.getEnd());
        initialValues.put(KEY_MODIFIED,convertDateToString(new Date()));

        return mDb.insert(DATABASE_TABLE, null, initialValues);
    }

    /**
     * Fetch all Reminders.  This will utilize SQLite's cursors and create an ArrayList
     * that is passed back to the caller.
     *
     * @return List of Reminders
     */
    public List<Reminder> fetchAllReminders(){
    	Cursor cursor = fetchAllRemindersCursor();
        int idColumn = cursor.getColumnIndex(KEY_ROWID);
        int titleColumn = cursor.getColumnIndex(KEY_TITLE);
        int startColumn = cursor.getColumnIndex(KEY_STARTDATE);
        int endColumn = cursor.getColumnIndex(KEY_ENDDATE);

        List<Reminder> list = new ArrayList<Reminder>();
    	if(cursor != null){
            if(cursor.moveToFirst()){

                int count = cursor.getCount();
                Log.d("ReminderSqliteImpl", "there are " + count + " records.");

                for(int i=0; i<count; i++){
                    Reminder reminder = new Reminder();
                    reminder.setId(cursor.getLong(idColumn));
                    reminder.setTitle(cursor.getString(titleColumn));
                    reminder.setStart(cursor.getString(startColumn));
                    reminder.setEnd(cursor.getString(endColumn));

                    list.add(reminder);

                    cursor.moveToNext();
                }
            }
        }
    	return list;
    }
    /**
     * Fetch Individual Reminder.  We take the 'query by example' approach, where we pass in
     * a Reminder.  This would allow us to query by Title if id wasn't set.
     *
     * @param r Reminder with id set to the Reminder we want fetched.
     * @return Reminder that was passed in, with data filled out from query.
     */
    public Reminder fetchReminder(Reminder r){
    	Cursor cursor = fetchReminderCursor(r.getId());
        int idColumn = cursor.getColumnIndex(KEY_ROWID);
        int titleColumn = cursor.getColumnIndex(KEY_TITLE);
        int startColumn = cursor.getColumnIndex(KEY_STARTDATE);
        int endColumn = cursor.getColumnIndex(KEY_ENDDATE);
    	if(cursor != null){
            r.setId(cursor.getLong(idColumn));
            r.setTitle(cursor.getString(titleColumn));
            r.setStart(cursor.getString(startColumn));
            r.setEnd(cursor.getString(endColumn));
    	}
    	return r;
    }
    /**
     * Update the reminder using the details provided. We pass in a
     * Reminder, create ContentValues from that Reminder, then update
     * the record based on rowID
     *
     * @param r the Reminder to update
     * @return true if the reminder was successfully updated, false otherwise
     */
    public boolean updateReminder(Reminder r) {
        ContentValues args = new ContentValues();
        args.put(KEY_TITLE, r.getTitle());
        args.put(KEY_STARTDATE, r.getStart());
        args.put(KEY_ENDDATE, r.getEnd());
        args.put(KEY_MODIFIED,convertDateToString(new Date()));

        return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + r.getId(), null) > 0;
    }

    /**
     * Delete the reminder.  Rather than passing in the rowID, we pass the entire
     * reminder.  Again, by passing objects, our app is significantly simplified.
     *
     * @param r the Reminder to be deleted.
     * @return true if deleted, false otherwise
     */
    public boolean deleteReminder(Reminder r) {

        return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + r.getId(), null) > 0;
    }

    /**
     * Return a Cursor over the list of all reminders in the database.
     * This is more of a convenience function, as we don't allow outside
     * classes to use it anymore
     *
     * @return Cursor over all reminder
     */
    private Cursor fetchAllRemindersCursor() {

        return mDb.query(DATABASE_TABLE, new String[] {
        			KEY_ROWID,
        			KEY_TITLE,
        			KEY_STARTDATE,
        			KEY_ENDDATE,
        			KEY_MODIFIED
        			}, null, null, null, null, null);
    }

    /**
     * Return a Cursor positioned at the reminder that matches the given rowId
     * Again, a convenience function, as we don't allow outside classes ot use it
     *
     * @param rowId id of reminder to retrieve
     * @return Cursor positioned to matching reminder, if found
     * @throws SQLException if reminder could not be found/retrieved
     */
    private Cursor fetchReminderCursor(long rowId) throws SQLException {

        Cursor mCursor =

                mDb.query(true, DATABASE_TABLE, new String[] {
            			KEY_ROWID,
            			KEY_TITLE,
            			KEY_STARTDATE,
            			KEY_ENDDATE,
            			KEY_MODIFIED
            			}, KEY_ROWID + "=" + rowId, null,
                        null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }

    /**
     * convertStringToDate will take a Sqlite String and convert it to a date
     * @param s String to convert to Date
     * @return Date object
     */
	private Date convertStringToDate(String s){
		Date date = null;
		DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date = iso8601Format.parse(s);
		} catch (ParseException e) {
			Log.e("Reminder.convertStringToDate", "Parsing ISO8601 datetime failed", e);
		}
		return date;
	}

	/**
	 * convertDateToString will take a Date object and return a SQLite date string
	 * @param date Date
	 * @return String
	 */
	private String convertDateToString(Date date){
		long when = date.getTime();
		int flags = 0;
		flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
		flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
		flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
		flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;

		String finalDateTime = android.text.format.DateUtils.formatDateTime(mCtx,
				when + TimeZone.getDefault().getOffset(when), flags);

		return finalDateTime;

	}

    /**
     * DatabaseHelper basically copied from Androids NotebookExample.
     * Here we short-circuit some functions to make our above code
     * more readable.
     */
    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME);
            onCreate(db);
        }
    }

}

2 comments ↓

#1 Android DataServices – DB4O — h6 – HatSix on 12.05.09 at 8:06 pm

[...] ← Android DataServices – SQLite [...]

#2 Android DataServices — h6 – HatSix on 12.05.09 at 8:42 pm

[...] Android DataServices – SQLite → [...]

what is term life insurance
taxes on life insurance
global life insurance
new york life insurance
Banlieue 13 Watch Online
universal life insurance company
types of life insurance
evergreen life insurance
life insurance on business
discount term life insurance
Be Kind Rewind Watch Online
limited pay life insurance
life insurance with no medical
connecticut general life insurance co
allstate life insurance
london life insurance edmonton alberta canada
Balls of Fury Watch Online
metropolitan life insurance co
free life insurance quote
canada life insurance
life insurance secrets
decreasing life insurance
life investors insurance
insurer disclaims life insurance coverage
hartford life insurance company
level term life insurance
life insurance over 50
life insurance without medical exam
life insurance coverage denied
protective life health insurance
gauranteed life insurance
life insurance on business taxes
texas life insurance company
bankers life insurance
skandia life insurance
Boy A Watch Online
sun life insurance company
northwestern mutual life insurance
life insurance dividends cash value
what is universal life insurance
american family life insurance
mutual life insurance companies
aviva life insurance
standard life insurance company
nationwide life insurance
split dollar life insurance
Bangkok Dangerous Watch Online
aids life insurance
Backdraft Watch Online
aarp term life insurance
mega life and health insurance company
life insurance training school bellevue washington
dividend insurance life whole
sue life insurance company
Airplane! Watch Online
globe life insurance service center
best life insurance
A Few Good Men Download
Battle of the Bulge Watch Online
first to die life insurance
second to die life insurance
pet insurance for life
life insurance statistics
term life insurance no medical exam
A Nightmare on Elm Street Download
A Beautiful Mind Download
life insurance company failures
sterling life insurance
life insurance no exam
nys life insurance guarantee corp
denied life insurance
federal employees group life insurance
home auto life business insurance
american general life insurance credit rating
monumental life insurance company
valley forge life insurance
life insurance cost
metropolitan life insurance
life insurance whole life
american general life insurance danville va
gulf life insurance
life insurance renewal training in connecticut
Behind Enemy Lines Watch Online
what is life insurance
reliastar life insurance company
life insurance company ratings
life insurance trust
pacific life insurance company
life insurance agents
stonebridge life insurance
ranking of life insurance companies
unison life insurance
whole life insurance quotes
life insurance ads
valley forge life insurance company
washington state life insurance renewal
central united life insurance company
financial american life insurance company
Big Trouble in Little China Watch Online
american general life insurance company
Body Heat Watch Online
life insurance denial lawsuit
american life insurance
life insurance courses
define term life insurance
hartford life insurance employee
life insurance basics
great american life insurance company
national life insurance richland hills tx
Blood Diamond Watch Online
zurich life insurance
veterans group life insurance
midland mutual life insurance
principle life insurance
whole of life insurance
cheap life insurance
tracking life insurance policies
Beautiful Girls Watch Online
isaiah life insurance
beneficial life insurance
life insurance commissions
life insurance quote
term life insurance company
Blade Runner Watch Online
connecticut life insurance renewal classes
whole life insurance quote
mortgage life insurance
compare life insurance
life insurance law
investment grade indexed universal life insurance
t-d n-s life insurance rating
online life insurance quotes
A History of Violence Download
term life insurance website
life insurance no medical exam
life insurance and irrevocable trusts
Blue Thunder Watch Online
life insurance policy in san francisco
pruco life insurance
american general life insurance
gerber life insurance
Blue Streak Watch Online
connecticut life insurance renewal of license
guardian life insurance
american general life insurance co
phoenix life insurance
life insurance settlement
new york life insurance company
life insurance for teenren
life insurance term
principal mutual life insurance
homesteaders life insurance
aviva life insurance 2009 complaints
ing life insurance and annuity company
kansas city life insurance company
life insurance license renewal in connecticut
instant term life insurance
cheap term life insurance
protective life insurance co
american travelers life insurance
lincoln life insurance company
western southern life insurance
whole life insurance policy
life insurance claim
kotak life insurance
branch offices of london life insurance
life insurance coverage
genworth life insurance company
life insurance sales leads
no medical exam life insurance
Black Hawk Down Watch Online
allianz life insurance
american life insurance company
guaranteed acceptance life insurance
reliance standard life insurance
combined life insurance
term life insurance quotes
life insurance corporation
great american life insurance
history of life insurance
life insurance coverage attorneys
globe life insurance
how does life insurance work
A Knights Tale Download
low cost life insurance
term life insurance
cash value life insurance
georgia allstate life insurance
life insurance calendar system
life insurance coverage lawyers
survivorship life insurance
life insurance in wales
principal life insurance
mega life and health insurance
over 50s life insurance
life insurance devide
southland life insurance company
life insurance scam dacey
transamerica life insurance co
veterans life insurance
taylor v national life insurance co
bankers casualty and life insurance
life insurance residual income
life insurance quotes
lost life insurance policy
top life insurance companies
ratings hartford life insurance company
life insurance claim rejected
term life insurance rates
Batman Watch Online
federal employee life insurance plans
american international life insurance
dai-ichi life insurance advertising
life insurance comparisons
john hancock life insurance company
safeco life insurance headquarters seattle wa
dispute life insurance claim
printed life insurance ads
monumental life insurance
crump life insurance
surety life insurance company
joint whole life insurance
life insurance ratings
columbus ohio life insurance companies
shenandoah life insurance
liberty national life insurance company
Black Rain Watch Online
presential life insurance co
Blue Velvet Watch Online
cancelling life insurance
empire life insurance homepage
life insurance for over 50s
genworth life insurance fixed annuity
life insurance comparison
aig life insurance
group universal life insurance
integon life insurance
liberty life insurance
allstate life insurance company
life insurance dispute litigation
west coast life insurance company
midland national life insurance
Baraka Watch Online
Battle of Britain Watch Online
mass mutual life insurance
level term life insurance quotes
selling life insurance
government federal employee life insurance
jackson life insurance
indexed universal life insurance
Big Daddy Watch Online
the paul revere life insurance
no medical life insurance
life insurance company of north america
vermont life insurance
term life insurance quote
liberty national life insurance
lafayette life insurance company
life insurance taxable
life insurance malaysia
life insurance lawsuit
life insurance ads
high risk life insurance
dai-ichi life insurance
dispute life insurance claim denial
met life insurance
life insurance types
life term insurance
sun life insurance
advertising life insurance in japan
aetna life insurance
cheap life insurance 55
get cash for life insurance
wife as beneficiary of life insurance
national life insurance company
peoples benefit life insurance
globe life insurance quote
penn mutual life insurance
country life insurance company
irrevocable life insurance trust
term life insurance rate
ninja life insurance
aaa life insurance company
life insurance premium financing
unclaimed life insurance
shenandoah life insurance company
life insurance scam williams
variable life insurance
over 50 life insurance
A Time to Kill Watch Online
met life auto insurance
guardian life insurance company
globe life and accident insurance company
western southern life insurance company
life insurance calculator
united of omaha life insurance
reassure america life insurance company
Being There Watch Online
instant term life insurance quote
farmers mutual life insurance
split-dollar life insurance
life insurance texas
prime america life insurance
gleaner life insurance
insurance life insurance
liberty life insurance company
protective life insurance company
lincoln national life insurance company
Amadeus Watch Online
stonebridge life insurance company
uk life insurance
life insurance online
denied life insurance claim attorney
florida life insurance
franklin life insurance
Alpha Dog Watch Online
life insurance leads
life insurance rates
american investors life insurance company
life insurance companies
american health and life insurance company
life insurance claims lawyer
american heritage life insurance company
pan american life insurance co
metropolitan life insurance company
agent payout for life insurance
first colony life insurance
Back to School Watch Online
Batman Forever Watch Online
denied life insurance policy
life insurance health screening
insurance life mortgage online quote
savings bank life insurance
whole life insurance explained
what is whole life insurance
credit life insurance
california life insurance
northwestern mutual life insurance havre montana
cash value on life insurance policies
american fidelity life insurance company
fidelity life insurance companies
connecticut general life insurance
life insurance policy
co-operators life insurance
philadelphia united life insurance company
insurer rejected life insurance claim
Babylon A.D. Watch Online
pennsylvania life insurance
Batman Returns Watch Online
loans against whole life insurance
international life insurance co
american income life insurance company
Babel Watch Online
mega life insurance
creditors and life insurance
conseco life insurance
american heritage life insurance co
transamerica life insurance
national benefit life insurance company
amex life insurance co
mutual of omaha life insurance
public domain life insurance by name
riversource life insurance
life insurance au
homesteaders life insurance
colonial life insurance
scottish widows life insurance
morgage life insurance
instant life insurance
met life insurance company
sign on to globe life insurance
lincoln life insurance
Bobby Watch Online
life accident insurance
life insurance confirmation
life insurance bring back rule
nippon life insurance
who has received life insurance payouts
standard life insurance
american income life insurance
unum life insurance
reliastar life insurance
no exam life insurance
life insurance brokers
life insurance company
cuna mutual life insurance
life insurance no medical
rio grande national life insurance
Beowulf Watch Online
Across the Universe Watch Online
aetna life insurance company
midwestern united life insurance company
reverse life insurance
banner life insurance
fep life insurance program
empire life insurance homepage overland kansas
hartford life insurance
west coast life insurance
ohio national life insurance
Bolt Watch Online
life insurance corporation of india
london life insurance company edmonton branch
colonial penn life insurance
life insurance with no physical exams
affordable life insurance
national service life insurance
mississippi life insurance exam test
failure to pay life insurance