Add more constraints on table Repetitions

This commit is contained in:
2017-06-21 13:18:19 -04:00
parent 3584affbe0
commit 6801d1d1ae
17 changed files with 376 additions and 73 deletions

View File

@@ -22,5 +22,5 @@ package org.isoron.uhabits.core;
public class Config
{
public static final String DATABASE_FILENAME = "uhabits.db";
public static int DATABASE_VERSION = 21;
public static int DATABASE_VERSION = 22;
}

View File

@@ -23,7 +23,15 @@ import java.util.*;
public interface Database
{
Cursor select(String query, String... params);
Cursor query(String query, String... params);
default void query(String query, ProcessCallback callback)
{
try (Cursor c = query(query)) {
c.moveToNext();
callback.process(c);
}
}
int update(String tableName,
Map<String, Object> values,
@@ -45,4 +53,9 @@ public interface Database
void close();
int getVersion();
interface ProcessCallback
{
void process(Cursor cursor);
}
}

View File

@@ -36,7 +36,7 @@ public class JdbcDatabase implements Database
}
@Override
public Cursor select(String query, String... params)
public Cursor query(String query, String... params)
{
try
{
@@ -197,7 +197,7 @@ public class JdbcDatabase implements Database
@Override
public int getVersion()
{
try (Cursor c = select("PRAGMA user_version"))
try (Cursor c = query("PRAGMA user_version"))
{
c.moveToNext();
return c.getInt(0);

View File

@@ -37,11 +37,11 @@ public class MigrationHelper
this.db = db;
}
public void executeMigrations(int oldVersion, int newVersion)
public void migrateTo(int newVersion)
{
try
{
for (int v = oldVersion + 1; v <= newVersion; v++)
for (int v = db.getVersion() + 1; v <= newVersion; v++)
{
String fname = String.format(Locale.US, "/migrations/%02d.sql", v);
for (String command : SQLParser.parse(open(fname)))

View File

@@ -63,7 +63,7 @@ public class Repository<T>
@NonNull
public List<T> findAll(@NonNull String query, @NonNull String... params)
{
try (Cursor c = db.select(buildSelectQuery() + query, params))
try (Cursor c = db.query(buildSelectQuery() + query, params))
{
return cursorToMultipleRecords(c);
}
@@ -76,7 +76,7 @@ public class Repository<T>
@Nullable
public T findFirst(String query, String... params)
{
try (Cursor c = db.select(buildSelectQuery() + query, params))
try (Cursor c = db.query(buildSelectQuery() + query, params))
{
if (!c.moveToNext()) return null;
return cursorToSingleRecord(c);

View File

@@ -29,7 +29,7 @@ import java.io.*;
import javax.inject.*;
import static org.isoron.uhabits.core.Config.DATABASE_VERSION;
import static org.isoron.uhabits.core.Config.*;
/**
* Class that imports data from database files exported by Loop Habit Tracker.
@@ -55,8 +55,8 @@ public class LoopDBImporter extends AbstractImporter
Database db = opener.open(file);
boolean canHandle = true;
Cursor c = db.select("select count(*) from SQLITE_MASTER " +
"where name='Checkmarks' or name='Repetitions'");
Cursor c = db.query("select count(*) from SQLITE_MASTER " +
"where name='Checkmarks' or name='Repetitions'");
if (!c.moveToNext() || c.getInt(0) != 2)
{

View File

@@ -56,8 +56,8 @@ public class RewireDBImporter extends AbstractImporter
if (!isSQLite3File(file)) return false;
Database db = opener.open(file);
Cursor c = db.select("select count(*) from SQLITE_MASTER " +
"where name='CHECKINS' or name='UNIT'");
Cursor c = db.query("select count(*) from SQLITE_MASTER " +
"where name='CHECKINS' or name='UNIT'");
boolean result = (c.moveToNext() && c.getInt(0) == 2);
@@ -83,9 +83,9 @@ public class RewireDBImporter extends AbstractImporter
try
{
c = db.select("select _id, name, description, schedule, " +
"active_days, repeating_count, days, period " +
"from habits");
c = db.query("select _id, name, description, schedule, " +
"active_days, repeating_count, days, period " +
"from habits");
if (!c.moveToNext()) return;
do
@@ -150,7 +150,7 @@ public class RewireDBImporter extends AbstractImporter
try
{
String[] params = { Integer.toString(rewireHabitId) };
c = db.select(
c = db.query(
"select distinct date from checkins where habit_id=? and type=2",
params);
if (!c.moveToNext()) return;
@@ -181,7 +181,7 @@ public class RewireDBImporter extends AbstractImporter
try
{
c = db.select(
c = db.query(
"select time, active_days from reminders where habit_id=? limit 1",
params);

View File

@@ -56,8 +56,8 @@ public class TickmateDBImporter extends AbstractImporter
if (!isSQLite3File(file)) return false;
Database db = opener.open(file);
Cursor c = db.select("select count(*) from SQLITE_MASTER " +
"where name='tracks' or name='track2groups'");
Cursor c = db.query("select count(*) from SQLITE_MASTER " +
"where name='tracks' or name='track2groups'");
boolean result = (c.moveToNext() && c.getInt(0) == 2);
@@ -86,7 +86,7 @@ public class TickmateDBImporter extends AbstractImporter
try
{
String[] params = {Integer.toString(tickmateTrackId)};
c = db.select(
c = db.query(
"select distinct year, month, day from ticks where _track_id=?",
params);
if (!c.moveToNext()) return;
@@ -115,7 +115,7 @@ public class TickmateDBImporter extends AbstractImporter
try
{
c = db.select("select _id, name, description from tracks",
c = db.query("select _id, name, description from tracks",
new String[0]);
if (!c.moveToNext()) return;

View File

@@ -21,6 +21,8 @@ package org.isoron.uhabits.core.models;
import android.support.annotation.*;
import org.apache.commons.lang3.builder.*;
public final class Reminder
{
private final int hour;
@@ -51,4 +53,40 @@ public final class Reminder
{
return minute;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Reminder reminder = (Reminder) o;
return new EqualsBuilder()
.append(hour, reminder.hour)
.append(minute, reminder.minute)
.append(days, reminder.days)
.isEquals();
}
@Override
public int hashCode()
{
return new HashCodeBuilder(17, 37)
.append(hour)
.append(minute)
.append(days)
.toHashCode();
}
@Override
public String toString()
{
return new ToStringBuilder(this)
.append("hour", hour)
.append("minute", minute)
.append("days", days)
.toString();
}
}

View File

@@ -19,6 +19,8 @@
package org.isoron.uhabits.core.models;
import org.apache.commons.lang3.builder.*;
import java.util.*;
public class WeekdayList
@@ -68,4 +70,30 @@ public class WeekdayList
return packedList;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WeekdayList that = (WeekdayList) o;
return new EqualsBuilder().append(weekdays, that.weekdays).isEquals();
}
@Override
public int hashCode()
{
return new HashCodeBuilder(17, 37).append(weekdays).toHashCode();
}
@Override
public String toString()
{
return new ToStringBuilder(this)
.append("weekdays", weekdays)
.toString();
}
}

View File

@@ -0,0 +1,24 @@
delete from repetitions where habit not in (select id from habits);
delete from repetitions where timestamp is null;
delete from repetitions where habit is null;
delete from repetitions where rowid not in (
select min(rowid) from repetitions group by habit, timestamp
);
begin transaction;
alter table Repetitions rename to RepetitionsBak;
create table Repetitions (
id integer primary key autoincrement,
habit integer not null references habits(id),
timestamp integer not null,
value integer not null);
drop index idx_repetitions_habit_timestamp;
create unique index idx_repetitions_habit_timestamp on Repetitions(
habit, timestamp);
insert into Repetitions select * from RepetitionsBak;
drop table RepetitionsBak;
commit;
pragma foreign_keys=ON;