1/*
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.util.ArrayList;
28import java.util.Arrays;
29import java.util.HashMap;
30import java.util.List;
31import java.util.Map;
32
33/* This class implements record like data storage for aggregator.
34 * The data is stored in the sqlite database row by row without primary key, all
35 * columns are assume having string value.
36 * Sample usage:
37 *       AggregatorRecordStorage db = new AggregatorRecordStorage(this, "TestTable",
38 *               new String[]{"clusterid", "long", "lat"});
39 *       db.removeAllData();
40 *       HashMap<String, String> row = new HashMap<String, String>();
41 *       row.put("clusterid", "home");
42 *       row.put("long", "110.203");
43 *       row.put("lat", "-13.787");
44 *       db.addData(row);
45 *       row.put("clusterid", "office");
46 *       row.put("long", "1.203");
47 *       row.put("lat", "33.787");
48 *       db.addData(row);
49 *       List<Map<String,String> > allData = db.getAllData();
50 *       Log.i(TAG,"Total data in database: " + allData.size());
51 */
52class AggregatorRecordStorage extends AggregatorStorage {
53    private static final String TAG = "AggregatorRecordStorage";
54    private String mTableName;
55    private List<String> mColumnNames;
56
57    public AggregatorRecordStorage(Context context, String tableName, String [] columnNames) {
58        if (columnNames.length < 1) {
59            throw new RuntimeException("No column keys");
60        }
61        mColumnNames = Arrays.asList(columnNames);
62        mTableName = tableName;
63
64        String tableCmd = "create table " + tableName + "( " + columnNames[0] +
65          " TEXT";
66        for (int i = 1; i < columnNames.length; ++i)
67            tableCmd = tableCmd + ", " + columnNames[i] + " TEXT";
68        tableCmd = tableCmd + ");";
69        Log.i(TAG, tableCmd);
70        try {
71            mDbHelper = new DBHelper(context, tableName, tableCmd);
72            mDatabase = mDbHelper.getWritableDatabase();
73        } catch (SQLException e) {
74            throw new RuntimeException("Can't open table: " + tableName);
75        }
76    }
77
78    // Adding one more row to the table.
79    // the data is a map of <column_name, value> pair.
80    public boolean addData(Map<String, String> data) {
81        ContentValues content = new ContentValues();
82        for (Map.Entry<String, String> item : data.entrySet()) {
83            content.put(item.getKey(), item.getValue());
84        }
85        long rowID =
86                mDatabase.insert(mTableName, null, content);
87        return rowID >= 0;
88    }
89
90    // Return all data as a list of Map.
91    // Notice that the column names are repeated for each row.
92    public List<Map<String, String>> getAllData() {
93        ArrayList<Map<String, String> > allData = new ArrayList<Map<String, String> >();
94
95        Cursor cursor = mDatabase.rawQuery("select * from " + mTableName + ";", null);
96        if (cursor.getCount() == 0) {
97            return allData;
98        }
99        cursor.moveToFirst();
100        do {
101            HashMap<String, String> oneRow = new HashMap<String, String>();
102            for (String column : mColumnNames) {
103                int columnIndex = cursor.getColumnIndex(column);
104                if (!cursor.isNull(columnIndex)) {
105                    String value = cursor.getString(columnIndex);
106                    oneRow.put(column, value);
107                }
108            }
109            allData.add(oneRow);
110        } while (cursor.moveToNext());
111        return allData;
112    }
113
114    // Empty the storage.
115    public int removeAllData() {
116        int nDeleteRows = mDatabase.delete(mTableName, "1", null);
117        Log.i(TAG, "Number of rows in table deleted: " + nDeleteRows);
118        return nDeleteRows;
119    }
120}
121