diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 8648051a..028a68a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -112,7 +112,7 @@ public class GBApplication extends Application { // StatusPrinter.print(lc); // Logger logger = LoggerFactory.getLogger(GBApplication.class); - setupDatabase(); + setupDatabase(this); deviceService = createDeviceService(); GB.environment = GBEnvironment.createDeviceEnvironment(); @@ -202,12 +202,12 @@ public class GBApplication extends Application { return LoggerFactory.getLogger(GBApplication.class); } - private void setupDatabase() { + static void setupDatabase(Context context) { // DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "test-db", null); - DBOpenHelper helper = new DBOpenHelper(this, "test-db", null); + DBOpenHelper helper = new DBOpenHelper(context, "test-db", null); SQLiteDatabase db = helper.getWritableDatabase(); DaoMaster daoMaster = new DaoMaster(db); - lockHandler = new LockHandler(daoMaster.newSession()); + lockHandler = new LockHandler(daoMaster, helper); } public static Context getContext() { @@ -298,6 +298,9 @@ public class GBApplication extends Application { */ public static synchronized boolean deleteActivityDatabase() { // TODO: flush, close, reopen db + if (lockHandler != null) { + lockHandler.closeDb(); + } // if (mActivityDatabaseHandler != null) { // mActivityDatabaseHandler.close(); // mActivityDatabaseHandler = null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java index 982a35a6..1f091fb0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java @@ -7,8 +7,10 @@ import java.util.List; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; @@ -18,10 +20,14 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; */ public class LockHandler implements DBHandler { - private final DaoSession session; + private final DaoMaster daoMaster; + private DaoSession session; + private final SQLiteOpenHelper helper; - public LockHandler(DaoSession daoSession) { - session = daoSession; + public LockHandler(DaoMaster daoMaster, DBOpenHelper helper) { + this.daoMaster = daoMaster; + this.helper = helper; + session = daoMaster.newSession(); } @Override @@ -30,13 +36,27 @@ public class LockHandler implements DBHandler { } @Override - public void closeDb() { + public synchronized void openDb() { + if (session != null) { + throw new IllegalStateException("session must be null"); + } + // this will create completely new db instances. This handler will be dead + GBApplication.setupDatabase(GBApplication.getContext()); + } + @Override + public synchronized void closeDb() { + if (session == null) { + throw new IllegalStateException("session must not be null"); + } + session.clear(); + session.getDatabase().close(); + session = null; } @Override public SQLiteOpenHelper getHelper() { - return null; + return helper; } @Override @@ -45,7 +65,7 @@ public class LockHandler implements DBHandler { } @Override - public SQLiteDatabase getWritableDatabase() { - return null; + public SQLiteDatabase getDatabase() { + return daoMaster.getDatabase(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index aecd5f94..b1d2b742 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -240,7 +240,7 @@ public class DebugActivity extends GBActivity { try (DBHandler dbHandler = GBApplication.acquireDB()) { DBHelper helper = new DBHelper(this); File dir = FileUtils.getExternalFilesDir(); - File destFile = helper.exportDB(dbHandler.getHelper(), dir); + File destFile = helper.exportDB(dbHandler, dir); GB.toast(this, "Exported to: " + destFile.getAbsolutePath(), Toast.LENGTH_LONG, GB.INFO); } catch (Exception ex) { GB.toast(this, "Error exporting DB: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex); @@ -260,7 +260,7 @@ public class DebugActivity extends GBActivity { File dir = FileUtils.getExternalFilesDir(); SQLiteOpenHelper sqLiteOpenHelper = dbHandler.getHelper(); File sourceFile = new File(dir, sqLiteOpenHelper.getDatabaseName()); - helper.importDB(sqLiteOpenHelper, sourceFile); + helper.importDB(dbHandler, sourceFile); helper.validateDB(sqLiteOpenHelper); GB.toast(DebugActivity.this, "Import successful.", Toast.LENGTH_LONG, GB.INFO); } catch (Exception ex) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java index 1c8d881a..f332e36b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java @@ -64,6 +64,11 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl new SchemaMigration().onDowngrade(db, oldVersion, newVersion); } + @Override + public SQLiteDatabase getDatabase() { + return super.getWritableDatabase(); + } + public void addGBActivitySample(ActivitySample sample) { try (SQLiteDatabase db = this.getWritableDatabase()) { ContentValues values = new ContentValues(); @@ -156,7 +161,10 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl @Override public void closeDb() { - GBApplication.releaseDB(); + } + + @Override + public void openDb() { } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java index d9f1ab85..3fd59fd1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java @@ -11,6 +11,7 @@ public interface DBHandler extends AutoCloseable { * Closes the database. */ void closeDb(); + void openDb(); SQLiteOpenHelper getHelper(); @@ -20,7 +21,7 @@ public interface DBHandler extends AutoCloseable { */ void close() throws Exception; - SQLiteDatabase getWritableDatabase(); + SQLiteDatabase getDatabase(); DaoSession getDaoSession(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java index d7d23b85..6b19cd8b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java @@ -37,41 +37,57 @@ public class DBHelper { this.context = context; } - private String getClosedDBPath(SQLiteOpenHelper dbHandler) throws IllegalStateException { - SQLiteDatabase db = dbHandler.getReadableDatabase(); + /** + * Closes the database and returns its name. + * Important: after calling this, you have to DBHandler#openDb() it again + * to get it back to work. + * @param dbHandler + * @return + * @throws IllegalStateException + */ + private String getClosedDBPath(DBHandler dbHandler) throws IllegalStateException { + SQLiteDatabase db = dbHandler.getDatabase(); String path = db.getPath(); - db.close(); + dbHandler.closeDb(); if (db.isOpen()) { // reference counted, so may still be open throw new IllegalStateException("Database must be closed"); } return path; } - public File exportDB(SQLiteOpenHelper dbHandler, File toDir) throws IllegalStateException, IOException { + public File exportDB(DBHandler dbHandler, File toDir) throws IllegalStateException, IOException { String dbPath = getClosedDBPath(dbHandler); - File sourceFile = new File(dbPath); - File destFile = new File(toDir, sourceFile.getName()); - if (destFile.exists()) { - File backup = new File(toDir, destFile.getName() + "_" + getDate()); - destFile.renameTo(backup); - } else if (!toDir.exists()) { - if (!toDir.mkdirs()) { - throw new IOException("Unable to create directory: " + toDir.getAbsolutePath()); + try { + File sourceFile = new File(dbPath); + File destFile = new File(toDir, sourceFile.getName()); + if (destFile.exists()) { + File backup = new File(toDir, destFile.getName() + "_" + getDate()); + destFile.renameTo(backup); + } else if (!toDir.exists()) { + if (!toDir.mkdirs()) { + throw new IOException("Unable to create directory: " + toDir.getAbsolutePath()); + } } - } - FileUtils.copyFile(sourceFile, destFile); - return destFile; + FileUtils.copyFile(sourceFile, destFile); + return destFile; + } finally { + dbHandler.openDb(); + } } private String getDate() { return new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.US).format(new Date()); } - public void importDB(SQLiteOpenHelper dbHandler, File fromFile) throws IllegalStateException, IOException { + public void importDB(DBHandler dbHandler, File fromFile) throws IllegalStateException, IOException { String dbPath = getClosedDBPath(dbHandler); - File toFile = new File(dbPath); - FileUtils.copyFile(fromFile, toFile); + try { + File toFile = new File(dbPath); + FileUtils.copyFile(fromFile, toFile); + } finally { + dbHandler.openDb(); + } } public void validateDB(SQLiteOpenHelper dbHandler) throws IOException {