Replace ActiveAndroid queries with raw SQLite queries

pull/145/head
Alinson S. Xavier 9 years ago
parent add08d6054
commit efc7b2cebb

@ -58,6 +58,7 @@ dependencies {
compile 'org.apmem.tools:layouts:1.10@aar' compile 'org.apmem.tools:layouts:1.10@aar'
compile 'com.opencsv:opencsv:3.7' compile 'com.opencsv:opencsv:3.7'
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT' compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
compile 'org.jetbrains:annotations-java5:15.0'
compile 'com.jakewharton:butterknife:8.0.1' compile 'com.jakewharton:butterknife:8.0.1'
apt 'com.jakewharton:butterknife-compiler:8.0.1' apt 'com.jakewharton:butterknife-compiler:8.0.1'

@ -19,18 +19,18 @@
package org.isoron.uhabits; package org.isoron.uhabits;
import android.app.Application; import android.app.*;
import android.content.Context; import android.content.*;
import android.support.annotation.Nullable; import android.support.annotation.*;
import com.activeandroid.ActiveAndroid; import com.activeandroid.*;
import org.isoron.uhabits.models.HabitList; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.DatabaseUtils; import org.isoron.uhabits.utils.*;
import java.io.File; import java.io.*;
import javax.inject.Inject; import javax.inject.*;
/** /**
* The Android application for Loop Habit Tracker. * The Android application for Loop Habit Tracker.
@ -92,7 +92,7 @@ public class HabitsApplication extends Application
{ {
if (context != null) context if (context != null) context
.getClassLoader() .getClassLoader()
.loadClass("org.isoron.uhabits.unit.models.HabitTest"); .loadClass("org.isoron.uhabits.BaseAndroidTest");
return true; return true;
} }
catch (final Exception e) catch (final Exception e)

@ -21,13 +21,14 @@ package org.isoron.uhabits.models.sqlite;
import android.database.sqlite.*; import android.database.sqlite.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.annotation.Nullable;
import com.activeandroid.*; import com.activeandroid.*;
import com.activeandroid.query.*; import com.activeandroid.query.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.sqlite.records.*; import org.isoron.uhabits.models.sqlite.records.*;
import org.isoron.uhabits.utils.*; import org.jetbrains.annotations.*;
import java.util.*; import java.util.*;
@ -36,14 +37,23 @@ import java.util.*;
*/ */
public class SQLiteCheckmarkList extends CheckmarkList public class SQLiteCheckmarkList extends CheckmarkList
{ {
@Nullable
private HabitRecord habitRecord;
@NonNull
private final SQLiteUtils<CheckmarkRecord> sqlite;
public SQLiteCheckmarkList(Habit habit) public SQLiteCheckmarkList(Habit habit)
{ {
super(habit); super(habit);
sqlite = new SQLiteUtils<>(CheckmarkRecord.class);
} }
@Override @Override
public void add(List<Checkmark> checkmarks) public void add(List<Checkmark> checkmarks)
{ {
check(habit.getId());
String query = String query =
"insert into Checkmarks(habit, timestamp, value) values (?,?,?)"; "insert into Checkmarks(habit, timestamp, value) values (?,?,?)";
@ -69,16 +79,26 @@ public class SQLiteCheckmarkList extends CheckmarkList
} }
} }
@NonNull
@Override @Override
public List<Checkmark> getByInterval(long fromTimestamp, long toTimestamp) public List<Checkmark> getByInterval(long fromTimestamp, long toTimestamp)
{ {
check(habit.getId());
computeAll(); computeAll();
List<CheckmarkRecord> records = select() String query = "select habit, timestamp, value " +
.and("timestamp >= ?", fromTimestamp) "from checkmarks " +
.and("timestamp <= ?", toTimestamp) "where habit = ? and timestamp >= ? and timestamp <= ? " +
.execute(); "order by timestamp desc";
String params[] = {
Long.toString(habit.getId()),
Long.toString(fromTimestamp),
Long.toString(toTimestamp)
};
List<CheckmarkRecord> records = sqlite.query(query, params);
for (CheckmarkRecord record : records) record.habit = habitRecord;
return toCheckmarks(records); return toCheckmarks(records);
} }
@ -98,19 +118,31 @@ public class SQLiteCheckmarkList extends CheckmarkList
@Nullable @Nullable
protected Checkmark getNewestComputed() protected Checkmark getNewestComputed()
{ {
CheckmarkRecord record = select().limit(1).executeSingle(); 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()) };
CheckmarkRecord record = sqlite.querySingle(query, params);
if (record == null) return null; if (record == null) return null;
record.habit = habitRecord;
return record.toCheckmark(); return record.toCheckmark();
} }
@NonNull @Contract("null -> fail")
private From select() private void check(Long id)
{ {
return new Select() if (id == null) throw new RuntimeException("habit is not saved");
.from(CheckmarkRecord.class)
.where("habit = ?", habit.getId()) if (habitRecord != null) return;
.and("timestamp <= ?", DateUtils.getStartOfToday())
.orderBy("timestamp desc"); habitRecord = HabitRecord.get(id);
if (habitRecord == null) throw new RuntimeException("habit not found");
} }
@NonNull @NonNull

