/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.bordeaux.services;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.lang.System;
import java.util.concurrent.ConcurrentHashMap;
// This class manages the database for storing the session data.
//
class BordeauxSessionStorage {
private static final String TAG = "BordeauxSessionStorage";
// unique key for the session
public static final String COLUMN_KEY = "key";
// name of the learning class
public static final String COLUMN_CLASS = "class";
// data of the learning model
public static final String COLUMN_MODEL = "model";
// last update time
public static final String COLUMN_TIME = "time";
private static final String DATABASE_NAME = "bordeaux";
private static final String SESSION_TABLE = "sessions";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table " + SESSION_TABLE + "( " + COLUMN_KEY +
" TEXT primary key, " + COLUMN_CLASS + " TEXT, " +
COLUMN_MODEL + " BLOB, " + COLUMN_TIME + " INTEGER);";
private SessionDBHelper mDbHelper;
private SQLiteDatabase mDbSessions;
BordeauxSessionStorage(final Context context) {
try {
mDbHelper = new SessionDBHelper(context);
mDbSessions = mDbHelper.getWritableDatabase();
} catch (SQLException e) {
throw new RuntimeException("Can't open session database");
}
}
private class SessionDBHelper extends SQLiteOpenHelper {
SessionDBHelper(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 " + SESSION_TABLE);
onCreate(db);
}
}
private ContentValues createSessionEntry(String key, Class learner, byte[] model) {
ContentValues entry = new ContentValues();
entry.put(COLUMN_KEY, key);
entry.put(COLUMN_TIME, System.currentTimeMillis());
entry.put(COLUMN_MODEL, model);
entry.put(COLUMN_CLASS, learner.getName());
return entry;
}
boolean saveSession(String key, Class learner, byte[] model) {
ContentValues content = createSessionEntry(key, learner, model);
long rowID =
mDbSessions.insertWithOnConflict(SESSION_TABLE, null, content,
SQLiteDatabase.CONFLICT_REPLACE);
return rowID >= 0;
}
private BordeauxSessionManager.Session getSessionFromCursor(Cursor cursor) {
BordeauxSessionManager.Session session = new BordeauxSessionManager.Session();
String className = cursor.getString(cursor.getColumnIndex(COLUMN_CLASS));
try {
session.learnerClass = Class.forName(className);
session.learner = (IBordeauxLearner) session.learnerClass.getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Can't instantiate class: " + className);
}
byte[] model = cursor.getBlob(cursor.getColumnIndex(COLUMN_MODEL));
session.learner.setModel(model);
return session;
}
BordeauxSessionManager.Session getSession(String key) {
Cursor cursor = mDbSessions.query(true, SESSION_TABLE,
new String[]{COLUMN_KEY, COLUMN_CLASS, COLUMN_MODEL, COLUMN_TIME},
COLUMN_KEY + "=\"" + key + "\"", null, null, null, null, null);
if ((cursor == null) | (cursor.getCount() == 0)) {
cursor.close();
return null;
}
if (cursor.getCount() > 1) {
cursor.close();
throw new RuntimeException("Unexpected duplication in session table for key:" + key);
}
cursor.moveToFirst();
BordeauxSessionManager.Session s = getSessionFromCursor(cursor);
cursor.close();
return s;
}
void getAllSessions(ConcurrentHashMap<String, BordeauxSessionManager.Session> sessions) {
Cursor cursor = mDbSessions.rawQuery("select * from ?;", new String[]{SESSION_TABLE});
if (cursor == null) return;
cursor.moveToFirst();
do {
String key = cursor.getString(cursor.getColumnIndex(COLUMN_KEY));
BordeauxSessionManager.Session session = getSessionFromCursor(cursor);
sessions.put(key, session);
} while (cursor.moveToNext());
}
// remove all sessions that have the key that matches the given sql regular
// expression.
int removeSessions(String reKey) {
int nDeleteRows = mDbSessions.delete(SESSION_TABLE, "? like \"?\"",
new String[]{COLUMN_KEY, reKey});
Log.i(TAG, "Number of rows in session table deleted: " + nDeleteRows);
return nDeleteRows;
}
}