diff --git a/uhabits-android/build.gradle b/uhabits-android/build.gradle index 70cd1dca7..a23f7e8f9 100644 --- a/uhabits-android/build.gradle +++ b/uhabits-android/build.gradle @@ -11,7 +11,7 @@ android { minSdkVersion 19 targetSdkVersion 25 - buildConfigField "Integer", "databaseVersion", "19" + buildConfigField "Integer", "databaseVersion", "20" buildConfigField "String", "databaseFilename", "\"uhabits.db\"" buildConfigField "int", "roboSdk", (System.getenv("ROBO_SDK") ?: "25") @@ -146,3 +146,4 @@ task coverageReport(type: JacocoReport) { classDirectories = files(fileTree(dir: androidClasses, excludes: excludes)) executionData = files(jvmExecData, connectedExecData) } + diff --git a/uhabits-android/src/main/assets/migrations/20.sql b/uhabits-android/src/main/assets/migrations/20.sql new file mode 100644 index 000000000..7a8a44177 --- /dev/null +++ b/uhabits-android/src/main/assets/migrations/20.sql @@ -0,0 +1,3 @@ +drop table checkmarks; +drop table streak; +drop table score; diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java index 839a71aec..4025e824c 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java @@ -21,6 +21,7 @@ package org.isoron.uhabits.models.sqlite; import org.isoron.uhabits.core.*; import org.isoron.uhabits.core.models.*; +import org.isoron.uhabits.core.models.memory.*; import dagger.*; @@ -46,7 +47,7 @@ public class SQLModelFactory implements ModelFactory @Override public CheckmarkList buildCheckmarkList(Habit habit) { - return new SQLiteCheckmarkList(habit); + return new MemoryCheckmarkList(habit); } @Override @@ -64,12 +65,12 @@ public class SQLModelFactory implements ModelFactory @Override public ScoreList buildScoreList(Habit habit) { - return new SQLiteScoreList(habit); + return new MemoryScoreList(habit); } @Override public StreakList buildStreakList(Habit habit) { - return new SQLiteStreakList(habit); + return new MemoryStreakList(habit); } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteCheckmarkList.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteCheckmarkList.java deleted file mode 100644 index dc6f2e2d2..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteCheckmarkList.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite; - -import android.database.sqlite.*; -import android.support.annotation.*; -import android.support.annotation.Nullable; - -import com.activeandroid.*; - -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.utils.*; -import org.isoron.uhabits.models.sqlite.records.*; -import org.jetbrains.annotations.*; - -import java.util.*; - -/** - * Implementation of a {@link CheckmarkList} that is backed by SQLite. - */ -public class SQLiteCheckmarkList extends CheckmarkList -{ - - @Nullable - private HabitRecord habitRecord; - - @NonNull - private final SQLiteUtils sqlite; - - @Nullable - private Integer todayValue; - - @NonNull - private final SQLiteStatement invalidateStatement; - - @NonNull - private final SQLiteStatement addStatement; - - @NonNull - private final SQLiteDatabase db; - - private static final String ADD_QUERY = - "insert into Checkmarks(habit, timestamp, value) values (?,?,?)"; - - private static final String INVALIDATE_QUERY = - "delete from Checkmarks where habit = ? and timestamp >= ?"; - - public SQLiteCheckmarkList(Habit habit) - { - super(habit); - sqlite = new SQLiteUtils<>(CheckmarkRecord.class); - - db = Cache.openDatabase(); - addStatement = db.compileStatement(ADD_QUERY); - invalidateStatement = db.compileStatement(INVALIDATE_QUERY); - } - - @Override - public void add(List checkmarks) - { - check(habit.getId()); - db.beginTransaction(); - try - { - for (Checkmark c : checkmarks) - { - addStatement.bindLong(1, habit.getId()); - addStatement.bindLong(2, c.getTimestamp()); - addStatement.bindLong(3, c.getValue()); - addStatement.execute(); - } - - db.setTransactionSuccessful(); - } - finally - { - db.endTransaction(); - } - } - - @NonNull - @Override - public List getByInterval(long fromTimestamp, long toTimestamp) - { - check(habit.getId()); - compute(fromTimestamp, toTimestamp); - - String query = "select habit, timestamp, value " + - "from checkmarks " + - "where habit = ? and timestamp >= ? and timestamp <= ? " + - "order by timestamp desc"; - - String params[] = { - Long.toString(habit.getId()), - Long.toString(fromTimestamp), - Long.toString(toTimestamp) - }; - - List 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())); - } - - return toCheckmarks(records); - } - - @Override - public void invalidateNewerThan(long timestamp) - { - todayValue = null; - invalidateStatement.bindLong(1, habit.getId()); - invalidateStatement.bindLong(2, timestamp); - invalidateStatement.execute(); - observable.notifyListeners(); - } - - @Override - @Nullable - protected Checkmark getNewestComputed() - { - check(habit.getId()); - String query = "select habit, timestamp, value " + - "from checkmarks " + - "where habit = ? " + - "order by timestamp desc " + - "limit 1"; - - String params[] = { Long.toString(habit.getId()) }; - return getSingleCheckmarkFromQuery(query, params); - } - - @Override - @Nullable - protected Checkmark getOldestComputed() - { - check(habit.getId()); - String query = "select habit, timestamp, value " + - "from checkmarks " + - "where habit = ? " + - "order by timestamp asc " + - "limit 1"; - - String params[] = { Long.toString(habit.getId()) }; - return getSingleCheckmarkFromQuery(query, params); - } - - @Contract("null -> fail") - private void check(Long id) - { - if (id == null) throw new RuntimeException("habit is not saved"); - if (habitRecord != null) return; - - habitRecord = HabitRecord.get(id); - if (habitRecord == null) throw new RuntimeException("habit not found"); - } - - @Nullable - private Checkmark getSingleCheckmarkFromQuery(String query, String params[]) - { - CheckmarkRecord record = sqlite.querySingle(query, params); - if (record == null) return null; - record.habit = habitRecord; - return record.toCheckmark(); - } - - @NonNull - private List toCheckmarks(@NonNull List records) - { - List checkmarks = new LinkedList<>(); - for (CheckmarkRecord r : records) checkmarks.add(r.toCheckmark()); - return checkmarks; - } - - @Override - public int getTodayValue() - { - if(todayValue == null) todayValue = super.getTodayValue(); - return todayValue; - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteScoreList.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteScoreList.java deleted file mode 100644 index 02e082cae..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteScoreList.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite; - -import android.database.sqlite.*; -import android.support.annotation.*; -import android.support.annotation.Nullable; - -import com.activeandroid.*; - -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.models.sqlite.records.*; -import org.jetbrains.annotations.*; - -import java.util.*; - -/** - * Implementation of a ScoreList that is backed by SQLite. - */ -public class SQLiteScoreList extends ScoreList -{ - - @Nullable - private HabitRecord habitRecord; - - @NonNull - private final SQLiteUtils sqlite; - - @Nullable - private Double todayValue; - - @NonNull - private final SQLiteStatement invalidateStatement; - - @NonNull - private final SQLiteStatement addStatement; - - public static final String ADD_QUERY = - "insert into Score(habit, timestamp, score) values (?,?,?)"; - - public static final String INVALIDATE_QUERY = - "delete from Score where habit = ? " + "and timestamp >= ?"; - - private final SQLiteDatabase db; - - /** - * Constructs a new ScoreList associated with the given habit. - * - * @param habit the habit this list should be associated with - */ - public SQLiteScoreList(@NonNull Habit habit) - { - super(habit); - sqlite = new SQLiteUtils<>(ScoreRecord.class); - - db = Cache.openDatabase(); - addStatement = db.compileStatement(ADD_QUERY); - invalidateStatement = db.compileStatement(INVALIDATE_QUERY); - } - - @Override - public void add(List scores) - { - check(habit.getId()); - db.beginTransaction(); - try - { - for (Score s : scores) - { - addStatement.bindLong(1, habit.getId()); - addStatement.bindLong(2, s.getTimestamp()); - addStatement.bindDouble(3, s.getValue()); - addStatement.execute(); - } - - db.setTransactionSuccessful(); - } - finally - { - db.endTransaction(); - } - } - - @NonNull - @Override - public List getByInterval(long fromTimestamp, long toTimestamp) - { - check(habit.getId()); - compute(fromTimestamp, toTimestamp); - - String query = "select habit, timestamp, score " + - "from Score " + - "where habit = ? and timestamp >= ? and timestamp <= ? " + - "order by timestamp desc"; - - String params[] = { - Long.toString(habit.getId()), - Long.toString(fromTimestamp), - Long.toString(toTimestamp) - }; - - List records = sqlite.query(query, params); - for (ScoreRecord record : records) record.habit = habitRecord; - return toScores(records); - } - - @Override - @Nullable - public Score getComputedByTimestamp(long timestamp) - { - check(habit.getId()); - - String query = "select habit, timestamp, score from Score " + - "where habit = ? and timestamp = ? " + - "order by timestamp desc"; - - String params[] = - { Long.toString(habit.getId()), Long.toString(timestamp) }; - - return getScoreFromQuery(query, params); - } - - @Override - public void invalidateNewerThan(long timestamp) - { - todayValue = null; - invalidateStatement.bindLong(1, habit.getId()); - invalidateStatement.bindLong(2, timestamp); - invalidateStatement.execute(); - getObservable().notifyListeners(); - } - - @Override - @NonNull - public List toList() - { - check(habit.getId()); - computeAll(); - - String query = "select habit, timestamp, score from Score " + - "where habit = ? order by timestamp desc"; - - String params[] = { Long.toString(habit.getId()) }; - - List records = sqlite.query(query, params); - for (ScoreRecord record : records) record.habit = habitRecord; - - return toScores(records); - } - - @Nullable - @Override - protected Score getNewestComputed() - { - check(habit.getId()); - String query = "select habit, timestamp, score from Score " + - "where habit = ? order by timestamp desc " + - "limit 1"; - - String params[] = { Long.toString(habit.getId()) }; - return getScoreFromQuery(query, params); - } - - @Nullable - @Override - protected Score getOldestComputed() - { - check(habit.getId()); - String query = "select habit, timestamp, score from Score " + - "where habit = ? order by timestamp asc " + - "limit 1"; - - String params[] = { Long.toString(habit.getId()) }; - return getScoreFromQuery(query, params); - } - - @Contract("null -> fail") - private void check(Long id) - { - if (id == null) throw new RuntimeException("habit is not saved"); - if (habitRecord != null) return; - habitRecord = HabitRecord.get(id); - if (habitRecord == null) throw new RuntimeException("habit not found"); - } - - @Nullable - private Score getScoreFromQuery(String query, String[] params) - { - ScoreRecord record = sqlite.querySingle(query, params); - if (record == null) return null; - record.habit = habitRecord; - return record.toScore(); - } - - @NonNull - private List toScores(@NonNull List records) - { - List scores = new LinkedList<>(); - for (ScoreRecord r : records) scores.add(r.toScore()); - return scores; - } - - @Override - public double getTodayValue() - { - if (todayValue == null) todayValue = super.getTodayValue(); - return todayValue; - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteStreakList.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteStreakList.java deleted file mode 100644 index 168b7313a..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteStreakList.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite; - -import android.database.sqlite.*; -import android.support.annotation.*; -import android.support.annotation.Nullable; - -import com.activeandroid.*; - -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.utils.*; -import org.isoron.uhabits.models.sqlite.records.*; -import org.isoron.uhabits.utils.*; -import org.jetbrains.annotations.*; - -import java.util.*; - -/** - * Implementation of a StreakList that is backed by SQLite. - */ -public class SQLiteStreakList extends StreakList -{ - private HabitRecord habitRecord; - - @NonNull - private final SQLiteUtils sqlite; - - private final SQLiteStatement invalidateStatement; - - public SQLiteStreakList(Habit habit) - { - super(habit); - sqlite = new SQLiteUtils<>(StreakRecord.class); - - SQLiteDatabase db = Cache.openDatabase(); - String invalidateQuery = "delete from Streak where habit = ? " + - "and end >= ?"; - invalidateStatement = db.compileStatement(invalidateQuery); - } - - @Override - public List getAll() - { - check(habit.getId()); - rebuild(); - - String query = StreakRecord.SELECT + "where habit = ? " + - "order by end desc"; - - String params[] = { Long.toString(habit.getId())}; - - List records = sqlite.query(query, params); - return recordsToStreaks(records); - } - - @Override - public Streak getNewestComputed() - { - StreakRecord newestRecord = getNewestRecord(); - if (newestRecord == null) return null; - return newestRecord.toStreak(); - } - - @Override - public void invalidateNewerThan(long timestamp) - { - invalidateStatement.bindLong(1, habit.getId()); - invalidateStatement.bindLong(2, timestamp - DateUtils.millisecondsInOneDay); - invalidateStatement.execute(); - observable.notifyListeners(); - } - - @Override - protected void add(@NonNull List streaks) - { - check(habit.getId()); - - DatabaseUtils.executeAsTransaction(() -> { - for (Streak streak : streaks) - { - StreakRecord record = new StreakRecord(); - record.copyFrom(streak); - record.habit = habitRecord; - record.save(); - } - }); - } - - @Override - protected void removeNewestComputed() - { - StreakRecord newestStreak = getNewestRecord(); - if (newestStreak != null) newestStreak.delete(); - } - - @Nullable - private StreakRecord getNewestRecord() - { - check(habit.getId()); - String query = StreakRecord.SELECT + "where habit = ? " + - "order by end desc " + - "limit 1 "; - String params[] = { habit.getId().toString() }; - StreakRecord record = sqlite.querySingle(query, params); - if (record != null) record.habit = habitRecord; - return record; - - } - - @NonNull - private List recordsToStreaks(List records) - { - LinkedList streaks = new LinkedList<>(); - - for (StreakRecord record : records) - { - record.habit = habitRecord; - streaks.add(record.toStreak()); - } - - return streaks; - } - - @Contract("null -> fail") - private void check(Long id) - { - if (id == null) throw new RuntimeException("habit is not saved"); - - if(habitRecord != null) return; - - habitRecord = HabitRecord.get(id); - if (habitRecord == null) throw new RuntimeException("habit not found"); - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/CheckmarkRecord.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/CheckmarkRecord.java deleted file mode 100644 index 74c8e8a6d..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/CheckmarkRecord.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite.records; - -import android.database.*; - -import com.activeandroid.*; -import com.activeandroid.annotation.*; - -import org.isoron.uhabits.core.models.*; - -/** - * The SQLite database record corresponding to a {@link Checkmark}. - */ -@Table(name = "Checkmarks") -public class CheckmarkRecord extends Model implements SQLiteRecord -{ - /** - * The habit to which this checkmark belongs. - */ - @Column(name = "habit") - public HabitRecord habit; - - /** - * Timestamp of the day to which this checkmark corresponds. Time of the day - * must be midnight (UTC). - */ - @Column(name = "timestamp") - public Long timestamp; - - /** - * Indicates whether there is a repetition at the given timestamp or not, - * and whether the repetition was expected. Assumes one of the values - * UNCHECKED, CHECKED_EXPLICITLY or CHECKED_IMPLICITLY. - */ - @Column(name = "value") - public Integer value; - - @Override - public void copyFrom(Cursor c) - { - timestamp = c.getLong(1); - value = c.getInt(2); - } - - public Checkmark toCheckmark() - { - return new Checkmark(timestamp, value); - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java index 5cd02bb65..5731da245 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java @@ -125,26 +125,10 @@ public class HabitRecord extends Model implements SQLiteRecord Long id = getId(); DatabaseUtils.executeAsTransaction(() -> { - new Delete() - .from(CheckmarkRecord.class) - .where("habit = ?", id) - .execute(); - new Delete() .from(RepetitionRecord.class) .where("habit = ?", id) .execute(); - - new Delete() - .from(ScoreRecord.class) - .where("habit = ?", id) - .execute(); - - new Delete() - .from(StreakRecord.class) - .where("habit = ?", id) - .execute(); - delete(); }); } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/ScoreRecord.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/ScoreRecord.java deleted file mode 100644 index 0907d3115..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/ScoreRecord.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite.records; - -import android.database.*; - -import com.activeandroid.*; -import com.activeandroid.annotation.*; - -import org.isoron.uhabits.core.models.*; - -/** - * The SQLite database record corresponding to a Score. - */ -@Table(name = "Score") -public class ScoreRecord extends Model implements SQLiteRecord -{ - @Column(name = "habit") - public HabitRecord habit; - - /** - * Timestamp of the day to which this score applies. Time of day should be - * midnight (UTC). - */ - @Column(name = "timestamp") - public Long timestamp; - - /** - * Value of the score. - */ - @Column(name = "score") - public Double score; - - @Override - public void copyFrom(Cursor c) - { - timestamp = c.getLong(1); - score = c.getDouble(2); - } - - /** - * Constructs and returns a {@link Score} based on this record's data. - * - * @return a {@link Score} with this record's data - */ - public Score toScore() - { - return new Score(timestamp, score); - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/StreakRecord.java b/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/StreakRecord.java deleted file mode 100644 index a16878ea3..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/StreakRecord.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2016 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models.sqlite.records; - -import android.database.*; - -import com.activeandroid.*; -import com.activeandroid.annotation.*; - -import org.isoron.uhabits.core.models.*; - -import java.lang.reflect.*; - -/** - * The SQLite database record corresponding to a Streak. - */ -@Table(name = "Streak") -public class StreakRecord extends Model implements SQLiteRecord -{ - public static final String SELECT = "select id, start, end, length from Streak "; - - @Column(name = "habit") - public HabitRecord habit; - - @Column(name = "start") - public Long start; - - @Column(name = "end") - public Long end; - - @Column(name = "length") - public Long length; - - public static StreakRecord get(Long id) - { - return StreakRecord.load(StreakRecord.class, id); - } - - public void copyFrom(Streak streak) - { - start = streak.getStart(); - end = streak.getEnd(); - length = streak.getLength(); - } - - @Override - public void copyFrom(Cursor c) - { - setId(c.getLong(0)); - start = c.getLong(1); - end = c.getLong(2); - length = c.getLong(3); - } - - private void setId(long id) - { - try - { - Field f = (Model.class).getDeclaredField("mId"); - f.setAccessible(true); - f.set(this, id); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - public Streak toStreak() - { - return new Streak(start, end); - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java index 1e03f4f95..50a14edea 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java @@ -76,10 +76,8 @@ public abstract class DatabaseUtils Configuration dbConfig = new Configuration.Builder(context) .setDatabaseName(getDatabaseFilename()) .setDatabaseVersion(BuildConfig.databaseVersion) - .addModelClasses(CheckmarkRecord.class, HabitRecord.class, - RepetitionRecord.class, ScoreRecord.class, StreakRecord.class, - Event.class) - .create(); + .addModelClasses(HabitRecord.class, RepetitionRecord.class, + Event.class).create(); try { diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java index 3c335ca1f..51b1ba024 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java @@ -27,12 +27,12 @@ import java.util.*; public class MemoryScoreList extends ScoreList { - LinkedList list; + ArrayList list; public MemoryScoreList(Habit habit) { super(habit); - list = new LinkedList<>(); + list = new ArrayList<>(); } @Override @@ -53,7 +53,7 @@ public class MemoryScoreList extends ScoreList for (Score s : list) if (s.getTimestamp() >= fromTimestamp && - s.getTimestamp() <= toTimestamp) filtered.add(s); + s.getTimestamp() <= toTimestamp) filtered.add(s); return filtered; } @@ -94,7 +94,7 @@ public class MemoryScoreList extends ScoreList protected Score getNewestComputed() { if (list.isEmpty()) return null; - return list.getFirst(); + return list.get(0); } @Nullable @@ -102,6 +102,6 @@ public class MemoryScoreList extends ScoreList protected Score getOldestComputed() { if (list.isEmpty()) return null; - return list.getLast(); + return list.get(list.size() - 1); } } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java index 1cadf75c2..9707c9bbe 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java @@ -26,12 +26,12 @@ import java.util.*; public class MemoryStreakList extends StreakList { - LinkedList list; + ArrayList list; public MemoryStreakList(Habit habit) { super(habit); - list = new LinkedList<>(); + list = new ArrayList<>(); } @Override diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/BaseUnitTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/BaseUnitTest.java index 5473ba296..6279258db 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/BaseUnitTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/BaseUnitTest.java @@ -36,6 +36,7 @@ import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class BaseUnitTest { + protected HabitList habitList; protected HabitFixtures fixtures; @@ -46,12 +47,13 @@ public class BaseUnitTest protected CommandRunner commandRunner; + // 8:00am, January 25th, 2015 (UTC) + protected static final long FIXED_LOCAL_TIME = 1422172800000L; + @Before public void setUp() { - // 8:00am, January 25th, 2015 (UTC) - long fixed_local_time = 1422172800000L; - DateUtils.setFixedLocalTime(fixed_local_time); + DateUtils.setFixedLocalTime(FIXED_LOCAL_TIME); modelFactory = new MemoryModelFactory(); habitList = spy(modelFactory.buildHabitList());