blob: 9979d84def3834f3d36790a019ee9fae8f2f752d [file] [log] [blame]
Wei Hua1dd8ef52012-03-30 15:15:12 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.bordeaux.services;
18
19import android.content.ContentValues;
20import android.content.Context;
21import android.database.Cursor;
22import android.database.SQLException;
23import android.database.sqlite.SQLiteDatabase;
24import android.database.sqlite.SQLiteOpenHelper;
25import android.util.Log;
26
27import java.lang.System;
28import java.util.concurrent.ConcurrentHashMap;
29
30// This class manages the database for storing the session data.
31//
32class BordeauxSessionStorage {
33
34 private static final String TAG = "BordeauxSessionStorage";
35 // unique key for the session
36 public static final String COLUMN_KEY = "key";
37 // name of the learning class
38 public static final String COLUMN_CLASS = "class";
39 // data of the learning model
40 public static final String COLUMN_MODEL = "model";
41 // last update time
42 public static final String COLUMN_TIME = "time";
43
44 private static final String DATABASE_NAME = "bordeaux";
45 private static final String SESSION_TABLE = "sessions";
46 private static final int DATABASE_VERSION = 1;
47 private static final String DATABASE_CREATE =
48 "create table " + SESSION_TABLE + "( " + COLUMN_KEY +
49 " TEXT primary key, " + COLUMN_CLASS + " TEXT, " +
50 COLUMN_MODEL + " BLOB, " + COLUMN_TIME + " INTEGER);";
51
52 private SessionDBHelper mDbHelper;
53 private SQLiteDatabase mDbSessions;
54
55 BordeauxSessionStorage(final Context context) {
56 try {
57 mDbHelper = new SessionDBHelper(context);
58 mDbSessions = mDbHelper.getWritableDatabase();
59 } catch (SQLException e) {
60 throw new RuntimeException("Can't open session database");
61 }
62 }
63
64 private class SessionDBHelper extends SQLiteOpenHelper {
65 SessionDBHelper(Context context) {
66 super(context, DATABASE_NAME, null, DATABASE_VERSION);
67 }
68
69 @Override
70 public void onCreate(SQLiteDatabase db) {
71 db.execSQL(DATABASE_CREATE);
72 }
73
74 @Override
75 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
76 Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
77 + newVersion + ", which will destroy all old data");
78
79 db.execSQL("DROP TABLE IF EXISTS " + SESSION_TABLE);
80 onCreate(db);
81 }
82 }
83
84 private ContentValues createSessionEntry(String key, Class learner, byte[] model) {
85 ContentValues entry = new ContentValues();
86 entry.put(COLUMN_KEY, key);
87 entry.put(COLUMN_TIME, System.currentTimeMillis());
88 entry.put(COLUMN_MODEL, model);
89 entry.put(COLUMN_CLASS, learner.getName());
90 return entry;
91 }
92
93 boolean saveSession(String key, Class learner, byte[] model) {
94 ContentValues content = createSessionEntry(key, learner, model);
95 long rowID =
96 mDbSessions.insertWithOnConflict(SESSION_TABLE, null, content,
97 SQLiteDatabase.CONFLICT_REPLACE);
98 return rowID >= 0;
99 }
100
101 private BordeauxSessionManager.Session getSessionFromCursor(Cursor cursor) {
102 BordeauxSessionManager.Session session = new BordeauxSessionManager.Session();
103 String className = cursor.getString(cursor.getColumnIndex(COLUMN_CLASS));
104 try {
105 session.learnerClass = Class.forName(className);
106 session.learner = (IBordeauxLearner) session.learnerClass.getConstructor().newInstance();
107 } catch (Exception e) {
108 throw new RuntimeException("Can't instantiate class: " + className);
109 }
110 byte[] model = cursor.getBlob(cursor.getColumnIndex(COLUMN_MODEL));
111 session.learner.setModel(model);
112 return session;
113 }
114
115 BordeauxSessionManager.Session getSession(String key) {
116 Cursor cursor = mDbSessions.query(true, SESSION_TABLE,
117 new String[]{COLUMN_KEY, COLUMN_CLASS, COLUMN_MODEL, COLUMN_TIME},
118 COLUMN_KEY + "=\"" + key + "\"", null, null, null, null, null);
saberian7b5b77b2012-06-04 11:19:43 -0700119 if ((cursor == null) | (cursor.getCount() == 0)) {
120 cursor.close();
121 return null;
122 }
Wei Hua1dd8ef52012-03-30 15:15:12 -0700123 if (cursor.getCount() > 1) {
saberian7b5b77b2012-06-04 11:19:43 -0700124 cursor.close();
Wei Hua1dd8ef52012-03-30 15:15:12 -0700125 throw new RuntimeException("Unexpected duplication in session table for key:" + key);
126 }
127 cursor.moveToFirst();
saberian7b5b77b2012-06-04 11:19:43 -0700128 BordeauxSessionManager.Session s = getSessionFromCursor(cursor);
129 cursor.close();
130 return s;
Wei Hua1dd8ef52012-03-30 15:15:12 -0700131 }
132
133 void getAllSessions(ConcurrentHashMap<String, BordeauxSessionManager.Session> sessions) {
134 Cursor cursor = mDbSessions.rawQuery("select * from ?;", new String[]{SESSION_TABLE});
135 if (cursor == null) return;
136 do {
137 String key = cursor.getString(cursor.getColumnIndex(COLUMN_KEY));
138 BordeauxSessionManager.Session session = getSessionFromCursor(cursor);
139 sessions.put(key, session);
140 } while (cursor.moveToNext());
141 }
142
143 // remove all sessions that have the key that matches the given sql regular
144 // expression.
145 int removeSessions(String reKey) {
146 int nDeleteRows = mDbSessions.delete(SESSION_TABLE, "? like \"?\"",
147 new String[]{COLUMN_KEY, reKey});
148 Log.i(TAG, "Number of rows in session table deleted: " + nDeleteRows);
149 return nDeleteRows;
150 }
151}