mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Repair inconsistent data instead of throwing exception
This commit is contained in:
@@ -171,13 +171,13 @@ public class MainTest
|
||||
clickMenuItem(R.string.archive);
|
||||
assertHabitsDontExist(names);
|
||||
|
||||
clickMenuItem(R.string.show_archived);
|
||||
clickMenuItem(R.string.hide_archived);
|
||||
|
||||
assertHabitsExist(names);
|
||||
selectHabits(names);
|
||||
clickMenuItem(R.string.unarchive);
|
||||
|
||||
clickMenuItem(R.string.show_archived);
|
||||
clickMenuItem(R.string.hide_archived);
|
||||
|
||||
assertHabitsExist(names);
|
||||
deleteHabits(names);
|
||||
|
||||
@@ -115,6 +115,41 @@ public class SQLiteCheckmarkListTest extends BaseAndroidTest
|
||||
assertThat(records.get(0).timestamp, equalTo(today - 21 * day));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixRecords() throws Exception
|
||||
{
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
long from = DateUtils.getStartOfToday();
|
||||
long to = from + 5 * day;
|
||||
|
||||
List<CheckmarkRecord> original, actual, expected;
|
||||
HabitRecord habit = new HabitRecord();
|
||||
|
||||
original = new ArrayList<>();
|
||||
original.add(new CheckmarkRecord(habit, from + 8*day, 2));
|
||||
original.add(new CheckmarkRecord(habit, from + 5*day, 0));
|
||||
original.add(new CheckmarkRecord(habit, from + 4*day, 0));
|
||||
original.add(new CheckmarkRecord(habit, from + 4*day, 2));
|
||||
original.add(new CheckmarkRecord(habit, from + 3*day, 2));
|
||||
original.add(new CheckmarkRecord(habit, from + 2*day, 1));
|
||||
original.add(new CheckmarkRecord(habit, from + 2*day + 100, 1));
|
||||
original.add(new CheckmarkRecord(habit, from, 0));
|
||||
original.add(new CheckmarkRecord(habit, from, 2));
|
||||
original.add(new CheckmarkRecord(habit, from - day, 2));
|
||||
|
||||
actual = SQLiteCheckmarkList.fixRecords(original, habit, from, to);
|
||||
|
||||
expected = new ArrayList<>();
|
||||
expected.add(new CheckmarkRecord(habit, from + 5*day, 0));
|
||||
expected.add(new CheckmarkRecord(habit, from + 4*day, 2));
|
||||
expected.add(new CheckmarkRecord(habit, from + 3*day, 2));
|
||||
expected.add(new CheckmarkRecord(habit, from + 2*day, 1));
|
||||
expected.add(new CheckmarkRecord(habit, from + day, 0));
|
||||
expected.add(new CheckmarkRecord(habit, from, 2));
|
||||
|
||||
assertThat(actual, equalTo(expected));
|
||||
}
|
||||
|
||||
private List<CheckmarkRecord> getAllRecords()
|
||||
{
|
||||
return new Select()
|
||||
|
||||
@@ -115,14 +115,7 @@ public class SQLiteCheckmarkList extends CheckmarkList
|
||||
List<CheckmarkRecord> records = sqlite.query(query, params);
|
||||
for (CheckmarkRecord record : records) record.habit = habitRecord;
|
||||
|
||||
int nDays = DateUtils.getDaysBetween(fromTimestamp, toTimestamp) + 1;
|
||||
if (records.size() != nDays)
|
||||
{
|
||||
throw new InconsistentDatabaseException(
|
||||
String.format("habit=%s, %d expected, %d found",
|
||||
habit.getName(), nDays, records.size()));
|
||||
}
|
||||
|
||||
records = fixRecords(records, habitRecord, fromTimestamp, toTimestamp);
|
||||
return toCheckmarks(records);
|
||||
}
|
||||
|
||||
@@ -198,6 +191,28 @@ public class SQLiteCheckmarkList extends CheckmarkList
|
||||
return checkmarks;
|
||||
}
|
||||
|
||||
public static List<CheckmarkRecord> fixRecords(List<CheckmarkRecord> original,
|
||||
HabitRecord habit,
|
||||
long fromTimestamp,
|
||||
long toTimestamp)
|
||||
{
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
ArrayList<CheckmarkRecord> records = new ArrayList<>();
|
||||
|
||||
for (long t = toTimestamp; t >= fromTimestamp; t -= day)
|
||||
records.add(new CheckmarkRecord(habit, t, Checkmark.UNCHECKED));
|
||||
|
||||
for (CheckmarkRecord record : original)
|
||||
{
|
||||
if ((toTimestamp - record.timestamp) % day != 0) continue;
|
||||
int offset = (int) ((toTimestamp - record.timestamp) / day);
|
||||
if (offset < 0 || offset >= records.size()) continue;
|
||||
records.set(offset, record);
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
private static class CachedData
|
||||
{
|
||||
int todayValue;
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.database.*;
|
||||
import com.activeandroid.*;
|
||||
import com.activeandroid.annotation.*;
|
||||
|
||||
import org.apache.commons.lang3.builder.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
|
||||
/**
|
||||
@@ -53,6 +54,17 @@ public class CheckmarkRecord extends Model implements SQLiteRecord
|
||||
@Column(name = "value")
|
||||
public Integer value;
|
||||
|
||||
public CheckmarkRecord()
|
||||
{
|
||||
}
|
||||
|
||||
public CheckmarkRecord(HabitRecord habit, Long timestamp, Integer value)
|
||||
{
|
||||
this.habit = habit;
|
||||
this.timestamp = timestamp;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(Cursor c)
|
||||
{
|
||||
@@ -64,4 +76,40 @@ public class CheckmarkRecord extends Model implements SQLiteRecord
|
||||
{
|
||||
return new Checkmark(timestamp, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
CheckmarkRecord that = (CheckmarkRecord) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(habit, that.habit)
|
||||
.append(timestamp, that.timestamp)
|
||||
.append(value, that.value)
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.append(habit)
|
||||
.append(timestamp)
|
||||
.append(value)
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return new ToStringBuilder(this)
|
||||
.append("habit", habit)
|
||||
.append("timestamp", timestamp)
|
||||
.append("value", value)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user