diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 5cdf5fc9..c26013d1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -30,6 +30,7 @@ import ch.qos.logback.core.Appender; import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBConstants; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.database.DaoHandler; import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService; @@ -51,7 +52,7 @@ public class GBApplication extends Application { // Since this class must not log to slf4j, we use plain android.util.Log private static final String TAG = "GBApplication"; private static GBApplication context; - private static ActivityDatabaseHandler mActivityDatabaseHandler; + private static DBHandler mActivityDatabaseHandler; private static final Lock dbLock = new ReentrantLock(); private static DeviceService deviceService; private static SharedPreferences sharedPrefs; @@ -118,7 +119,7 @@ public class GBApplication extends Application { deviceService = createDeviceService(); GB.environment = GBEnvironment.createDeviceEnvironment(); - mActivityDatabaseHandler = new ActivityDatabaseHandler(context); +// mActivityDatabaseHandler = new ActivityDatabaseHandler(context); loadBlackList(); IntentFilter filterLocal = new IntentFilter(); @@ -209,6 +210,7 @@ public class GBApplication extends Application { SQLiteDatabase db = helper.getWritableDatabase(); DaoMaster daoMaster = new DaoMaster(db); daoSession = daoMaster.newSession(); + mActivityDatabaseHandler = new DaoHandler(daoMaster, helper); } public static DaoSession getDaoSession() { 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 ce9e1ae4..539667af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/ActivityDatabaseHandler.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationScript; +import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; @@ -52,49 +53,12 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - LOG.info("ActivityDatabase: schema upgrade requested from " + oldVersion + " to " + newVersion); - try { - for (int i = oldVersion + 1; i <= newVersion; i++) { - DBUpdateScript updater = getUpdateScript(db, i); - if (updater != null) { - LOG.info("upgrading activity database to version " + i); - updater.upgradeSchema(db); - } - } - LOG.info("activity database is now at version " + newVersion); - } catch (RuntimeException ex) { - GB.toast("Error upgrading database.", Toast.LENGTH_SHORT, GB.ERROR, ex); - throw ex; // reject upgrade - } + new SchemaMigration().onUpgrade(db, oldVersion, newVersion); } @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { - LOG.info("ActivityDatabase: schema downgrade requested from " + oldVersion + " to " + newVersion); - try { - for (int i = oldVersion; i >= newVersion; i--) { - DBUpdateScript updater = getUpdateScript(db, i); - if (updater != null) { - LOG.info("downgrading activity database to version " + (i - 1)); - updater.downgradeSchema(db); - } - } - LOG.info("activity database is now at version " + newVersion); - } catch (RuntimeException ex) { - GB.toast("Error downgrading database.", Toast.LENGTH_SHORT, GB.ERROR, ex); - throw ex; // reject downgrade - } - } - - private DBUpdateScript getUpdateScript(SQLiteDatabase db, int version) { - try { - Class updateClass = getClass().getClassLoader().loadClass(getClass().getPackage().getName() + ".schema.ActivityDBUpdate_" + version); - return (DBUpdateScript) updateClass.newInstance(); - } catch (ClassNotFoundException e) { - return null; - } catch (InstantiationException | IllegalAccessException e) { - throw new RuntimeException("Error instantiating DBUpdate class for version " + version, e); - } + new SchemaMigration().onDowngrade(db, oldVersion, newVersion); } public void addGBActivitySample(ActivitySample sample) { 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 49dbbd40..b0ad2620 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHandler.java @@ -10,6 +10,11 @@ import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; public interface DBHandler { + /** + * Closes the database. + */ + void close(); + SQLiteOpenHelper getHelper(); /** diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DaoHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DaoHandler.java new file mode 100644 index 00000000..6887ac12 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DaoHandler.java @@ -0,0 +1,82 @@ +package nodomain.freeyourgadget.gadgetbridge.database; + +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; + +public class DaoHandler implements DBHandler { + + private final DaoMaster mDaoMaster; + private final SQLiteOpenHelper openHelper; + + public DaoHandler(DaoMaster master, DaoMaster.DevOpenHelper helper) { + mDaoMaster = master; + openHelper = helper; + } + + @Override + public void close() { + getHelper().close(); + } + + @Override + public SQLiteOpenHelper getHelper() { + return openHelper; + } + + @Override + public void release() { + GBApplication.releaseDB(); + } + + @Override + public List getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) { + return null; + } + + @Override + public List getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) { + return null; + } + + @Override + public List getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) { + return null; + } + + @Override + public void addGBActivitySample(int timestamp, int provider, int intensity, int steps, int kind, int heartrate) { + + } + + @Override + public void addGBActivitySamples(ActivitySample[] activitySamples) { + + } + + @Override + public SQLiteDatabase getWritableDatabase() { + return mDaoMaster.getDatabase(); + } + + @Override + public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind, SampleProvider provider) { + + } + + @Override + public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) { + + } + + @Override + public int fetchLatestTimestamp(SampleProvider provider) { + return 0; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java new file mode 100644 index 00000000..6e1c959b --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/SchemaMigration.java @@ -0,0 +1,59 @@ +package nodomain.freeyourgadget.gadgetbridge.database.schema; + +import android.database.sqlite.SQLiteDatabase; +import android.widget.Toast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class SchemaMigration { + private static final Logger LOG = LoggerFactory.getLogger(SchemaMigration.class); + + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + LOG.info("ActivityDatabase: schema upgrade requested from " + oldVersion + " to " + newVersion); + try { + for (int i = oldVersion + 1; i <= newVersion; i++) { + DBUpdateScript updater = getUpdateScript(db, i); + if (updater != null) { + LOG.info("upgrading activity database to version " + i); + updater.upgradeSchema(db); + } + } + LOG.info("activity database is now at version " + newVersion); + } catch (RuntimeException ex) { + GB.toast("Error upgrading database.", Toast.LENGTH_SHORT, GB.ERROR, ex); + throw ex; // reject upgrade + } + } + + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + LOG.info("ActivityDatabase: schema downgrade requested from " + oldVersion + " to " + newVersion); + try { + for (int i = oldVersion; i >= newVersion; i--) { + DBUpdateScript updater = getUpdateScript(db, i); + if (updater != null) { + LOG.info("downgrading activity database to version " + (i - 1)); + updater.downgradeSchema(db); + } + } + LOG.info("activity database is now at version " + newVersion); + } catch (RuntimeException ex) { + GB.toast("Error downgrading database.", Toast.LENGTH_SHORT, GB.ERROR, ex); + throw ex; // reject downgrade + } + } + + private DBUpdateScript getUpdateScript(SQLiteDatabase db, int version) { + try { + Class updateClass = getClass().getClassLoader().loadClass(getClass().getPackage().getName() + ".schema.ActivityDBUpdate_" + version); + return (DBUpdateScript) updateClass.newInstance(); + } catch (ClassNotFoundException e) { + return null; + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException("Error instantiating DBUpdate class for version " + version, e); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBActivitySample2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBActivitySample2.java new file mode 100644 index 00000000..d01b322e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBActivitySample2.java @@ -0,0 +1,94 @@ +package nodomain.freeyourgadget.gadgetbridge.impl; + +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; + +public class GBActivitySample2 implements ActivitySample { + private final int timestamp; + private final SampleProvider provider; + private final int intensity; + private final int steps; + private final int type; + private final int customValue; + + public GBActivitySample2(SampleProvider provider, int timestamp, int intensity, int steps, int type) { + this(provider, timestamp, intensity, steps, type, 0); + } + + public GBActivitySample2(SampleProvider provider, int timestamp, int intensity, int steps, int type, int customValue) { + this.timestamp = timestamp; + this.provider = provider; + this.intensity = intensity; + this.steps = steps; + this.customValue = customValue; + this.type = type; + validate(); + } + + private void validate() { + if (steps < 0) { + throw new IllegalArgumentException("steps must be >= 0"); + } + if (intensity < 0) { + throw new IllegalArgumentException("intensity must be >= 0"); + } + if (timestamp < 0) { + throw new IllegalArgumentException("timestamp must be >= 0"); + } + if (customValue < 0) { + throw new IllegalArgumentException("customValue must be >= 0"); + } + } + + @Override + public int getTimestamp() { + return timestamp; + } + + @Override + public SampleProvider getProvider() { + return provider; + } + + @Override + public int getRawIntensity() { + return intensity; + } + + @Override + public float getIntensity() { + return getProvider().normalizeIntensity(getRawIntensity()); + } + + @Override + public int getSteps() { + return steps; + } + + @Override + public int getRawKind() { + return type; + } + + @Override + public int getKind() { + return getProvider().normalizeType(getRawKind()); + } + + @Override + public int getCustomValue() { + return customValue; + } + + @Override + public String toString() { + return "GBActivitySample{" + + "timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(timestamp)) + + ", intensity=" + getIntensity() + + ", steps=" + getSteps() + + ", customValue=" + getCustomValue() + + ", type=" + getKind() + + '}'; + } +}