/**
Copyright 2015 Tim Engler, Rareventure LLC
This file is part of Tiny Travel Tracker.
Tiny Travel Tracker is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Tiny Travel Tracker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Tiny Travel Tracker. If not, see <http://www.gnu.org/licenses/>.
*/
package com.rareventure.gps2;
import java.io.File;
import java.io.IOException;
import java.io.SyncFailedException;
import com.rareventure.android.DbUtil;
import com.rareventure.android.database.timmy.RollBackTimmyTable;
import com.rareventure.android.database.timmy.TimmyDatabase;
import com.rareventure.android.database.timmy.TimmyTable;
import com.rareventure.android.encryption.EncryptedRow;
import com.rareventure.gps2.database.GpsLocationRow;
import com.rareventure.gps2.database.TimeZoneTimeRow;
import com.rareventure.gps2.database.cache.AreaPanel;
import com.rareventure.gps2.database.cache.MediaLocTime;
import com.rareventure.gps2.database.cache.TimeTree;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;
//TODO 3: The whole database stuff is kind of crappy. Rewrite for greater code efficiency, or even use templates?
public class GpsTrailerDbProvider {
private static final String TAG = "GpsTrailerDbProvider";
public static final String DB_FILE_NAME = "gps.db3";
public static boolean isDatabasePresent()
{
return getDbFile(false).isFile();
}
public static File getDbFile(boolean isTmpFile)
{
return new File(GTG.getExternalStorageDirectory()+"/"+DB_FILE_NAME+(isTmpFile ? ".tmp" : ""));
}
public static SQLiteDatabase createNewDbFile(File dbFile)
{
if(GTG.getExternalStorageDirectory() == null)
throw new IllegalStateException("why is external storage directory null?");
if (!GTG.getExternalStorageDirectory().exists())
{
throw new IllegalStateException("directory doesn't exist");
}
deleteDbFiles(dbFile);
SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile.toString(), null,
SQLiteDatabase.OPEN_READWRITE
+ SQLiteDatabase.CREATE_IF_NECESSARY);
GpsTrailerDb.initializeNewDb(db);
return db;
}
/**
* Deletes database and related journal file
*/
public static void deleteDbFiles(File dbFile) {
dbFile.delete();
new File(dbFile+"-journal").delete();
}
public static SQLiteDatabase openDatabase(File dbFile) {
Log.d(GTG.TAG, "Using db " + dbFile);
SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile.toString(), null,
SQLiteDatabase.OPEN_READWRITE);
GpsTrailerDb.upgradeDbIfNecessary(db);
//cleanup after failed restore if necessary
//if there is no gps_location_row or it has zero rows
GpsTrailerDb.replaceTableWithBakIfNecessary(db, GpsLocationRow.TABLE_NAME);
GpsTrailerDb.replaceTableWithBakIfNecessary(db, TimeZoneTimeRow.TABLE_NAME);
return db;
}
public static final String APCACHE_TIMMY_TABLE_FILENAME = "AreaPanel.tt";
public static final String TIME_TREE_TIMMY_TABLE_FILENAME = "TimeTree.tt";
public static final String MEDIA_LOC_TIME_TIMMY_TABLE_FILENAME = "MediaLocTime.tt";
public static final String MEDIA_LOC_TIME_PLUS_TIMMY_TABLE_FILENAME = "MediaLocTimePlus.tt";
public static final String TIMMY_DB_FILENAME = "cache.td";
public static TimmyDatabase createTimmyDb() throws SyncFailedException, IOException {
TimmyDatabase timmyDb = new TimmyDatabase(GTG.getExternalStorageDirectory()+"/"+TIMMY_DB_FILENAME);
timmyDb
.addRollBackTimmyTable(
GTG.getExternalStorageDirectory()+ "/"
+ APCACHE_TIMMY_TABLE_FILENAME,
GTG.crypt.crypt
.getNumOutputBytesForEncryption(AreaPanel.DATA_LENGTH));
timmyDb
.addRollBackTimmyTable(
GTG.getExternalStorageDirectory()+ "/"
+ TIME_TREE_TIMMY_TABLE_FILENAME,
GTG.crypt.crypt
.getNumOutputBytesForEncryption(TimeTree.DATA_LENGTH));
timmyDb
.addTimmyTable(
GTG.getExternalStorageDirectory()+ "/"
+ MEDIA_LOC_TIME_TIMMY_TABLE_FILENAME,
GTG.crypt.crypt
.getNumOutputBytesForEncryption(MediaLocTime.DATA_LENGTH));
// timmyDb
// .addTimmyTable(
// context.getExternalFilesDir(null) + "/"
// + MEDIA_LOC_TIME_PLUS_TIMMY_TABLE_FILENAME,
// crypt.crypt
// .getNumOutputBytesForEncryption(MediaLocTime.DATA_LENGTH)
// + EncryptedRow.EXTRA_BYTES_FOR_USER_DATA_KEY);
return timmyDb;
}
public static void deleteUnopenedCache() {
//TODO 2.5 this is weird to have here!!
for(String file : new String [] { APCACHE_TIMMY_TABLE_FILENAME, TIME_TREE_TIMMY_TABLE_FILENAME,
MEDIA_LOC_TIME_TIMMY_TABLE_FILENAME, MEDIA_LOC_TIME_PLUS_TIMMY_TABLE_FILENAME, TIMMY_DB_FILENAME})
{
file = GTG.getExternalStorageDirectory()+ "/" + file;
new File(file).delete();
new File(file+TimmyTable.ROLLFORWARD_EXTENSION).delete();
new File(file+RollBackTimmyTable.ROLLBACK_EXTENSION).delete();
}
}
// TODO 4: Insert into rest immediately when we have a stop, and update it
// later when we move, so we have real timeness
// in the display of rest periods.. Is this even going to work? If they take
// it out of their pocket, it will shake.. and
// in the event of a system crash, we'll need to clean up this handiwork.
}