More WIP for intrgrating old activity db into new one

(one demand to keep user in control)
This commit is contained in:
cpfeiffer 2016-06-17 00:07:50 +02:00
parent d544509b60
commit 13959677af
7 changed files with 164 additions and 69 deletions

View File

@ -44,6 +44,11 @@ public class LockHandler implements DBHandler {
} }
@Override
public DaoMaster getDaoMaster() {
return daoMaster;
}
private boolean isValid() { private boolean isValid() {
return daoMaster != null; return daoMaster != null;
} }

View File

@ -27,12 +27,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapter;
import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
@ -40,6 +47,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
@ -292,6 +300,55 @@ public class DebugActivity extends GBActivity {
.show(); .show();
} }
private void insertActivityDbContents() {
DBHelper helper = new DBHelper(getBaseContext());
ActivityDatabaseHandler oldHandler = helper.getOldActivityDatabaseHandler();
if (oldHandler == null) {
return;
}
GBDevice device = getDeviceForMergingActivityDatabaseInto();
if (device == null) {
return;
}
try (DBHandler targetHandler = GBApplication.acquireDB()) {
helper.importOldDb(oldHandler, device, targetHandler.getDaoMaster(), targetHandler);
} catch (GBException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private GBDevice getDeviceForMergingActivityDatabaseInto() {
final List<GBDevice> availableDevices = new ArrayList<>(DeviceHelper.getInstance().getAvailableDevices(getBaseContext()));
if (availableDevices.isEmpty()) {
return null;
} else if (availableDevices.size() == 1) {
return availableDevices.get(0);
}
GBDeviceAdapter adapter = new GBDeviceAdapter(getBaseContext(), availableDevices);
final GBDevice[] result = new GBDevice[1];
new AlertDialog.Builder(this)
.setCancelable(true)
.setTitle("Delete Activity Data?")
.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
GBDevice device = availableDevices.get(which);
result[0] = device;
}
})
.setMessage("Select the device to merge the previous activity database data into.")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
return result[0];
}
private void deleteActivityDatabase() { private void deleteActivityDatabase() {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setCancelable(true) .setCancelable(true)

View File

@ -292,6 +292,19 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
return -1; return -1;
} }
public boolean hasContent() {
try {
try (SQLiteDatabase db = this.getReadableDatabase()) {
try (Cursor cursor = db.query(TABLE_GBACTIVITYSAMPLES, new String[]{KEY_TIMESTAMP}, null, null, null, KEY_TIMESTAMP + " DESC", "1")) {
return cursor.moveToFirst();
}
}
} catch (Exception ex) {
// can't expect anything
return false;
}
}
@Override @Override
public DaoSession getDaoSession() { public DaoSession getDaoSession() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -32,5 +32,6 @@ public interface DBHandler extends AutoCloseable {
SQLiteDatabase getDatabase(); SQLiteDatabase getDatabase();
DaoMaster getDaoMaster();
DaoSession getDaoSession(); DaoSession getDaoSession();
} }

View File

@ -4,10 +4,12 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -15,7 +17,10 @@ import java.util.Locale;
import de.greenrobot.dao.query.Query; import de.greenrobot.dao.query.Query;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes; import nodomain.freeyourgadget.gadgetbridge.entities.DeviceAttributes;
@ -26,11 +31,19 @@ import nodomain.freeyourgadget.gadgetbridge.entities.UserAttributes;
import nodomain.freeyourgadget.gadgetbridge.entities.UserDao; import nodomain.freeyourgadget.gadgetbridge.entities.UserDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate; import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_CUSTOM_SHORT;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_STEPS;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TIMESTAMP;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.TABLE_GBACTIVITYSAMPLES;
/** /**
* Provides utiliy access to some common entities, so you won't need to use * Provides utiliy access to some common entities, so you won't need to use
* their DAO classes. * their DAO classes.
@ -302,4 +315,76 @@ public class DBHelper {
} }
return false; return false;
} }
/**
* Returns the old activity database handler if there is any content in that
* db, or null otherwise.
* @return the old activity db handler or null
*/
@Nullable
public ActivityDatabaseHandler getOldActivityDatabaseHandler() {
ActivityDatabaseHandler handler = new ActivityDatabaseHandler(context);
if (handler.hasContent()) {
return handler;
}
return null;
}
public void importOldDb(ActivityDatabaseHandler oldDb, GBDevice targetDevice, DaoMaster daoMaster, DBHandler targetDBHandler) {
DaoSession tempSession = daoMaster.newSession();
try {
importActivityDatabase(oldDb, targetDevice, tempSession, targetDBHandler);
} finally {
tempSession.clear();
}
}
private boolean isEmpty(DaoSession session) {
long totalSamplesCount = session.getMiBandActivitySampleDao().count();
totalSamplesCount += session.getPebbleActivitySampleDao().count();
return totalSamplesCount == 0;
}
private void importActivityDatabase(ActivityDatabaseHandler oldDbHandler, GBDevice targetDevice, DaoSession session, DBHandler targetDBHandler) {
try (SQLiteDatabase oldDB = oldDbHandler.getReadableDatabase()) {
User user = DBHelper.getUser(session);
for (DeviceCoordinator coordinator : DeviceHelper.getInstance().getAllCoordinators()) {
AbstractSampleProvider<? extends AbstractActivitySample> sampleProvider = (AbstractSampleProvider<? extends AbstractActivitySample>) coordinator.getSampleProvider(targetDBHandler);
importActivitySamples(oldDB, targetDevice, session, sampleProvider, user);
}
}
}
private <T extends AbstractActivitySample> void importActivitySamples(SQLiteDatabase fromDb, GBDevice targetDevice, DaoSession targetSession, AbstractSampleProvider<T> sampleProvider, User user) {
String order = "timestamp";
final String where = "provider=" + sampleProvider.getID();
try (Cursor cursor = fromDb.query(TABLE_GBACTIVITYSAMPLES, null, where, null, null, null, order)) {
int colTimeStamp = cursor.getColumnIndex(KEY_TIMESTAMP);
int colIntensity = cursor.getColumnIndex(KEY_INTENSITY);
int colSteps = cursor.getColumnIndex(KEY_STEPS);
int colType = cursor.getColumnIndex(KEY_TYPE);
int colCustomShort = cursor.getColumnIndex(KEY_CUSTOM_SHORT);
Long deviceId = DBHelper.getDevice(targetDevice, targetSession).getId();
Long userId = user.getId();
List<T> newSamples = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
T newSample = sampleProvider.createActivitySample();
newSample.setUserId(userId);
newSample.setDeviceId(deviceId);
newSample.setTimestamp(cursor.getInt(colTimeStamp));
newSample.setRawKind(cursor.getInt(colType));
newSample.setProvider(sampleProvider);
newSample.setRawIntensity(cursor.getInt(colIntensity));
newSample.setSteps(cursor.getInt(colSteps));
int hrValue = cursor.getInt(colCustomShort);
if (newSample instanceof HeartRateSample) {
((HeartRateSample)newSample).setHeartRate(hrValue);
}
newSamples.add(newSample);
}
sampleProvider.getSampleDao().insertInTx(newSamples, true);
}
}
} }

