package com.github.pires.obd.reader.trips;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Some code taken from https://github.com/wdkapps/FillUp
*/
public class TripLog {
/// the database version number
public static final int DATABASE_VERSION = 1;
/// the name of the database
public static final String DATABASE_NAME = "tripslog.db";
/// a tag string for debug logging (the name of this class)
private static final String TAG = TripLog.class.getName();
/// database table names
private static final String RECORDS_TABLE = "Records";
/// SQL commands to delete the database
public static final String[] DATABASE_DELETE = new String[]{
"drop table if exists " + RECORDS_TABLE + ";",
};
/// column names for RECORDS_TABLE
private static final String RECORD_ID = "id";
private static final String RECORD_START_DATE = "startDate";
private static final String RECORD_END_DATE = "endDate";
private static final String RECORD_RPM_MAX = "rmpMax";
private static final String RECORD_SPEED_MAX = "speedMax";
private static final String RECORD_ENGINE_RUNTIME = "engineRuntime";
/// SQL commands to create the database
public static final String[] DATABASE_CREATE = new String[]{
"create table " + RECORDS_TABLE + " ( " +
RECORD_ID + " integer primary key autoincrement, " +
RECORD_START_DATE + " integer not null, " +
RECORD_END_DATE + " integer, " +
RECORD_SPEED_MAX + " integer, " +
RECORD_RPM_MAX + " integer, " +
RECORD_ENGINE_RUNTIME + " text" +
");"
};
/// array of all column names for RECORDS_TABLE
private static final String[] RECORDS_TABLE_COLUMNS = new String[]{
RECORD_ID,
RECORD_START_DATE,
RECORD_END_DATE,
RECORD_SPEED_MAX,
RECORD_ENGINE_RUNTIME,
RECORD_RPM_MAX
};
/// singleton instance
private static TripLog instance;
/// context of the instance creator
private final Context context;
/// a helper instance used to open and close the database
private final TripLogOpenHelper helper;
/// the database
private final SQLiteDatabase db;
private TripLog(Context context) {
this.context = context;
this.helper = new TripLogOpenHelper(this.context);
this.db = helper.getWritableDatabase();
}
/**
* DESCRIPTION:
* Returns a single instance, creating it if necessary.
*
* @return GasLog - singleton instance.
*/
public static TripLog getInstance(Context context) {
if (instance == null) {
instance = new TripLog(context);
}
return instance;
}
/**
* DESCRIPTION:
* Convenience method to test assertion.
*
* @param assertion - an asserted boolean condition.
* @param tag - a tag String identifying the calling method.
* @param msg - an error message to display/log.
* @throws RuntimeException if the assertion is false
*/
private void ASSERT(boolean assertion, String tag, String msg) {
if (!assertion) {
String assert_msg = "ASSERT failed: " + msg;
Log.e(tag, assert_msg);
throw new RuntimeException(assert_msg);
}
}
public TripRecord startTrip() {
final String tag = TAG + ".createRecord()";
try {
TripRecord record = new TripRecord();
long rowID = db.insertOrThrow(RECORDS_TABLE, null, getContentValues(record));
record.setID((int) rowID);
return record;
} catch (SQLiteConstraintException e) {
Log.e(tag, "SQLiteConstraintException: " + e.getMessage());
} catch (SQLException e) {
Log.e(tag, "SQLException: " + e.getMessage());
}
return null;
}
/**
* DESCRIPTION:
* Updates a trip record in the log.
*
* @param record - the TripRecord to update.
* @return boolean flag indicating success/failure (true=success)
*/
public boolean updateRecord(TripRecord record) {
final String tag = TAG + ".updateRecord()";
ASSERT((record.getID() != null), tag, "record id cannot be null");
boolean success = false;
try {
ContentValues values = getContentValues(record);
values.remove(RECORD_ID);
String whereClause = RECORD_ID + "=" + record.getID();
int count = db.update(RECORDS_TABLE, values, whereClause, null);
success = (count > 0);
} catch (SQLiteConstraintException e) {
Log.e(tag, "SQLiteConstraintException: " + e.getMessage());
} catch (SQLException e) {
Log.e(tag, "SQLException: " + e.getMessage());
}
return success;
}
/**
* DESCRIPTION:
* Convenience method to convert a TripRecord instance to a set of key/value
* pairs in a ContentValues instance utilized by SQLite access methods.
*
* @param record - the GasRecord to convert.
* @return a ContentValues instance representing the specified GasRecord.
*/
private ContentValues getContentValues(TripRecord record) {
ContentValues values = new ContentValues();
values.put(RECORD_ID, record.getID());
values.put(RECORD_START_DATE, record.getStartDate().getTime());
if (record.getEndDate() != null)
values.put(RECORD_END_DATE, record.getEndDate().getTime());
values.put(RECORD_RPM_MAX, record.getEngineRpmMax());
values.put(RECORD_SPEED_MAX, record.getSpeedMax());
if (record.getEngineRuntime() != null)
values.put(RECORD_ENGINE_RUNTIME, record.getEngineRuntime());
return values;
}
private void update() {
String sql = "ALTER TABLE " + RECORDS_TABLE + " ADD COLUMN " + RECORD_ENGINE_RUNTIME + " integer;";
db.execSQL(sql);
}
public List<TripRecord> readAllRecords() {
//update();
final String tag = TAG + ".readAllRecords()";
List<TripRecord> list = new ArrayList<>();
Cursor cursor = null;
try {
String orderBy = RECORD_START_DATE;
cursor = db.query(
RECORDS_TABLE,
RECORDS_TABLE_COLUMNS,
null,
null, null, null,
orderBy,
null
);
// create a list of TripRecords from the data
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
TripRecord record = getRecordFromCursor(cursor);
list.add(record);
} while (cursor.moveToNext());
}
}
} catch (SQLException e) {
Log.e(tag, "SQLException: " + e.getMessage());
list.clear();
} finally {
if (cursor != null) cursor.close();
}
return list;
}
/**
* DESCRIPTION:
* Deletes a specified trip record from the log.
*
* @param id - the TripRecord to delete.
* @return boolean flag indicating success/failure (true=success)
*/
public boolean deleteTrip(long id) {
final String tag = TAG + ".deleteRecord()";
boolean success = false;
try {
String whereClause = RECORD_ID + "=" + id;
String[] whereArgs = null;
int count = db.delete(RECORDS_TABLE, whereClause, whereArgs);
success = (count == 1);
} catch (SQLException e) {
Log.e(tag, "SQLException: " + e.getMessage());
}
return success;
}
/**
* DESCRIPTION:
* Convenience method to create a TripRecord instance from values read
* from the database.
*
* @param c - a Cursor containing results of a database query.
* @return a GasRecord instance (null if no data).
*/
private TripRecord getRecordFromCursor(Cursor c) {
final String tag = TAG + ".getRecordFromCursor()";
TripRecord record = null;
if (c != null) {
record = new TripRecord();
int id = c.getInt(c.getColumnIndex(RECORD_ID));
long startDate = c.getLong(c.getColumnIndex(RECORD_START_DATE));
long endTime = c.getLong(c.getColumnIndex(RECORD_END_DATE));
int engineRpmMax = c.getInt(c.getColumnIndex(RECORD_RPM_MAX));
int speedMax = c.getInt(c.getColumnIndex(RECORD_SPEED_MAX));
record.setID(id);
record.setStartDate(new Date(startDate));
record.setEndDate(new Date(endTime));
record.setEngineRpmMax(engineRpmMax);
record.setSpeedMax(speedMax);
if (!c.isNull(c.getColumnIndex(RECORD_ENGINE_RUNTIME)))
record.setEngineRuntime(c.getString(c.getColumnIndex(RECORD_ENGINE_RUNTIME)));
}
return record;
}
}