Never store reference to SQLiteDatabase

SQLiteDatabase closes automatically at random times. Storing a reference
to an open SQLiteDatabase eventually leads to a crash.
See: https://stackoverflow.com/questions/1483629/
pull/316/head
Alinson S. Xavier 8 years ago
parent 9fe446b424
commit 91996924d9

@ -53,38 +53,27 @@ public class SQLiteCheckmarkList extends CheckmarkList
@Nullable @Nullable
private CachedData cache; private CachedData cache;
@NonNull
private final SQLiteStatement invalidateStatement;
@NonNull
private final SQLiteStatement addStatement;
@NonNull
private final SQLiteDatabase db;
public SQLiteCheckmarkList(Habit habit) public SQLiteCheckmarkList(Habit habit)
{ {
super(habit); super(habit);
sqlite = new SQLiteUtils<>(CheckmarkRecord.class); sqlite = new SQLiteUtils<>(CheckmarkRecord.class);
db = Cache.openDatabase();
addStatement = db.compileStatement(ADD_QUERY);
invalidateStatement = db.compileStatement(INVALIDATE_QUERY);
} }
@Override @Override
public void add(List<Checkmark> checkmarks) public void add(List<Checkmark> checkmarks)
{ {
check(habit.getId()); check(habit.getId());
SQLiteDatabase db = Cache.openDatabase();
SQLiteStatement statement = db.compileStatement(ADD_QUERY);
db.beginTransaction(); db.beginTransaction();
try try
{ {
for (Checkmark c : checkmarks) for (Checkmark c : checkmarks)
{ {
addStatement.bindLong(1, habit.getId()); statement.bindLong(1, habit.getId());
addStatement.bindLong(2, c.getTimestamp()); statement.bindLong(2, c.getTimestamp());
addStatement.bindLong(3, c.getValue()); statement.bindLong(3, c.getValue());
addStatement.execute(); statement.execute();
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();
@ -132,9 +121,11 @@ public class SQLiteCheckmarkList extends CheckmarkList
public void invalidateNewerThan(long timestamp) public void invalidateNewerThan(long timestamp)
{ {
cache = null; cache = null;
invalidateStatement.bindLong(1, habit.getId()); SQLiteDatabase db = Cache.openDatabase();
invalidateStatement.bindLong(2, timestamp); SQLiteStatement statement = db.compileStatement(INVALIDATE_QUERY);
invalidateStatement.execute(); statement.bindLong(1, habit.getId());
statement.bindLong(2, timestamp);
statement.execute();
observable.notifyListeners(); observable.notifyListeners();
} }

@ -49,14 +49,6 @@ public class SQLiteScoreList extends ScoreList
@NonNull @NonNull
private final SQLiteUtils<ScoreRecord> sqlite; private final SQLiteUtils<ScoreRecord> sqlite;
@NonNull
private final SQLiteStatement invalidateStatement;
@NonNull
private final SQLiteStatement addStatement;
private final SQLiteDatabase db;
@Nullable @Nullable
private CachedData cache = null; private CachedData cache = null;
@ -69,25 +61,23 @@ public class SQLiteScoreList extends ScoreList
{ {
super(habit); super(habit);
sqlite = new SQLiteUtils<>(ScoreRecord.class); sqlite = new SQLiteUtils<>(ScoreRecord.class);
db = Cache.openDatabase();
addStatement = db.compileStatement(ADD_QUERY);
invalidateStatement = db.compileStatement(INVALIDATE_QUERY);
} }
@Override @Override
public void add(List<Score> scores) public void add(List<Score> scores)
{ {
check(habit.getId()); check(habit.getId());
SQLiteDatabase db = Cache.openDatabase();
SQLiteStatement statement = db.compileStatement(ADD_QUERY);
db.beginTransaction(); db.beginTransaction();
try try
{ {
for (Score s : scores) for (Score s : scores)
{ {
addStatement.bindLong(1, habit.getId()); statement.bindLong(1, habit.getId());
addStatement.bindLong(2, s.getTimestamp()); statement.bindLong(2, s.getTimestamp());
addStatement.bindLong(3, s.getValue()); statement.bindLong(3, s.getValue());
addStatement.execute(); statement.execute();
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();
@ -150,9 +140,11 @@ public class SQLiteScoreList extends ScoreList
public synchronized void invalidateNewerThan(long timestamp) public synchronized void invalidateNewerThan(long timestamp)
{ {
cache = null; cache = null;
invalidateStatement.bindLong(1, habit.getId()); SQLiteDatabase db = Cache.openDatabase();
invalidateStatement.bindLong(2, timestamp); SQLiteStatement statement = db.compileStatement(INVALIDATE_QUERY);
invalidateStatement.execute(); statement.bindLong(1, habit.getId());
statement.bindLong(2, timestamp);
statement.execute();
getObservable().notifyListeners(); getObservable().notifyListeners();
} }

@ -37,22 +37,19 @@ import java.util.*;
*/ */
public class SQLiteStreakList extends StreakList public class SQLiteStreakList extends StreakList
{ {
private static final String INVALIDATE_QUERY =
"delete from Streak where habit = ? and end >= ?";
private HabitRecord habitRecord; private HabitRecord habitRecord;
@NonNull @NonNull
private final SQLiteUtils<StreakRecord> sqlite; private final SQLiteUtils<StreakRecord> sqlite;
private final SQLiteStatement invalidateStatement;
public SQLiteStreakList(Habit habit) public SQLiteStreakList(Habit habit)
{ {
super(habit); super(habit);
sqlite = new SQLiteUtils<>(StreakRecord.class); sqlite = new SQLiteUtils<>(StreakRecord.class);
SQLiteDatabase db = Cache.openDatabase();
String invalidateQuery = "delete from Streak where habit = ? " +
"and end >= ?";
invalidateStatement = db.compileStatement(invalidateQuery);
} }
@Override @Override
@ -81,9 +78,11 @@ public class SQLiteStreakList extends StreakList
@Override @Override
public void invalidateNewerThan(long timestamp) public void invalidateNewerThan(long timestamp)
{ {
invalidateStatement.bindLong(1, habit.getId()); SQLiteDatabase db = Cache.openDatabase();
invalidateStatement.bindLong(2, timestamp - DateUtils.millisecondsInOneDay); SQLiteStatement statement = db.compileStatement(INVALIDATE_QUERY);
invalidateStatement.execute(); statement.bindLong(1, habit.getId());
statement.bindLong(2, timestamp - DateUtils.millisecondsInOneDay);
statement.execute();
observable.notifyListeners(); observable.notifyListeners();
} }

Loading…
Cancel
Save