View File

@ -3,27 +3,24 @@ package nodomain.freeyourgadget.gadgetbridge.database;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.LockHandler;
import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration; import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample; import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_CUSTOM_SHORT; import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_CUSTOM_SHORT;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY; import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_PROVIDER;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_STEPS; import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_STEPS;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TIMESTAMP; import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TIMESTAMP;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TYPE; import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TYPE;
@ -39,69 +36,6 @@ public class DBOpenHelper extends DaoMaster.OpenHelper {
this.context = context; this.context = context;
} }
public boolean importOldDbIfNecessary(DaoMaster daoMaster, DBHandler targetDBHandler) {
DaoSession tempSession = daoMaster.newSession();
try {
if (isEmpty(tempSession)) {
importActivityDatabaseInto(tempSession, targetDBHandler);
return true;
}
} finally {
tempSession.clear();
}
return false;
}
private boolean isEmpty(DaoSession session) {
long totalSamplesCount = session.getMiBandActivitySampleDao().count();
totalSamplesCount += session.getPebbleActivitySampleDao().count();
return totalSamplesCount == 0;
}
private void importActivityDatabaseInto(DaoSession session, DBHandler targetDBHandler) {
ActivityDatabaseHandler handler = new ActivityDatabaseHandler(getContext());
try (SQLiteDatabase db = handler.getReadableDatabase()) {
User user = DBHelper.getUser(session);
for (DeviceCoordinator coordinator : DeviceHelper.getInstance().getAllCoordinators()) {
AbstractSampleProvider<? extends AbstractActivitySample> sampleProvider = (AbstractSampleProvider<? extends AbstractActivitySample>) coordinator.getSampleProvider(targetDBHandler);
importActivitySamples(db, session, sampleProvider, user);
}
}
}
private <T extends AbstractActivitySample> void importActivitySamples(SQLiteDatabase fromDb, DaoSession targetSession, AbstractSampleProvider<T> sampleProvider, User user) {
String order = "timestamp";
final String where = "provider=" + sampleProvider.getID();
try (Cursor cursor = fromDb.query(TABLE_GBACTIVITYSAMPLES, null, where, null, null, null, order)) {
int colTimeStamp = cursor.getColumnIndex(KEY_TIMESTAMP);
int colIntensity = cursor.getColumnIndex(KEY_INTENSITY);
int colSteps = cursor.getColumnIndex(KEY_STEPS);
int colType = cursor.getColumnIndex(KEY_TYPE);
int colCustomShort = cursor.getColumnIndex(KEY_CUSTOM_SHORT);
Long userId = user.getId();
List<T> newSamples = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
T newSample = sampleProvider.createActivitySample();
newSample.setUserId(userId);
newSample.setDeviceId(deviceId);
newSample.setTimestamp(cursor.getInt(colTimeStamp));
newSample.setRawKind(cursor.getInt(colType));
newSample.setProvider(sampleProvider);
newSample.setRawIntensity(cursor.getInt(colIntensity));
newSample.setSteps(cursor.getInt(colSteps));
int hrValue = cursor.getInt(colCustomShort);
if (newSample instanceof HeartRateSample) {
((HeartRateSample)newSample).setHeartRate(hrValue);
}
newSamples.add(newSample);
}
sampleProvider.getSampleDao().insertInTx(newSamples, true);
}
}
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
new SchemaMigration(updaterClassNamePrefix).onUpgrade(db, oldVersion, newVersion); new SchemaMigration(updaterClassNamePrefix).onUpgrade(db, oldVersion, newVersion);

View File

@ -38,7 +38,7 @@ public abstract class AbstractActivitySample implements ActivitySample {
public abstract Long getUserId(); public abstract Long getUserId();
public abstract void setDeviceId(Long userId); public abstract void setDeviceId(Long deviceId);
public abstract Long getDeviceId(); public abstract Long getDeviceId();