@ -19,8 +19,10 @@
package org.isoron.uhabits.models.sqlite; package org.isoron.uhabits.models.sqlite;
import android.database.sqlite.*;
import android.support.annotation.*; import android.support.annotation.*;
import com.activeandroid.*;
import com.activeandroid.query.*; import com.activeandroid.query.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
@ -37,9 +39,13 @@ public class SQLiteHabitList extends HabitList
private HashMap<Long, Habit> cache; private HashMap<Long, Habit> cache;
private final SQLiteUtils<HabitRecord> sqlite;
private SQLiteHabitList() private SQLiteHabitList()
{ {
cache = new HashMap<>(); cache = new HashMap<>();
sqlite = new SQLiteUtils<>(HabitRecord.class);
} }
/** /**
@ -77,13 +83,18 @@ public class SQLiteHabitList extends HabitList
@Override @Override
public int countActive() public int countActive()
{ {
return select().count(); SQLiteDatabase db = Cache.openDatabase();
SQLiteStatement st = db.compileStatement(
"select count(*) from habits where archived = 0");
return (int) st.simpleQueryForLong();
} }
@Override @Override
public int countWithArchived() public int countWithArchived()
{ {
return selectWithArchived().count(); SQLiteDatabase db = Cache.openDatabase();
SQLiteStatement st = db.compileStatement("select count(*) from habits");
return (int) st.simpleQueryForLong();
} }
@Override @Override
@ -91,8 +102,17 @@ public class SQLiteHabitList extends HabitList
public List<Habit> getAll(boolean includeArchive) public List<Habit> getAll(boolean includeArchive)
{ {
List<HabitRecord> recordList; List<HabitRecord> recordList;
if (includeArchive) recordList = selectWithArchived().execute(); if (includeArchive)
else recordList = select().execute(); {
String query = HabitRecord.SELECT + "order by position";
recordList = sqlite.query(query, null);
}
else
{
String query = HabitRecord.SELECT + "where archived = 0 " +
"order by position";
recordList = sqlite.query(query, null);
}
List<Habit> habits = new LinkedList<>(); List<Habit> habits = new LinkedList<>();
for (HabitRecord record : recordList) for (HabitRecord record : recordList)
@ -127,11 +147,10 @@ public class SQLiteHabitList extends HabitList
@Nullable @Nullable
public Habit getByPosition(int position) public Habit getByPosition(int position)
{ {
HabitRecord record = selectWithArchived() String query = HabitRecord.SELECT + "where position = ? limit 1";
.where("position = ?", position) String params[] = { Integer.toString(position) };
.executeSingle(); HabitRecord record = sqlite.querySingle(query, params);
if (record != null) return getById(record.getId());
if(record != null) return getById(record.getId());
return null; return null;
} }
@ -222,18 +241,4 @@ public class SQLiteHabitList extends HabitList
} }
} }
@NonNull
private From select()
{
return new Select()
.from(HabitRecord.class)
.where("archived = 0")
.orderBy("position");
}
@NonNull
private From selectWithArchived()
{
return new Select().from(HabitRecord.class).orderBy("position");
}
} }

@ -20,12 +20,13 @@
package org.isoron.uhabits.models.sqlite; package org.isoron.uhabits.models.sqlite;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.annotation.Nullable;
import com.activeandroid.query.*; import com.activeandroid.query.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.sqlite.records.*; import org.isoron.uhabits.models.sqlite.records.*;
import org.isoron.uhabits.utils.*; import org.jetbrains.annotations.*;
import java.util.*; import java.util.*;
@ -34,9 +35,15 @@ import java.util.*;
*/ */
public class SQLiteRepetitionList extends RepetitionList public class SQLiteRepetitionList extends RepetitionList
{ {
private final SQLiteUtils<RepetitionRecord> sqlite;
@Nullable
private HabitRecord habitRecord;
public SQLiteRepetitionList(@NonNull Habit habit) public SQLiteRepetitionList(@NonNull Habit habit)
{ {
super(habit); super(habit);
sqlite = new SQLiteUtils<>(RepetitionRecord.class);
} }
/** /**
@ -59,25 +66,56 @@ public class SQLiteRepetitionList extends RepetitionList
@Override @Override
public List<Repetition> getByInterval(long timeFrom, long timeTo) public List<Repetition> getByInterval(long timeFrom, long timeTo)
{ {
return toRepetitions(selectFromTo(timeFrom, timeTo).execute()); check(habit.getId());
String query = "select habit, timestamp " +
"from Repetitions " +
"where habit = ? and timestamp >= ? and timestamp <= ? " +
"order by timestamp";
String params[] = {
Long.toString(habit.getId()),
Long.toString(timeFrom),
Long.toString(timeTo)
};
List<RepetitionRecord> records = sqlite.query(query, params);
return toRepetitions(records);
} }
@Override @Override
@Nullable @Nullable
public Repetition getByTimestamp(long timestamp) public Repetition getByTimestamp(long timestamp)
{ {
RepetitionRecord record = check(habit.getId());
select().where("timestamp = ?", timestamp).executeSingle(); String query = "select habit, timestamp " +
"from Repetitions " +
"where habit = ? and timestamp = ? " +
"limit 1";
String params[] =
{ Long.toString(habit.getId()), Long.toString(timestamp) };
RepetitionRecord record = sqlite.querySingle(query, params);
if (record == null) return null; if (record == null) return null;
record.habit = habitRecord;
return record.toRepetition(); return record.toRepetition();
} }
@Override @Override
public Repetition getOldest() public Repetition getOldest()
{ {
RepetitionRecord record = select().limit(1).executeSingle(); check(habit.getId());
String query = "select habit, timestamp " +
"from Repetitions " +
"where habit = ? " +
"order by timestamp asc " +
"limit 1";
String params[] = { Long.toString(habit.getId()) };
RepetitionRecord record = sqlite.querySingle(query, params);
if (record == null) return null; if (record == null) return null;
record.habit = habitRecord;
return record.toRepetition(); return record.toRepetition();
} }
@ -93,33 +131,29 @@ public class SQLiteRepetitionList extends RepetitionList
observable.notifyListeners(); observable.notifyListeners();
} }
@NonNull @Contract("null -> fail")
private From select() private void check(Long id)
{ {
return new Select() if (id == null) throw new RuntimeException("habit is not saved");
.from(RepetitionRecord.class)
.where("habit = ?", habit.getId())
.and("timestamp <= ?", DateUtils.getStartOfToday())
.orderBy("timestamp");
}
@NonNull if (habitRecord != null) return;
private From selectFromTo(long timeFrom, long timeTo)
{ habitRecord = HabitRecord.get(id);
return select() if (habitRecord == null) throw new RuntimeException("habit not found");
.and("timestamp >= ?", timeFrom)
.and("timestamp <= ?", timeTo);
} }
@NonNull @NonNull
private List<Repetition> toRepetitions( private List<Repetition> toRepetitions(
@Nullable List<RepetitionRecord> records) @NonNull List<RepetitionRecord> records)
{ {
List<Repetition> reps = new LinkedList<>(); check(habit.getId());
if (records == null) return reps;
List<Repetition> reps = new LinkedList<>();
for (RepetitionRecord record : records) for (RepetitionRecord record : records)
{
record.habit = habitRecord;
reps.add(record.toRepetition()); reps.add(record.toRepetition());
}
return reps; return reps;
} }

@ -21,12 +21,14 @@ package org.isoron.uhabits.models.sqlite;
import android.database.sqlite.*; import android.database.sqlite.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.annotation.Nullable;
import com.activeandroid.*; import com.activeandroid.*;
import com.activeandroid.query.*; import com.activeandroid.query.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.sqlite.records.*; import org.isoron.uhabits.models.sqlite.records.*;
import org.jetbrains.annotations.*;
import java.util.*; import java.util.*;
@ -35,6 +37,12 @@ import java.util.*;
*/ */
public class SQLiteScoreList extends ScoreList public class SQLiteScoreList extends ScoreList
{ {
@Nullable
private HabitRecord habitRecord;
@NonNull
private final SQLiteUtils<ScoreRecord> sqlite;
/** /**
* Constructs a new ScoreList associated with the given habit. * Constructs a new ScoreList associated with the given habit.
* *
@ -43,36 +51,13 @@ public class SQLiteScoreList extends ScoreList
public SQLiteScoreList(@NonNull Habit habit) public SQLiteScoreList(@NonNull Habit habit)
{ {
super(habit); super(habit);
} sqlite = new SQLiteUtils<>(ScoreRecord.class);
@Override
@NonNull
public List<Score> getAll()
{
computeAll();
List<ScoreRecord> records = select().execute();
List<Score> scores = new LinkedList<>();
for (ScoreRecord rec : records)
scores.add(rec.toScore());
return scores;
}
@Override
public void invalidateNewerThan(long timestamp)
{
new Delete()
.from(ScoreRecord.class)
.where("habit = ?", habit.getId())
.and("timestamp >= ?", timestamp)
.execute();
} }
@Override @Override
public void add(List<Score> scores) public void add(List<Score> scores)
{ {
check(habit.getId());
String query = String query =
"insert into Score(habit, timestamp, score) values (?,?,?)"; "insert into Score(habit, timestamp, score) values (?,?,?)";
@ -99,33 +84,83 @@ public class SQLiteScoreList extends ScoreList
} }
} }
@Override
@NonNull
public List<Score> getAll()
{
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<ScoreRecord> records = sqlite.query(query, params);
for (ScoreRecord record : records) record.habit = habitRecord;
List<Score> scores = new LinkedList<>();
for (ScoreRecord rec : records)
scores.add(rec.toScore());
return scores;
}
@Override @Override
@Nullable @Nullable
public Score getByTimestamp(long timestamp) public Score getByTimestamp(long timestamp)
{ {
check(habit.getId());
computeAll(); computeAll();
ScoreRecord record = String query = "select habit, timestamp, score from Score " +
select().where("timestamp = ?", timestamp).executeSingle(); "where habit = ? and timestamp = ? " +
"order by timestamp desc";
String params[] =
{Long.toString(habit.getId()), Long.toString(timestamp)};
ScoreRecord record = sqlite.querySingle(query, params);
if (record == null) return null; if (record == null) return null;
record.habit = habitRecord;
return record.toScore(); return record.toScore();
} }
@Override
public void invalidateNewerThan(long timestamp)
{
new Delete()
.from(ScoreRecord.class)
.where("habit = ?", habit.getId())
.and("timestamp >= ?", timestamp)
.execute();
}
@Nullable @Nullable
@Override @Override
protected Score getNewestComputed() protected Score getNewestComputed()
{ {
ScoreRecord record = select().limit(1).executeSingle(); 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())};
ScoreRecord record = sqlite.querySingle(query, params);
if (record == null) return null; if (record == null) return null;
record.habit = habitRecord;
return record.toScore(); return record.toScore();
} }
private From select() @Contract("null -> fail")
private void check(Long id)
{ {
return new Select() if (id == null) throw new RuntimeException("habit is not saved");
.from(ScoreRecord.class)
.where("habit = ?", habit.getId()) if(habitRecord != null) return;
.orderBy("timestamp desc");
habitRecord = HabitRecord.get(id);
if (habitRecord == null) throw new RuntimeException("habit not found");
} }
} }

@ -0,0 +1,84 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.models.sqlite;
import android.database.*;
import android.database.sqlite.*;
import android.support.annotation.*;
import com.activeandroid.*;
import org.isoron.uhabits.models.sqlite.records.*;
import java.util.*;
public class SQLiteUtils<T extends SQLiteRecord>
{
private Class klass;
public SQLiteUtils(Class klass)
{
this.klass = klass;
}
@NonNull
public List<T> query(String query, String params[])
{
SQLiteDatabase db = Cache.openDatabase();
try (Cursor c = db.rawQuery(query, params))
{
return cursorToMultipleRecords(c);
}
}
@Nullable
public T querySingle(String query, String params[])
{
SQLiteDatabase db = Cache.openDatabase();
try(Cursor c = db.rawQuery(query, params))
{
if (!c.moveToNext()) return null;
return cursorToSingleRecord(c);
}
}
@NonNull
private List<T> cursorToMultipleRecords(Cursor c)
{
List<T> records = new LinkedList<>();
while (c.moveToNext()) records.add(cursorToSingleRecord(c));
return records;
}
@NonNull
private T cursorToSingleRecord(Cursor c)
{
try
{
T record = (T) klass.newInstance();
record.copyFrom(c);
return record;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}

@ -19,6 +19,8 @@
package org.isoron.uhabits.models.sqlite.records; package org.isoron.uhabits.models.sqlite.records;
import android.database.*;
import com.activeandroid.*; import com.activeandroid.*;
import com.activeandroid.annotation.*; import com.activeandroid.annotation.*;
@ -29,7 +31,7 @@ import org.isoron.uhabits.models.sqlite.*;
* The SQLite database record corresponding to a {@link Checkmark}. * The SQLite database record corresponding to a {@link Checkmark}.
*/ */
@Table(name = "Checkmarks") @Table(name = "Checkmarks")
public class CheckmarkRecord extends Model public class CheckmarkRecord extends Model implements SQLiteRecord
{ {
/** /**
* The habit to which this checkmark belongs. * The habit to which this checkmark belongs.
@ -52,6 +54,13 @@ public class CheckmarkRecord extends Model
@Column(name = "value") @Column(name = "value")
public Integer value; public Integer value;
@Override
public void copyFrom(Cursor c)
{
timestamp = c.getLong(1);
value = c.getInt(2);
}
public Checkmark toCheckmark() public Checkmark toCheckmark()
{ {
SQLiteHabitList habitList = SQLiteHabitList.getInstance(); SQLiteHabitList habitList = SQLiteHabitList.getInstance();

@ -20,6 +20,7 @@
package org.isoron.uhabits.models.sqlite.records; package org.isoron.uhabits.models.sqlite.records;
import android.annotation.*; import android.annotation.*;
import android.database.*;
import android.support.annotation.*; import android.support.annotation.*;
import com.activeandroid.*; import com.activeandroid.*;
@ -28,17 +29,24 @@ import com.activeandroid.query.*;
import com.activeandroid.util.*; import com.activeandroid.util.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.DatabaseUtils;
import java.lang.reflect.*;
/** /**
* The SQLite database record corresponding to a {@link Habit}. * The SQLite database record corresponding to a {@link Habit}.
*/ */
@Table(name = "Habits") @Table(name = "Habits")
public class HabitRecord extends Model public class HabitRecord extends Model implements SQLiteRecord
{ {
public static final String HABIT_URI_FORMAT = public static final String HABIT_URI_FORMAT =
"content://org.isoron.uhabits/habit/%d"; "content://org.isoron.uhabits/habit/%d";
public static String SELECT =
"select id, color, description, freq_den, freq_num, " +
"name, position, reminder_hour, reminder_min, " +
"highlight, archived, reminder_days from habits ";
@Column(name = "name") @Column(name = "name")
public String name; public String name;
@ -147,6 +155,23 @@ public class HabitRecord extends Model
this.archived = model.getArchived(); this.archived = model.getArchived();
} }
@Override
public void copyFrom(Cursor c)
{
setId(c.getLong(0));
color = c.getInt(1);
description = c.getString(2);
freqDen = c.getInt(3);
freqNum = c.getInt(4);
name = c.getString(5);
position = c.getInt(6);
reminderHour = c.getInt(7);
reminderMin = c.getInt(8);
highlight = c.getInt(9);
archived = c.getInt(10);
reminderDays = c.getInt(11);
}
public void copyTo(Habit habit) public void copyTo(Habit habit)
{ {
habit.setName(this.name); habit.setName(this.name);
@ -172,4 +197,20 @@ public class HabitRecord extends Model
save(); save();
updateId(getId(), id); updateId(getId(), id);
} }
private void setId(Long id)
{
// HACK: The id field is declared private by ActiveAndroid and
// there are no setters. (WTF?)
try
{
Field f = (Model.class).getDeclaredField("mId");
f.setAccessible(true);
f.set(this, id);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
} }

@ -19,6 +19,8 @@
package org.isoron.uhabits.models.sqlite.records; package org.isoron.uhabits.models.sqlite.records;
import android.database.*;
import com.activeandroid.*; import com.activeandroid.*;
import com.activeandroid.annotation.*; import com.activeandroid.annotation.*;
@ -29,7 +31,7 @@ import org.isoron.uhabits.models.sqlite.*;
* The SQLite database record corresponding to a {@link Repetition}. * The SQLite database record corresponding to a {@link Repetition}.
*/ */
@Table(name = "Repetitions") @Table(name = "Repetitions")
public class RepetitionRecord extends Model public class RepetitionRecord extends Model implements SQLiteRecord
{ {
@Column(name = "habit") @Column(name = "habit")
public HabitRecord habit; public HabitRecord habit;
@ -37,15 +39,21 @@ public class RepetitionRecord extends Model
@Column(name = "timestamp") @Column(name = "timestamp")
public Long timestamp; public Long timestamp;
public static RepetitionRecord get(Long id)
{
return RepetitionRecord.load(RepetitionRecord.class, id);
}
public void copyFrom(Repetition repetition) public void copyFrom(Repetition repetition)
{ {
habit = HabitRecord.get(repetition.getHabit().getId()); habit = HabitRecord.get(repetition.getHabit().getId());
timestamp = repetition.getTimestamp(); timestamp = repetition.getTimestamp();
} }
public static RepetitionRecord get(Long id) @Override
public void copyFrom(Cursor c)
{ {
return RepetitionRecord.load(RepetitionRecord.class, id); timestamp = c.getLong(1);
} }
public Repetition toRepetition() public Repetition toRepetition()

@ -0,0 +1,27 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.models.sqlite.records;
import android.database.*;
public interface SQLiteRecord
{
void copyFrom(Cursor c);
}

@ -19,6 +19,8 @@
package org.isoron.uhabits.models.sqlite.records; package org.isoron.uhabits.models.sqlite.records;
import android.database.*;
import com.activeandroid.*; import com.activeandroid.*;
import com.activeandroid.annotation.*; import com.activeandroid.annotation.*;
@ -29,11 +31,8 @@ import org.isoron.uhabits.models.sqlite.*;
* The SQLite database record corresponding to a Score. * The SQLite database record corresponding to a Score.
*/ */
@Table(name = "Score") @Table(name = "Score")
public class ScoreRecord extends Model public class ScoreRecord extends Model implements SQLiteRecord
{ {
/**
* Habit to which this score belongs to.
*/
@Column(name = "habit") @Column(name = "habit")
public HabitRecord habit; public HabitRecord habit;
@ -50,6 +49,13 @@ public class ScoreRecord extends Model
@Column(name = "score") @Column(name = "score")
public Integer score; public Integer score;
@Override
public void copyFrom(Cursor c)
{
timestamp = c.getLong(1);
score = c.getInt(2);
}
/** /**
* Constructs and returns a {@link Score} based on this record's data. * Constructs and returns a {@link Score} based on this record's data.
* *

@ -19,26 +19,20 @@
package org.isoron.uhabits.ui.habits.list; package org.isoron.uhabits.ui.habits.list;
import android.support.annotation.NonNull; import android.os.*;
import android.support.annotation.*;
import org.isoron.uhabits.HabitsApplication;
import org.isoron.uhabits.R; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.CommandRunner; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.commands.ToggleRepetitionCommand; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.models.HabitList; import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.tasks.ExportCSVTask; import org.isoron.uhabits.ui.habits.list.controllers.*;
import org.isoron.uhabits.tasks.ExportDBTask; import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.tasks.ImportDataTask;
import org.isoron.uhabits.ui.BaseSystem; import java.io.*;
import org.isoron.uhabits.ui.habits.list.controllers.HabitCardListController;
import org.isoron.uhabits.utils.DateUtils; import javax.inject.*;
import org.isoron.uhabits.utils.Preferences;
import java.io.File;
import java.io.IOException;
import javax.inject.Inject;
public class ListHabitsController public class ListHabitsController
implements ImportDataTask.Listener, HabitCardListController.HabitListener implements ImportDataTask.Listener, HabitCardListController.HabitListener
@ -168,8 +162,10 @@ public class ListHabitsController
prefs.updateLastAppVersion(); prefs.updateLastAppVersion();
if (prefs.isFirstRun()) onFirstRun(); if (prefs.isFirstRun()) onFirstRun();
system.updateWidgets(); new Handler().postDelayed(() -> {
system.scheduleReminders(); system.updateWidgets();
system.scheduleReminders();
}, 1000);
} }
@Override @Override

Loading…
Cancel
Save