package pl.llp.aircasting.storage.repository; import pl.llp.aircasting.model.MeasurementStream; import pl.llp.aircasting.model.Session; import pl.llp.aircasting.storage.db.AirCastingDB; import pl.llp.aircasting.storage.db.ReadOnlyDatabaseTask; import pl.llp.aircasting.storage.db.WritableDatabaseTask; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.google.inject.Inject; import org.intellij.lang.annotations.Language; import java.util.ArrayList; import java.util.List; import static pl.llp.aircasting.storage.DBHelper.getLong; import static pl.llp.aircasting.storage.db.DBConstants.*; /** * Created by ags on 28/03/2013 at 18:48 */ public class SessionTrackerDAO { @Inject SessionRepository sessions; @Inject StreamRepository streamRepo; @Inject AirCastingDB dbAccessor; public List<Session> unfinishedSessions() { List<Long> longs = dbAccessor.executeReadOnlyTask(new ReadOnlyDatabaseTask<List<Long>>() { @Override public List<Long> execute(SQLiteDatabase readOnlyDb) { List<Long> result = new ArrayList<Long>(); Cursor cursor = readOnlyDb.rawQuery("SELECT " + SESSION_ID + " FROM " + SESSION_TABLE_NAME + " WHERE " + SESSION_INCOMPLETE + " = 1", null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { Long sessionId = getLong(cursor, SESSION_ID); result.add(sessionId); cursor.moveToNext(); } cursor.close(); return result; } }); List<Session> shallowSessions = sessions.loadShallow(longs); return shallowSessions; } public void complete(final long sessionId) { updateAverages(sessionId); fixTimes(sessionId); markComplete(sessionId); } private void updateAverages(final long sessionId) { List<MeasurementStream> streams = streamRepo.findAllForSession(sessionId); for (final MeasurementStream stream : streams) { final long streamId = stream.getId(); dbAccessor.executeWritableTask(new WritableDatabaseTask<Object>() { @Override public Object execute(SQLiteDatabase writableDb) { @Language("SQLite") String query = "UPDATE " + STREAM_TABLE_NAME + " \n" + "SET " + STREAM_AVG + " = \n (" + "SELECT\n AVG(" + MEASUREMENT_VALUE + ")\n" + " FROM " + MEASUREMENT_TABLE_NAME + " \n" + " WHERE " + MEASUREMENT_STREAM_ID + " = ?\n" + " ),\n " + " " + STREAM_PEAK + " =\n" + " (\n" + " SELECT\n MAX(" + MEASUREMENT_VALUE + ")\n" + " FROM " + MEASUREMENT_TABLE_NAME + "\n" + " WHERE " + MEASUREMENT_STREAM_ID + "= ?\n" + " )\n" + "WHERE " + STREAM_ID + " = ?"; writableDb.execSQL(query, new Object[]{streamId, streamId, streamId}); return null; } }); } } private void markComplete(final long sessionId) { dbAccessor.executeWritableTask(new WritableDatabaseTask<Void>() { @Override public Void execute(SQLiteDatabase writableDatabase) { ContentValues values = new ContentValues(); values.put(SESSION_INCOMPLETE, 0); writableDatabase.update(SESSION_TABLE_NAME, values, SESSION_ID + " = " + sessionId, null); return null; } @Override public String toString() { return String.format("Mark session %d as complete", sessionId); } }); } public void abandon(final Session unfinished) { final Long sessionId = unfinished.getId(); dbAccessor.executeWritableTask(new WritableDatabaseTask<Object>() { @Override public Object execute(SQLiteDatabase writableDb) { writableDb.delete(SESSION_TABLE_NAME, SESSION_ID + " = " + sessionId, null); writableDb.delete(MEASUREMENT_TABLE_NAME, MEASUREMENT_SESSION_ID + " = " + sessionId, null); writableDb.delete(STREAM_TABLE_NAME, STREAM_SESSION_ID + " = " + sessionId, null); writableDb.delete(NOTE_TABLE_NAME, NOTE_SESSION_ID + " = " + sessionId, null); return null; } }); } public void fixTimes(final long sessionId) { dbAccessor.executeWritableTask(new WritableDatabaseTask<Void>() { @Override public Void execute(SQLiteDatabase writableDatabase) { @Language("SQLite") String sql = " UPDATE " + SESSION_TABLE_NAME + " \n SET " + SESSION_START + " = \n " + "(\n SELECT MIN(" + MEASUREMENT_TIME + ") " + "FROM " + MEASUREMENT_TABLE_NAME + " WHERE " + MEASUREMENT_SESSION_ID + " = " + sessionId + " \n ), \n " + SESSION_END + " = \n " + "(\n SELECT MAX(" + MEASUREMENT_TIME + ") FROM " + MEASUREMENT_TABLE_NAME + " WHERE " + MEASUREMENT_SESSION_ID + " = " + sessionId + "\n ) \n" + " WHERE " + SESSION_ID + " = " + sessionId; writableDatabase.execSQL(sql); return null; } @Override public String toString() { return String.format("Update times for session %d", sessionId); } }); } }