/**
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.IOException;
import java.io.SyncFailedException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.rareventure.android.DbUtil;
import com.rareventure.gps2.database.GpsLocationRow;
import com.rareventure.gps2.database.TimeZoneTimeRow;
import com.rareventure.gps2.database.UserLocationRow;
import com.rareventure.gps2.database.cache.AreaPanel;
import com.rareventure.gps2.database.cache.MediaLocTime;
import com.rareventure.gps2.database.cache.TimeTree;
public final class GpsTrailerDb {
// This class cannot be instantiated
private GpsTrailerDb() {}
public static final int DATABASE_VERSION = 18;
public static final int GPS_LOCATION_TIME_FLAG_EST_SPEED = 1;
public static final int GPS_LOCATION_TIME_TYPE_GPS = 1;
/**
* Drops and recreates encryption tables and tables relating to encryption
* @param db
*/
public static void dropAndRecreateEncryptedTables(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS USER_DATA_KEY");
db.execSQL("CREATE TABLE USER_DATA_KEY (_id integer primary key, APP_ID INTEGER NOT NULL,encrypted_key blob);");
for(String table : new String [] { GpsLocationRow.TABLE_NAME, UserLocationRow.TABLE_NAME,
TimeZoneTimeRow.TABLE_NAME})
{
dropAndRecreateEncryptedTable(db, table);
}
}
public static void dropAndRecreateEncryptedTable(SQLiteDatabase db, String table)
{
Log.d(GTG.TAG,"dropping table "+table+"...");
db.execSQL("drop table if exists "+table);
Log.d(GTG.TAG, "done dropping "+table+" table...");
db.execSQL("create table "+table+" (" +
"_ID INTEGER PRIMARY KEY," +
"USER_DATA_KEY_FK INTEGER NOT NULL, " +
"DATA BLOB NOT NULL)" );
}
//TODO 3: investigate faster file formats. Since we're never deleting rows, we can get away with a flat file I think.. note that sqlite3 does
// not have performance improvements for fixed witdth columns (according to what I read)
public static void initializeNewDb(SQLiteDatabase db) {
//very important.. without this we'll get locking errors all over the place
// and cache population while cache reading is going on won't work
//this weird bit is to get around an android bug
//co: because we now use timmy tables and evo is acting funny with this
// Cursor c1 = db.rawQuery("PRAGMA journal_mode=wal", null); c1.moveToNext(); c1.close();
if(DbUtil.runQueryWithStrings(db, "select exists (SELECT 1 FROM sqlite_master WHERE " +
"type='table' AND upper(name)='ANDROID_METADATA')") != 1)
db.execSQL("CREATE TABLE android_metadata (locale TEXT);");
dropAndRecreateEncryptedTables(db);
//co: these tables were used as an experiment... might need them later
//CREATE TABLE WIFI_SCAN_RESULT (_ID INTEGER PRIMARY KEY,TIME LONG NOT NULL,SSID TEXT NOT NULL,BSSID TEXT NOT NULL,CAPABILITIES TEXT NOT NULL,LEVEL INTEGER NOT NULL,FREQUENCY INTEGER NOT NULL);
//CREATE TABLE rest (_id INTEGER PRIMARY KEY,begin_time LONG NOT NULL,end_time LONG NOT NULL);
//CREATE TABLE compass (_id INTEGER PRIMARY KEY,begin_time LONG NOT NULL,end_time LONG NOT NULL,direction FLOAT NOT NULL);
db.setVersion(DATABASE_VERSION);
}
public static void upgradeDbIfNecessary(SQLiteDatabase db) {
if(db.getVersion() < 14)
{
Log.d(GTG.TAG,"upgrading db to version 14");
dropAndRecreateEncryptedTable(db, MediaLocTime.TABLE_NAME);
db.setVersion(14);
}
else if(db.getVersion() == 14)
{
Log.d(GTG.TAG,"upgrading db to version 15");
Log.d(GTG.TAG,"dropping table media_loc_time...");
db.execSQL("drop table if exists media_loc_time");
db.setVersion(15);
}
else if(db.getVersion() == 15)
{
Log.d(GTG.TAG,"upgrading db to version 16");
Log.d(GTG.TAG, "Removing cache");
GpsTrailerDbProvider.deleteUnopenedCache();
db.setVersion(16);
}
else if(db.getVersion() == 16)
{
Log.d(GTG.TAG,"upgrading db to version 17");
Log.d(GTG.TAG, "creating time zone time table");
dropAndRecreateEncryptedTable(db, TimeZoneTimeRow.TABLE_NAME);
db.setVersion(17);
}
else if(db.getVersion() == 17)
{
Log.d(GTG.TAG,"upgrading db to version 18");
Log.d(GTG.TAG, "removing android_prefs table");
db.execSQL("drop table if exists android_prefs");
db.setVersion(18);
}
}
public static void moveToBakAndRecreateTable(String tableName) {
GTG.db.execSQL("DROP TABLE IF EXISTS "+tableName+"_BAK");
if(DbUtil.runQueryWithStrings(GTG.db, "select exists (SELECT 1 FROM sqlite_master WHERE type='table' AND upper(name)=?)", tableName.toUpperCase()) == 1)
{
GTG.db.execSQL("ALTER TABLE "+tableName+" RENAME TO "+tableName+"_BAK");
}
GpsTrailerDb.dropAndRecreateEncryptedTable(GTG.db, tableName);
}
public static void dropTable(String tableName) {
GTG.db.execSQL("DROP TABLE IF EXISTS "+tableName);
}
public static void dropBakTable(String tableName) {
GTG.db.execSQL("DROP TABLE IF EXISTS "+tableName+"_BAK");
}
public static void replaceTableWithBakIfNecessary(SQLiteDatabase db,
String tableName) {
if(
DbUtil.runQueryWithStrings(db, "select exists (SELECT 1 FROM sqlite_master WHERE type='table' AND upper(name)=?)", tableName.toUpperCase()) != 1
|| DbUtil.runQueryWithStrings(db, "select exists (SELECT 1 FROM "+tableName+" LIMIT 1)") != 1)
{
if(DbUtil.runQueryWithStrings(db, "select exists (SELECT 1 FROM sqlite_master WHERE type='table' AND upper(name)=?)", tableName.toUpperCase()+"_BAK") == 1)
{
db.execSQL("DROP TABLE IF EXISTS "+tableName);
db.execSQL("ALTER TABLE "+tableName+"_BAK RENAME TO "+tableName);
}
}
db.execSQL("DROP TABLE IF EXISTS "+tableName+"_BAK");
}
}