Minor update to show off the possiblities for the refactoring. This is just a short step, major improvements are still to come.
This commit is contained in:
parent
9cb019f5ca
commit
f31eabcefe
7 changed files with 242 additions and 46 deletions
|
@ -20,6 +20,7 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
|
import info.nightscout.androidaps.db.DataServiceManager;
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
@ -522,14 +523,14 @@ public class DataService extends IntentService {
|
||||||
private void handleRemovedFoodRecord(String _id) {
|
private void handleRemovedFoodRecord(String _id) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MainApp.getDbHelper().foodHelper.getDao().deleteByNSId(_id);
|
DataServiceManager.getInstance().getFoodService().deleteByNSId(_id);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleAddChangeFoodRecord(JSONObject trJson) throws JSONException {
|
public void handleAddChangeFoodRecord(JSONObject trJson) throws JSONException {
|
||||||
MainApp.getDbHelper().foodHelper.createFoodFromJsonIfNotExists(trJson);
|
DataServiceManager.getInstance().getFoodService().createFoodFromJsonIfNotExists(trJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRemovedRecordFromNS(String _id) {
|
private void handleRemovedRecordFromNS(String _id) {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class should get registered in the MainApp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DataServiceManager {
|
||||||
|
|
||||||
|
private static final DataServiceManager INSTANCE = new DataServiceManager();
|
||||||
|
|
||||||
|
private FoodService foodService;
|
||||||
|
|
||||||
|
public static DataServiceManager getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FoodService getFoodService() {
|
||||||
|
if (this.foodService == null) {
|
||||||
|
this.foodService = new FoodService();
|
||||||
|
}
|
||||||
|
|
||||||
|
return foodService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,7 +35,6 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
|
||||||
import info.nightscout.androidaps.events.EventNewBG;
|
import info.nightscout.androidaps.events.EventNewBG;
|
||||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
|
@ -55,6 +54,14 @@ import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.PercentageSplitter;
|
import info.nightscout.utils.PercentageSplitter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
|
||||||
|
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
|
||||||
|
*
|
||||||
|
* This class can safely be called from Services, but should not call Services to avoid circular dependencies.
|
||||||
|
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
|
||||||
|
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||||
|
*/
|
||||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
||||||
|
|
||||||
|
@ -94,12 +101,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
||||||
|
|
||||||
public FoodHelper foodHelper;
|
|
||||||
|
|
||||||
public DatabaseHelper(Context context) {
|
public DatabaseHelper(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
onCreate(getWritableDatabase(), getConnectionSource());
|
onCreate(getWritableDatabase(), getConnectionSource());
|
||||||
foodHelper = new FoodHelper(getConnectionSource());
|
|
||||||
//onUpgrade(getWritableDatabase(), getConnectionSource(), 1,1);
|
//onUpgrade(getWritableDatabase(), getConnectionSource(), 1,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +223,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
||||||
foodHelper.resetFood();
|
resetFood();
|
||||||
updateEarliestDataChange(0);
|
updateEarliestDataChange(0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -232,7 +236,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
scheduleTemporaryTargetChange();
|
scheduleTemporaryTargetChange();
|
||||||
scheduleCareportalEventChange();
|
scheduleCareportalEventChange();
|
||||||
scheduleProfileSwitchChange();
|
scheduleProfileSwitchChange();
|
||||||
foodHelper.scheduleFoodChange();
|
|
||||||
new java.util.Timer().schedule(
|
new java.util.Timer().schedule(
|
||||||
new java.util.TimerTask() {
|
new java.util.TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -308,6 +311,17 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
scheduleProfileSwitchChange();
|
scheduleProfileSwitchChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetFood() {
|
||||||
|
try {
|
||||||
|
TableUtils.dropTable(this.getConnectionSource(), Food.class, true);
|
||||||
|
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------ getDao -------------------------------------------
|
// ------------------ getDao -------------------------------------------
|
||||||
|
|
||||||
private Dao<TempTarget, Long> getDaoTempTargets() throws SQLException {
|
private Dao<TempTarget, Long> getDaoTempTargets() throws SQLException {
|
||||||
|
|
|
@ -86,7 +86,6 @@ public class FoodDao extends BaseDaoImpl<Food, Long> {
|
||||||
old.copyFrom(food);
|
old.copyFrom(food);
|
||||||
this.create(old);
|
this.create(old);
|
||||||
log.debug("FOOD: Updating record by _id: " + old.toString());
|
log.debug("FOOD: Updating record by _id: " + old.toString());
|
||||||
FoodHelper.scheduleFoodChange();
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -95,7 +94,6 @@ public class FoodDao extends BaseDaoImpl<Food, Long> {
|
||||||
}
|
}
|
||||||
this.createOrUpdate(food);
|
this.createOrUpdate(food);
|
||||||
log.debug("FOOD: New record: " + food.toString());
|
log.debug("FOOD: New record: " + food.toString());
|
||||||
FoodHelper.scheduleFoodChange();
|
|
||||||
return true;
|
return true;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -103,39 +101,6 @@ public class FoodDao extends BaseDaoImpl<Food, Long> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* deletes an entry by its NS Id.
|
|
||||||
*
|
|
||||||
* Basically a convenience method for findByNSId and deleteFood.
|
|
||||||
*
|
|
||||||
* should be moved to a Service
|
|
||||||
*
|
|
||||||
* @param _id
|
|
||||||
*/
|
|
||||||
public void deleteByNSId(String _id) throws SQLException {
|
|
||||||
Food stored = findByNSId(_id);
|
|
||||||
if (stored != null) {
|
|
||||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
|
||||||
this.deleteFood(stored);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* deletes the food and sends the foodChange Event
|
|
||||||
*
|
|
||||||
* should be moved ot a Service
|
|
||||||
*
|
|
||||||
* @param food
|
|
||||||
*/
|
|
||||||
public void deleteFood(Food food) {
|
|
||||||
try {
|
|
||||||
this.delete(food);
|
|
||||||
FoodHelper.scheduleFoodChange();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* finds food by its NS Id.
|
* finds food by its NS Id.
|
||||||
*
|
*
|
||||||
|
|
175
app/src/main/java/info/nightscout/androidaps/db/FoodService.java
Normal file
175
app/src/main/java/info/nightscout/androidaps/db/FoodService.java
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OrmLiteBaseService;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 24.09.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(FoodService.class);
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||||
|
|
||||||
|
public FoodDao getDao() {
|
||||||
|
return FoodDao.with(this.getConnectionSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service method is just taking care about the Food-Table,
|
||||||
|
* a central dataService should be use for throwing events for all
|
||||||
|
* tables.
|
||||||
|
*/
|
||||||
|
public void resetFood() {
|
||||||
|
this.getHelper().resetFood();
|
||||||
|
scheduleFoodChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A place to centrally register events to be posted, if any data changed.
|
||||||
|
* This should be implemented in an abstract service-class.
|
||||||
|
*
|
||||||
|
* We do need to make sure, that ICallback is extended to be able to handle multiple
|
||||||
|
* events, or handle a list of events.
|
||||||
|
*
|
||||||
|
* on some methods the earliestDataChange event is handled separatly, in that it is checked if it is
|
||||||
|
* set to null by another event already (eg. scheduleExtendedBolusChange).
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* @param eventWorker
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
private void scheduleEvent(final Event event, ScheduledExecutorService eventWorker,
|
||||||
|
final ICallback callback) {
|
||||||
|
|
||||||
|
class PostRunnable implements Runnable {
|
||||||
|
public void run() {
|
||||||
|
log.debug("Firing EventFoodChange");
|
||||||
|
MainApp.bus().post(event);
|
||||||
|
callback.setPost(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prepare task for execution in 1 sec
|
||||||
|
// cancel waiting task to prevent sending multiple posts
|
||||||
|
if (callback.getPost() != null)
|
||||||
|
callback.getPost().cancel(false);
|
||||||
|
Runnable task = new PostRunnable();
|
||||||
|
final int sec = 1;
|
||||||
|
callback.setPost(eventWorker.schedule(task, sec, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule a foodChange Event.
|
||||||
|
*/
|
||||||
|
public void scheduleFoodChange() {
|
||||||
|
this.scheduleEvent(new EventFoodDatabaseChanged(), foodEventWorker, new ICallback() {
|
||||||
|
@Override
|
||||||
|
public void setPost(ScheduledFuture<?> post) {
|
||||||
|
scheduledFoodEventPost = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScheduledFuture<?> getPost() {
|
||||||
|
return scheduledFoodEventPost;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Food> getFoodData() {
|
||||||
|
return this.getDao().getFoodData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"_id": "551ee3ad368e06e80856e6a9",
|
||||||
|
"type": "food",
|
||||||
|
"category": "Zakladni",
|
||||||
|
"subcategory": "Napoje",
|
||||||
|
"name": "Mleko",
|
||||||
|
"portion": 250,
|
||||||
|
"carbs": 12,
|
||||||
|
"gi": 1,
|
||||||
|
"created_at": "2015-04-14T06:59:16.500Z",
|
||||||
|
"unit": "ml"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
public void createFoodFromJsonIfNotExists(JSONObject trJson) {
|
||||||
|
try {
|
||||||
|
Food food = Food.createFromJson(trJson);
|
||||||
|
this.getDao().createOrUpdate(food);
|
||||||
|
} catch (JSONException | SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create of update a food record by the NS (Nightscout) Id.
|
||||||
|
*
|
||||||
|
* @param food
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean createOrUpdateByNS(Food food) {
|
||||||
|
boolean result = this.getDao().createOrUpdateByNS(food);
|
||||||
|
if (result) this.scheduleFoodChange();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes an entry by its NS Id.
|
||||||
|
*
|
||||||
|
* Basically a convenience method for findByNSId and delete.
|
||||||
|
*
|
||||||
|
* @param _id
|
||||||
|
*/
|
||||||
|
public void deleteByNSId(String _id) throws SQLException {
|
||||||
|
Food stored = this.getDao().findByNSId(_id);
|
||||||
|
if (stored != null) {
|
||||||
|
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||||
|
this.delete(stored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes the food and sends the foodChange Event
|
||||||
|
*
|
||||||
|
* should be moved ot a Service
|
||||||
|
*
|
||||||
|
* @param food
|
||||||
|
*/
|
||||||
|
public void delete(Food food) {
|
||||||
|
try {
|
||||||
|
this.getDao().delete(food);
|
||||||
|
this.scheduleFoodChange();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by triplem on 05.01.18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ICallback {
|
||||||
|
|
||||||
|
void setPost(ScheduledFuture<?> post);
|
||||||
|
|
||||||
|
ScheduledFuture<?> getPost();
|
||||||
|
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.db.DataServiceManager;
|
||||||
import info.nightscout.androidaps.db.Food;
|
import info.nightscout.androidaps.db.Food;
|
||||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
|
@ -121,7 +122,7 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().foodHelper.getDao().getFoodData());
|
RecyclerViewAdapter adapter = new RecyclerViewAdapter(DataServiceManager.getInstance().getFoodService().getFoodData());
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
loadData();
|
loadData();
|
||||||
|
@ -144,7 +145,7 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadData() {
|
void loadData() {
|
||||||
unfiltered = MainApp.getDbHelper().foodHelper.getDao().getFoodData();
|
unfiltered = DataServiceManager.getInstance().getFoodService().getFoodData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillCategories() {
|
void fillCategories() {
|
||||||
|
@ -299,7 +300,7 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
if (_id != null && !_id.equals("")) {
|
if (_id != null && !_id.equals("")) {
|
||||||
NSUpload.removeFoodFromNS(_id);
|
NSUpload.removeFoodFromNS(_id);
|
||||||
}
|
}
|
||||||
MainApp.getDbHelper().foodHelper.getDao().deleteFood(food);
|
DataServiceManager.getInstance().getFoodService().delete(food);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
||||||
|
|
Loading…
Reference in a new issue