/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2016 HydroloGIS (www.hydrologis.com)
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.core.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import eu.geopaparazzi.library.core.ResourcesManager;
import eu.geopaparazzi.library.database.GPLog;
import eu.geopaparazzi.library.util.debug.Debug;
/**
* The database manager.
*
* @author Andrea Antonello (www.hydrologis.com)
*/
@SuppressWarnings("nls")
public class DatabaseManager {
/**
* The db version.
*/
public static final int DATABASE_VERSION = 9;
private static final String DEBUG_TAG = "DATABASEMANAGER";
/**
* Buffer for bounds expansion.
*/
public static final float BUFFER = 0.001f;
private DatabaseOpenHelper databaseHelper;
/**
* @param context the {@link Context} to use.
* @return the db.
* @throws IOException if something goes wrong.
*/
public SQLiteDatabase getDatabase( Context context ) throws IOException {
File databaseFile;
try {
databaseFile = ResourcesManager.getInstance(context).getDatabaseFile();
} catch (Exception e) {
throw new IOException(e.getLocalizedMessage());
}
if (databaseHelper == null || !databaseFile.exists()) {
databaseHelper = new DatabaseOpenHelper(databaseFile);
SQLiteDatabase db = databaseHelper.getWritableDatabase(context);
if (GPLog.LOG_ANDROID) {
Log.i(DEBUG_TAG, "Database: " + db.getPath());
Log.i(DEBUG_TAG, "Database Version: " + db.getVersion());
Log.i(DEBUG_TAG, "Database Page Size: " + db.getPageSize());
Log.i(DEBUG_TAG, "Database Max Size: " + db.getMaximumSize());
Log.i(DEBUG_TAG, "Database Open? " + db.isOpen());
Log.i(DEBUG_TAG, "Database readonly? " + db.isReadOnly());
Log.i(DEBUG_TAG, "Database Locked by current thread? " + db.isDbLockedByCurrentThread());
}
}
return databaseHelper.getWritableDatabase(context);
}
/**
* Close the database.
*/
public void closeDatabase() {
if (databaseHelper != null) {
if (Debug.D)
Log.i(DEBUG_TAG, "Closing database");
databaseHelper.close();
if (Debug.D)
Log.i(DEBUG_TAG, "Database closed");
}
databaseHelper = null;
}
private static class DatabaseOpenHelper {
private SQLiteDatabase db;
private File databaseFile;
private DatabaseOpenHelper( File databaseFile ) {
this.databaseFile = databaseFile;
}
public void open( Context context ) throws IOException {
if (databaseFile.exists()) {
if (Debug.D)
Log.i("SQLiteHelper", "Opening database at " + databaseFile);
db = SQLiteDatabase.openOrCreateDatabase(databaseFile, null);
int dbVersion = db.getVersion();
if (DATABASE_VERSION > dbVersion)
upgrade(DATABASE_VERSION, dbVersion, context);
} else {
if (Debug.D) {
Log.i("SQLiteHelper", "Creating database at " + databaseFile);
Log.i("SQLiteHelper", "db folder exists: " + databaseFile.getParentFile().exists());
Log.i("SQLiteHelper", "db folder is writable: " + databaseFile.getParentFile().canWrite());
}
db = SQLiteDatabase.openOrCreateDatabase(databaseFile, null);
create(context);
}
}
public void close() {
if (!db.isOpen()) {
return;
}
db.close();
db = null;
}
/**
* Create the db from scratch.
*
* @param context the context to use.
* @throws IOException if something goes wrong.
*/
public void create( Context context ) throws IOException {
db.setLocale(Locale.getDefault());
db.setVersion(DATABASE_VERSION);
// CREATE TABLES
GPLog.createTables(db);
DaoMetadata.createTables();
DaoMetadata.initProjectMetadata(null, null, null, null);
DaoNotes.createTables();
DaoGpsLog.createTables();
DaoBookmarks.createTables();
DaoImages.createTables();
}
/**
* Upgrade the db if necessary.
*
* @param newDbVersion the new db version.
* @param oldDbVersion the old db version.
* @param context the context to use.
* @throws IOException if something goes wrong.
*/
public void upgrade( int newDbVersion, int oldDbVersion, Context context ) throws IOException {
// if (oldDbVersion == 1) {
// Log.i(DEBUG_TAG, "Db upgrade to 2");
// DaoNotes.upgradeNotesFromDB1ToDB2(db);
// }
// if (oldDbVersion <= 2) {
// Log.i(DEBUG_TAG, "Db upgrade to 3");
// DaoBookmarks.createTables();
// }
// if (oldDbVersion <= 3) {
// Log.i(DEBUG_TAG, "Db upgrade to 4");
// DaoImages.createTables();
// }
// if (oldDbVersion <= 4) {
// Log.i(DEBUG_TAG, "Db upgrade to 5");
// DaoNotes.upgradeNotesFromDB4ToDB5(db);
// }
// if (oldDbVersion <= 5) {
// Log.i(DEBUG_TAG, "Db upgrade to 6");
// DaoNotes.upgradeNotesFromDB5ToDB6(db);
// }
// if (oldDbVersion <= 6) {
// Log.i(DEBUG_TAG, "Db upgrade to 7");
// GPLog.createTables(db);
// }
// if (oldDbVersion <= 7) {
// Log.i(DEBUG_TAG, "Db upgrade to 8");
// // probably don't need to check (could just add column), but it is safer this way
// boolean checkField = DaoGpsLog.existsColumnInTable(db, "gpslogs", "lengthm");
// if (checkField == false) {
// DaoGpsLog.addFieldGPSTables(db, "gpslogs", "lengthm", "REAL");
// }
// }
// db.beginTransaction();
// try {
// db.setTransactionSuccessful();
// db.setVersion(newDbVersion);
// } catch (Exception e) {
// Log.e("DATABASEMANAGER", e.getLocalizedMessage(), e);
// throw new IOException(e.getLocalizedMessage());
// } finally {
// db.endTransaction();
// }
}
public SQLiteDatabase getWritableDatabase( Context context ) throws IOException {
if (db == null)
open(context);
return db;
}
}
}