package org.fitchfamily.android.gsmlocation;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import java.io.File;
import java.io.IOException;
public class DatabaseCreator {
private static final String SQL_INSERT = "INSERT INTO cells (mcc, mnc, lac, cid, longitude, latitude, accuracy, samples, altitude) VALUES (?, ?, ?, ?, ?, ?, ?, ?, -1);";
public static DatabaseCreator withTempFile(Context context) throws IOException {
// Remove any old failed download attempts
String path = Settings.with(context).databaseDirectory().toString();
File f = new File(path);
File file[] = f.listFiles();
for (int i=0; i < file.length; i++)
{
if (file[i].getName().startsWith("new_lacells")) {
file[i].delete();
}
}
return with(File.createTempFile("new_lacells", ".db", Settings.with(context).databaseDirectory()));
}
public static DatabaseCreator with(File file) {
return new DatabaseCreator(file);
}
private File file;
private SQLiteDatabase database;
private SQLiteStatement insertStatement;
private DatabaseCreator(File file) {
this.file = file;
}
/**
* Opens the database, does nothing if the database is already opened
* @return this object
*/
public DatabaseCreator open() {
if(database == null) {
database = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS +
SQLiteDatabase.OPEN_READWRITE +
SQLiteDatabase.CREATE_IF_NECESSARY
);
}
return this;
}
/**
* @throws UnsupportedOperationException if the database isn't opened
*/
private void ensureOpened() {
if(database == null) {
throw new UnsupportedOperationException(file + " is not opened");
}
}
/**
* @throws UnsupportedOperationException if the database is opened
*/
private void ensureClosed() {
if(database != null) {
throw new UnsupportedOperationException(file + " is opened");
}
}
/**
* Creates the table
* @throws UnsupportedOperationException if the database isn't opened
* @return this object
*/
public DatabaseCreator createTable() {
ensureOpened();
database.execSQL("CREATE TABLE cells(mcc INTEGER, mnc INTEGER, lac INTEGER, cid INTEGER, longitude REAL, latitude REAL, accuracy REAL, samples INTEGER, altitude REAL);");
return this;
}
/**
* Creates the index
* @throws UnsupportedOperationException if the database isn't opened
* @return this object
*/
public DatabaseCreator createIndex() {
ensureOpened();
database.execSQL("CREATE INDEX _idx1 ON cells (mcc, mnc, lac, cid);");
database.execSQL("CREATE INDEX _idx2 ON cells (lac, cid);");
return this;
}
/**
* Closes the database, does nothing if not opened
* @return this object
*/
public DatabaseCreator close() {
if(database != null) {
try {
database.close();
} catch (Exception ex) {
// We don't want a close to fail for our upper level stuff so ignore exception.
}
}
database = null;
insertStatement = null;
return this;
}
/**
* Tries to remove the journal file
* @throws UnsupportedOperationException if the database is opened
* @return this object
*/
public DatabaseCreator removeJournal() {
ensureClosed();
final File journalFile = new File(file.getAbsolutePath() + "-journal");
if (!journalFile.delete()) {
// ignore the error
}
return this;
}
/**
* Tries to delete the database and the journal file
* @throws UnsupportedOperationException if the database is opened
* @return this object
*/
public DatabaseCreator delete() {
ensureClosed();
removeJournal();
if(!file.delete()) {
// ignore
}
return this;
}
/**
* Tries to rename the database to the given file
* @param file the new name
* @throws UnsupportedOperationException if the database is opened
* @return this object
*/
public DatabaseCreator renameTo(File file) {
ensureClosed();
if(!this.file.renameTo(file)) {
// ignore
}
this.file = file;
return this;
}
/**
* Tries to replace the given database
* @param file the target file
* @throws UnsupportedOperationException if the database is opened
* @return this object
*/
public DatabaseCreator replace(File file) {
ensureClosed();
file.delete(); // delete if exists
renameTo(file);
return this;
}
/**
* start a transaction on the database
* @throws UnsupportedOperationException if the database is not opened
* @return this object
*/
public DatabaseCreator beginTransaction() {
ensureOpened();
database.beginTransaction();
return this;
}
/**
* start a transaction on the database
* @throws UnsupportedOperationException if the database is not opened
* @return this object
*/
public DatabaseCreator commitTransaction() {
ensureOpened();
database.setTransactionSuccessful();
database.endTransaction();
return this;
}
/**
* @throws UnsupportedOperationException if the database is not opened
* @return this object
*/
public DatabaseCreator insert(int mcc, String mnc, String lac, String cid, String longitude, String latitude, String accuracy, String samples) {
ensureOpened();
if(insertStatement == null) {
insertStatement = database.compileStatement(SQL_INSERT);
}
if (accuracy.contains(".")) {
accuracy = accuracy.substring(0, accuracy.indexOf("."));
}
int range = Integer.parseInt(accuracy);
range = Math.max(range, Config.MIN_RANGE);
range = Math.min(range, Config.MAX_RANGE);
insertStatement.bindString(1, Integer.toString(mcc));
insertStatement.bindString(2, mnc);
insertStatement.bindString(3, lac);
insertStatement.bindString(4, cid);
insertStatement.bindString(5, longitude);
insertStatement.bindString(6, latitude);
insertStatement.bindString(7, Integer.toString(range));
insertStatement.bindString(8, samples);
insertStatement.executeInsert();
insertStatement.clearBindings();
return this;
}
}