#557 - showoff of possible refactorings - see REFACTOR.md for additonal details
This commit is contained in:
parent
9255b93800
commit
9cb019f5ca
7 changed files with 249 additions and 216 deletions
|
@ -12,6 +12,8 @@ import org.json.JSONObject;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
@ -518,7 +520,12 @@ public class DataService extends IntentService {
|
|||
}
|
||||
|
||||
private void handleRemovedFoodRecord(String _id) {
|
||||
MainApp.getDbHelper().foodHelper.deleteFoodById(_id);
|
||||
|
||||
try {
|
||||
MainApp.getDbHelper().foodHelper.getDao().deleteByNSId(_id);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleAddChangeFoodRecord(JSONObject trJson) throws JSONException {
|
||||
|
|
|
@ -68,7 +68,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public static final String DATABASE_DBREQUESTS = "DBRequests";
|
||||
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
|
||||
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
|
||||
public static final String DATABASE_FOODS = "Foods";
|
||||
|
||||
private static final int DATABASE_VERSION = 8;
|
||||
|
||||
|
@ -95,11 +94,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
||||
|
||||
public FoodHelper foodHelper = new FoodHelper(this);
|
||||
public FoodHelper foodHelper;
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
onCreate(getWritableDatabase(), getConnectionSource());
|
||||
foodHelper = new FoodHelper(getConnectionSource());
|
||||
//onUpgrade(getWritableDatabase(), getConnectionSource(), 1,1);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,20 +3,25 @@ package info.nightscout.androidaps.db;
|
|||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.09.2017.
|
||||
*/
|
||||
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_FOODS)
|
||||
@DatabaseTable(tableName = Food.TABLE_FOODS)
|
||||
public class Food {
|
||||
private static Logger log = LoggerFactory.getLogger(Food.class);
|
||||
|
||||
public static final String TABLE_FOODS = "Foods";
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long key;
|
||||
|
||||
|
@ -64,6 +69,25 @@ public class Food {
|
|||
key = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static Food createFromJson(JSONObject json) throws JSONException {
|
||||
Food food = new Food();
|
||||
if ("food".equals(JsonHelper.safeGetString(json, "type"))) {
|
||||
food._id = JsonHelper.safeGetString(json, "_id");
|
||||
food.category = JsonHelper.safeGetString(json, "category");
|
||||
food.subcategory = JsonHelper.safeGetString(json, "subcategory");
|
||||
food.name = JsonHelper.safeGetString(json, "name");
|
||||
food.units = JsonHelper.safeGetString(json, "unit");
|
||||
food.portion = JsonHelper.safeGetDouble(json, "portion");
|
||||
food.carbs = JsonHelper.safeGetInt(json, "carbs");
|
||||
food.gi = JsonHelper.safeGetInt(json, "gi");
|
||||
food.energy = JsonHelper.safeGetInt(json, "energy");
|
||||
food.protein = JsonHelper.safeGetInt(json, "protein");
|
||||
food.fat = JsonHelper.safeGetInt(json, "fat");
|
||||
}
|
||||
|
||||
return food;
|
||||
}
|
||||
|
||||
public boolean isEqual(Food other) {
|
||||
if (portion != other.portion)
|
||||
return false;
|
||||
|
|
161
app/src/main/java/info/nightscout/androidaps/db/FoodDao.java
Normal file
161
app/src/main/java/info/nightscout/androidaps/db/FoodDao.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
import com.j256.ormlite.dao.BaseDaoImpl;
|
||||
import com.j256.ormlite.dao.DaoManager;
|
||||
import com.j256.ormlite.stmt.PreparedQuery;
|
||||
import com.j256.ormlite.stmt.QueryBuilder;
|
||||
import com.j256.ormlite.support.ConnectionSource;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by triplem on 04.01.18.
|
||||
*/
|
||||
|
||||
public class FoodDao extends BaseDaoImpl<Food, Long> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FoodDao.class);
|
||||
|
||||
public FoodDao(ConnectionSource source) throws SQLException {
|
||||
super(source, Food.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static instantiation methods. The database connection is accessed via
|
||||
* the OpenHelperManager which keeps a count of the number of objects
|
||||
* using the connection. Thus every call to connect() must be matched by
|
||||
* a call to release() once the session is done.
|
||||
*/
|
||||
public static FoodDao connect(Context context) {
|
||||
return with(OpenHelperManager.getHelper(context, DatabaseHelper.class)
|
||||
.getConnectionSource());
|
||||
}
|
||||
|
||||
public static FoodDao with(ConnectionSource connection) {
|
||||
try {
|
||||
return (FoodDao) DaoManager.createDao(connection, Food.class);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releasing the DAO flags the connection manager that the DAO is no
|
||||
* longer using the connection. When the connection count is zero, the
|
||||
* connection manager will close the database.
|
||||
*/
|
||||
public void release() {
|
||||
OpenHelperManager.releaseHelper();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @deprecated should use queryForAll instead, which is a standard method of the ORMLite DAO
|
||||
*/
|
||||
public List<Food> getFoodData() {
|
||||
try {
|
||||
QueryBuilder<Food, Long> queryBuilder = this.queryBuilder();
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
return this.query(preparedQuery);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean createOrUpdateByNS(Food food) {
|
||||
try {
|
||||
// find by NS _id
|
||||
if (food._id != null) {
|
||||
Food old = this.findByNSId(food._id);
|
||||
|
||||
if (old != null) {
|
||||
if (!old.isEqual(food)) {
|
||||
this.delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(food);
|
||||
this.create(old);
|
||||
log.debug("FOOD: Updating record by _id: " + old.toString());
|
||||
FoodHelper.scheduleFoodChange();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.createOrUpdate(food);
|
||||
log.debug("FOOD: New record: " + food.toString());
|
||||
FoodHelper.scheduleFoodChange();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @param _id
|
||||
* @return
|
||||
*/
|
||||
public Food findByNSId(String _id) {
|
||||
try {
|
||||
List<Food> list = this.queryForEq("_id", _id);
|
||||
|
||||
if (list.size() == 1) { // really? if there are more then one result, then we do not return anything...
|
||||
return list.get(0);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import com.j256.ormlite.android.AndroidConnectionSource;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.stmt.PreparedQuery;
|
||||
import com.j256.ormlite.stmt.QueryBuilder;
|
||||
import com.j256.ormlite.stmt.Where;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
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.EventFoodDatabaseChanged;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.09.2017.
|
||||
*/
|
||||
|
||||
public class FoodHelper {
|
||||
private static Logger log = LoggerFactory.getLogger(FoodHelper.class);
|
||||
|
||||
DatabaseHelper databaseHelper;
|
||||
|
||||
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||
|
||||
public FoodHelper(DatabaseHelper databaseHelper) {
|
||||
this.databaseHelper = databaseHelper;
|
||||
}
|
||||
|
||||
private Dao<Food, Long> getDaoFood() throws SQLException {
|
||||
return databaseHelper.getDao(Food.class);
|
||||
}
|
||||
|
||||
public void resetFood() {
|
||||
try {
|
||||
TableUtils.dropTable(databaseHelper.getConnectionSource(), Food.class, true);
|
||||
TableUtils.createTableIfNotExists(databaseHelper.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleFoodChange();
|
||||
}
|
||||
|
||||
public List<Food> getFoodData() {
|
||||
try {
|
||||
Dao<Food, Long> daoFood = getDaoFood();
|
||||
List<Food> foods;
|
||||
QueryBuilder<Food, Long> queryBuilder = daoFood.queryBuilder();
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
foods = daoFood.query(preparedQuery);
|
||||
return foods;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean createOrUpdate(Food food) {
|
||||
try {
|
||||
// find by NS _id
|
||||
if (food._id != null && !food._id.equals("")) {
|
||||
Food old;
|
||||
|
||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", food._id);
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
List<Food> found = getDaoFood().query(preparedQuery);
|
||||
if (found.size() > 0) {
|
||||
old = found.get(0);
|
||||
if (!old.isEqual(food)) {
|
||||
getDaoFood().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(food);
|
||||
getDaoFood().create(old);
|
||||
log.debug("FOOD: Updating record by _id: " + old.toString());
|
||||
scheduleFoodChange();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
getDaoFood().createOrUpdate(food);
|
||||
log.debug("FOOD: New record: " + food.toString());
|
||||
scheduleFoodChange();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(Food food) {
|
||||
try {
|
||||
getDaoFood().delete(food);
|
||||
scheduleFoodChange();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void scheduleFoodChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventFoodChange");
|
||||
MainApp.bus().post(new EventFoodDatabaseChanged());
|
||||
scheduledFoodEventPost = null;
|
||||
}
|
||||
}
|
||||
// prepare task for execution in 1 sec
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
if (scheduledFoodEventPost != null)
|
||||
scheduledFoodEventPost.cancel(false);
|
||||
Runnable task = new PostRunnable();
|
||||
final int sec = 1;
|
||||
scheduledFoodEventPost = foodEventWorker.schedule(task, sec, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_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 = new Food();
|
||||
if (trJson.has("type") && trJson.getString("type").equals("food")) {
|
||||
if (trJson.has("_id"))
|
||||
food._id = trJson.getString("_id");
|
||||
if (trJson.has("category"))
|
||||
food.category = trJson.getString("category");
|
||||
if (trJson.has("subcategory"))
|
||||
food.subcategory = trJson.getString("subcategory");
|
||||
if (trJson.has("name"))
|
||||
food.name = trJson.getString("name");
|
||||
if (trJson.has("unit"))
|
||||
food.units = trJson.getString("unit");
|
||||
if (trJson.has("portion"))
|
||||
food.portion = trJson.getDouble("portion");
|
||||
if (trJson.has("carbs"))
|
||||
food.carbs = trJson.getInt("carbs");
|
||||
if (trJson.has("gi"))
|
||||
food.gi = trJson.getInt("gi");
|
||||
if (trJson.has("energy"))
|
||||
food.energy = trJson.getInt("energy");
|
||||
if (trJson.has("protein"))
|
||||
food.protein = trJson.getInt("protein");
|
||||
if (trJson.has("fat"))
|
||||
food.fat = trJson.getInt("fat");
|
||||
}
|
||||
createOrUpdate(food);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteFoodById(String _id) {
|
||||
Food stored = findFoodById(_id);
|
||||
if (stored != null) {
|
||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
scheduleFoodChange();
|
||||
}
|
||||
}
|
||||
|
||||
public Food findFoodById(String _id) {
|
||||
try {
|
||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", _id);
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
List<Food> list = getDaoFood().query(preparedQuery);
|
||||
|
||||
if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -121,7 +121,7 @@ public class FoodFragment extends SubscriberFragment {
|
|||
}
|
||||
});
|
||||
|
||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().foodHelper.getFoodData());
|
||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().foodHelper.getDao().getFoodData());
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
loadData();
|
||||
|
@ -144,7 +144,7 @@ public class FoodFragment extends SubscriberFragment {
|
|||
}
|
||||
|
||||
void loadData() {
|
||||
unfiltered = MainApp.getDbHelper().foodHelper.getFoodData();
|
||||
unfiltered = MainApp.getDbHelper().foodHelper.getDao().getFoodData();
|
||||
}
|
||||
|
||||
void fillCategories() {
|
||||
|
@ -299,7 +299,7 @@ public class FoodFragment extends SubscriberFragment {
|
|||
if (_id != null && !_id.equals("")) {
|
||||
NSUpload.removeFoodFromNS(_id);
|
||||
}
|
||||
MainApp.getDbHelper().foodHelper.delete(food);
|
||||
MainApp.getDbHelper().foodHelper.getDao().deleteFood(food);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
||||
|
|
49
app/src/main/java/info/nightscout/utils/JsonHelper.java
Normal file
49
app/src/main/java/info/nightscout/utils/JsonHelper.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package info.nightscout.utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* JSonHelper is a Helper class which contains several methods to safely get data from the ggiven JSONObject.
|
||||
*
|
||||
* Created by triplem on 04.01.18.
|
||||
*/
|
||||
|
||||
public class JsonHelper {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(JsonHelper.class);
|
||||
|
||||
private JsonHelper() {};
|
||||
|
||||
public static String safeGetString(JSONObject json, String fieldName) throws JSONException {
|
||||
String result = null;
|
||||
|
||||
if (json.has(fieldName)) {
|
||||
result = json.getString(fieldName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double safeGetDouble(JSONObject json, String fieldName) throws JSONException {
|
||||
double result = 0d;
|
||||
|
||||
if (json.has(fieldName)) {
|
||||
result = json.getDouble(fieldName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int safeGetInt(JSONObject json, String fieldName) throws JSONException {
|
||||
int result = 0;
|
||||
|
||||
if (json.has(fieldName)) {
|
||||
result = json.getInt(fieldName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue