Repair inconsistent data instead of throwing exception

pull/316/head
Alinson S. Xavier 8 years ago
parent 001dd5a7c1
commit 404fc869b0

@ -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();
}
}

Loading…
Cancel
Save