package com.num.database.datasource; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.TimeZone; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import com.num.database.DatabaseOutput; import com.num.database.mapping.ApplicationMapping; import com.num.database.mapping.BaseMapping; import com.num.database.mapping.LatencyMapping; import com.num.database.mapping.ThroughputMapping; import com.num.models.GraphData; import com.num.models.GraphPoint; import com.num.models.Link; import com.num.models.MainModel; import com.num.models.Model; import com.num.models.Throughput; import com.num.utils.DeviceUtil; public abstract class DataSource { // Database fields public SQLiteDatabase database; public Context context; public BaseMapping dbHelper; public static boolean inTransaction = false; private final boolean IS_PURGE_ALLOWED = true; public int currentMode = 0; public DataSource(Context context) { this.context = context; } public boolean isPurgeAllowed() { return IS_PURGE_ALLOWED; } public void delay() { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // TODO this right now public void waitForTransaction() { while (inTransaction) { try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void open() throws SQLException { waitForTransaction(); inTransaction = true; database = dbHelper.getWritableDatabase(); } public void close() { inTransaction = false; dbHelper.close(); } public String getTime() { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(new Date()); } public abstract HashMap<String, ArrayList<GraphPoint>> getGraphData(); public abstract DatabaseOutput getOutput(); protected abstract void insertModel(Model model); public String[] getColumns() { return dbHelper.getDatabaseColumns().getColumnNames(); } public void setDBHelper(BaseMapping helper) { dbHelper = helper; if (isPurgeAllowed()) { purgeOldData(5, 10); Random random = new Random(); int lower = random.nextInt(10) * 5 + 10; int higher = lower + 5; //purgeOldData(lower, higher); } } public ArrayList<String> getDistinctValues(String column) { open(); String[] columns = new String[1]; columns[0] = column; Cursor cursor = database.query(true, dbHelper.getTableName(), columns, null, null, null, null, null, null); ArrayList<String> ret = new ArrayList<String>(); cursor.moveToFirst(); while (!cursor.isAfterLast()) { ret.add(cursor.getString(0)); cursor.moveToNext(); } cursor.close(); close(); System.out.println("fetch Distinct Values " + column + " DONE"); return ret; } private void purgeOldData(int startdays, int enddays) { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1 * enddays); Date endDelete = cal.getTime(); cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1 * startdays); Date onDelete = cal.getTime(); open(); while (onDelete.after(endDelete)) { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String s = sdf.format(onDelete); database.delete(dbHelper.getTableName(), ApplicationMapping.COLUMN_TIME + " LIKE '%" + s + "%'", null); cal.add(Calendar.DAY_OF_MONTH, -1); onDelete = cal.getTime(); } close(); } protected List<Map<String, String>> getDataStores( HashMap<String, String> filter) { open(); List<Map<String, String>> dataStores = new ArrayList<Map<String, String>>(); String selection = ""; String[] arguments = new String[filter.size()]; int count = 0; Iterator<String> iter = filter.keySet().iterator(); while (iter.hasNext()) { String key = iter.next(); String value = filter.get(key); selection += key + " = ? and "; arguments[count++] = value; } if (selection.length() > 5) { selection = selection.substring(0, selection.length() - 4); } Cursor cursor = database.query(dbHelper.getTableName(), getColumns(), selection, arguments, null, null, "_id"); cursor.moveToFirst(); while (!cursor.isAfterLast()) { Map<String, String> dataStore = dbHelper.getDatabaseColumns() .getDataStore(cursor); dataStores.add(dataStore); cursor.moveToNext(); } // Make sure to close the cursor cursor.close(); close(); return dataStores; } public List<Map<String, String>> getDataStores() { open(); List<Map<String, String>> dataStores = new ArrayList<Map<String, String>>(); Cursor cursor = database.query(dbHelper.getTableName(), getColumns(), null, null, null, null, "_id"); cursor.moveToFirst(); while (!cursor.isAfterLast()) { Map<String, String> dataStore = dbHelper.getDatabaseColumns() .getDataStore(cursor); dataStores.add(dataStore); cursor.moveToNext(); } // Make sure to close the cursor cursor.close(); close(); return dataStores; } public void insert(Model model) { Log.w("db", "inserting"); open(); insertModel(model); close(); } public ArrayList<GraphPoint> getGraphData(HashMap<String, String> filter) { if (getMode().equals("normal")) return getNormalGraphData(filter); else if (getMode().equals("aggregate")) return getAggregateGraphData(filter); else return null; } public ArrayList<GraphPoint> getNormalGraphData( HashMap<String, String> filter) { List<Map<String, String>> allData = getDataStores(filter); ArrayList<GraphPoint> points = new ArrayList<GraphPoint>(); for (Map<String, String> data : allData) { points.add(new GraphPoint(data.size(), extractValue(data), extractTime(data))); } return points; } public ArrayList<GraphPoint> getAggregateGraphData( HashMap<String, String> filter) { List<Map<String, String>> allData = getDataStores(filter); ArrayList<GraphPoint> points = new ArrayList<GraphPoint>(); Map<String, GraphPoint> pointmap = new HashMap<String, GraphPoint>(); for (Map<String, String> data : allData) { GraphPoint newPoint = new GraphPoint(0, extractValue(data), extractTime(data)); newPoint.setString(extractDate(data)); newPoint.sortByDate(true); String date = extractDate(data); if (pointmap.containsKey(date)) { GraphPoint oldPoint = pointmap.get(date); aggregatePoints(oldPoint, newPoint); } else { pointmap.put(date, newPoint); } } Iterator<String> iter = pointmap.keySet().iterator(); int count = 0; while (iter.hasNext()) { String date = iter.next(); points.add(pointmap.get(date)); } try { Collections.sort(points); } catch (Exception e) { e.printStackTrace(); } for (GraphPoint point : points) { point.x = count++; } return points; } public abstract int extractValue(Map<String, String> data); public abstract Date extractTime(Map<String, String> data); public String extractDate(Map<String, String> data) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = data.get(LatencyMapping.COLUMN_TIME); try { Date d = df.parse(dateString); return (d.getMonth() + 1) + "-" + d.getDate(); } catch (ParseException e) { e.printStackTrace(); return new Date().toString(); } } public Date extractDate(String dateString) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return df.parse(dateString); } catch (ParseException e) { e.printStackTrace(); return new Date(); } } public abstract void aggregatePoints(GraphPoint oldP, GraphPoint newP); public abstract String getGraphType(); public abstract String getYAxisLabel(); public abstract String[] getModes(); public String getMode() { return getModes()[currentMode]; } public void setMode(int mode) { currentMode = mode; } }