mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Move models.sqlite to uhabits-core
This commit is contained in:
@@ -9,6 +9,7 @@ dependencies {
|
||||
apt 'com.google.auto.factory:auto-factory:1.0-beta3'
|
||||
apt 'com.google.dagger:dagger:2.11-rc2'
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
compileOnly 'org.jetbrains:annotations-java5:15.0'
|
||||
compileOnly 'com.google.auto.factory:auto-factory:1.0-beta3'
|
||||
compileOnly 'com.google.dagger:dagger:2.11-rc2'
|
||||
implementation 'com.android.support:support-annotations:25.3.1'
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.db;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Column
|
||||
{
|
||||
String name() default "";
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.db;
|
||||
|
||||
public interface Cursor extends AutoCloseable
|
||||
{
|
||||
@Override
|
||||
void close();
|
||||
|
||||
boolean moveToNext();
|
||||
|
||||
Integer getInt(int index);
|
||||
|
||||
Long getLong(int index);
|
||||
|
||||
Double getDouble(int index);
|
||||
|
||||
String getString(int index);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.db;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface Database
|
||||
{
|
||||
Cursor select(String query, String... params);
|
||||
|
||||
int update(String tableName,
|
||||
Map<String, Object> values,
|
||||
String where,
|
||||
String... params);
|
||||
|
||||
Long insert(String tableName, Map<String, Object> values);
|
||||
|
||||
void delete(String tableName, String where, String... params);
|
||||
|
||||
void execSQL(String query, Object... params);
|
||||
|
||||
void beginTransaction();
|
||||
|
||||
void setTransactionSuccessful();
|
||||
|
||||
void endTransaction();
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.db;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.apache.commons.lang3.*;
|
||||
import org.apache.commons.lang3.tuple.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Repository<T>
|
||||
{
|
||||
@NonNull
|
||||
private final Class klass;
|
||||
|
||||
@NonNull
|
||||
private final Database db;
|
||||
|
||||
public Repository(@NonNull Class<T> klass, @NonNull Database db)
|
||||
{
|
||||
this.klass = klass;
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the record that has the id provided.
|
||||
* If no record is found, returns null.
|
||||
*/
|
||||
@Nullable
|
||||
public T find(@NonNull Long id)
|
||||
{
|
||||
return findFirst(String.format("where %s=?", getIdName()),
|
||||
id.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all records matching the given SQL query.
|
||||
*
|
||||
* The query should only contain the "where" part of the SQL query, and
|
||||
* optinally the "order by" part. "Group by" is not allowed. If no matching
|
||||
* records are found, returns an empty list.
|
||||
*/
|
||||
@NonNull
|
||||
public List<T> findAll(@NonNull String query, @NonNull String... params)
|
||||
{
|
||||
try (Cursor c = db.select(buildSelectQuery() + query, params))
|
||||
{
|
||||
return cursorToMultipleRecords(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first record matching the given SQL query.
|
||||
* See findAll for more details about the parameters.
|
||||
*/
|
||||
@Nullable
|
||||
public T findFirst(String query, String... params)
|
||||
{
|
||||
try (Cursor c = db.select(buildSelectQuery() + query, params))
|
||||
{
|
||||
if (!c.moveToNext()) return null;
|
||||
return cursorToSingleRecord(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given SQL query on the repository.
|
||||
*
|
||||
* The query can be of any kind. For example, complex deletes and updates
|
||||
* are allowed. The repository does not perform any checks to guarantee
|
||||
* that the query is valid, however the underlying database might.
|
||||
*/
|
||||
public void execSQL(String query, Object... params)
|
||||
{
|
||||
db.execSQL(query, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given callback inside a database transaction.
|
||||
*
|
||||
* If the callback terminates without throwing any exceptions, the
|
||||
* transaction is considered successful. If any exceptions are thrown,
|
||||
* the transaction is aborted. Nesting transactions is not allowed.
|
||||
*/
|
||||
public void executeAsTransaction(Runnable callback)
|
||||
{
|
||||
db.beginTransaction();
|
||||
try
|
||||
{
|
||||
callback.run();
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the record on the database.
|
||||
*
|
||||
* If the id of the given record is null, it is assumed that the record has
|
||||
* not been inserted in the repository yet. The record will be inserted, a
|
||||
* new id will be automatically generated, and the id of the given record
|
||||
* will be updated.
|
||||
*
|
||||
* If the given record has a non-null id, then an update will be performed
|
||||
* instead. That is, the previous record will be overwritten by the one
|
||||
* provided.
|
||||
*/
|
||||
public void save(T record)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field fields[] = getFields();
|
||||
String columns[] = getColumnNames();
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
values.put(columns[i], fields[i].get(record));
|
||||
|
||||
Long id = (Long) getIdField().get(record);
|
||||
int affectedRows = 0;
|
||||
|
||||
if (id != null) affectedRows =
|
||||
db.update(getTableName(), values, getIdName() + "=?",
|
||||
new String[]{ id.toString() });
|
||||
|
||||
if (id == null || affectedRows == 0)
|
||||
{
|
||||
id = db.insert(getTableName(), values);
|
||||
getIdField().set(record, id);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given record from the repository.
|
||||
* The id of the given record is also set to null.
|
||||
*/
|
||||
public void remove(T record)
|
||||
{
|
||||
try
|
||||
{
|
||||
Long id = (Long) getIdField().get(record);
|
||||
if (id == null) return;
|
||||
|
||||
db.delete(getTableName(), getIdName() + "=?",
|
||||
new String[]{ id.toString() });
|
||||
getIdField().set(record, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@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 cursor)
|
||||
{
|
||||
try
|
||||
{
|
||||
Constructor constructor = klass.getDeclaredConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
T record = (T) constructor.newInstance();
|
||||
|
||||
int index = 0;
|
||||
for (Field field : getFields())
|
||||
copyFieldFromCursor(record, field, cursor, index++);
|
||||
return record;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyFieldFromCursor(T record, Field field, Cursor c, int index)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
if (field.getType().isAssignableFrom(Integer.class))
|
||||
field.set(record, c.getInt(index));
|
||||
else if (field.getType().isAssignableFrom(Long.class))
|
||||
field.set(record, c.getLong(index));
|
||||
else if (field.getType().isAssignableFrom(Double.class))
|
||||
field.set(record, c.getDouble(index));
|
||||
else if (field.getType().isAssignableFrom(String.class))
|
||||
field.set(record, c.getString(index));
|
||||
else throw new RuntimeException(
|
||||
"Type not supported: " + field.getType().getName() + " " +
|
||||
field.getName());
|
||||
}
|
||||
|
||||
private String buildSelectQuery()
|
||||
{
|
||||
return String.format("select %s from %s ",
|
||||
StringUtils.join(getColumnNames(), ", "), getTableName());
|
||||
}
|
||||
|
||||
private List<Pair<Field, Column>> getFieldColumnPairs()
|
||||
{
|
||||
List<Pair<Field, Column>> fields = new ArrayList<>();
|
||||
for (Field field : klass.getDeclaredFields())
|
||||
for (Annotation annotation : field.getAnnotations())
|
||||
{
|
||||
if (!(annotation instanceof Column)) continue;
|
||||
Column column = (Column) annotation;
|
||||
fields.add(new ImmutablePair<>(field, column));
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Field[] getFields()
|
||||
{
|
||||
List<Field> fields = new ArrayList<>();
|
||||
List<Pair<Field, Column>> columns = getFieldColumnPairs();
|
||||
for (Pair<Field, Column> pair : columns) fields.add(pair.getLeft());
|
||||
return fields.toArray(new Field[]{});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String[] getColumnNames()
|
||||
{
|
||||
List<String> names = new ArrayList<>();
|
||||
List<Pair<Field, Column>> columns = getFieldColumnPairs();
|
||||
for (Pair<Field, Column> pair : columns)
|
||||
{
|
||||
String cname = pair.getRight().name();
|
||||
if (cname.isEmpty()) cname = pair.getLeft().getName();
|
||||
if (names.contains(cname))
|
||||
throw new RuntimeException("duplicated column : " + cname);
|
||||
names.add(cname);
|
||||
}
|
||||
|
||||
return names.toArray(new String[]{});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getTableName()
|
||||
{
|
||||
String name = getTableAnnotation().name();
|
||||
if (name.isEmpty()) throw new RuntimeException("Table name is empty");
|
||||
return name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getIdName()
|
||||
{
|
||||
String id = getTableAnnotation().id();
|
||||
if (id.isEmpty()) throw new RuntimeException("Table id is empty");
|
||||
return id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Field getIdField()
|
||||
{
|
||||
Field fields[] = getFields();
|
||||
String idName = getIdName();
|
||||
for (Field f : fields)
|
||||
if (f.getName().equals(idName)) return f;
|
||||
throw new RuntimeException("Field not found: " + idName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Table getTableAnnotation()
|
||||
{
|
||||
Table t = null;
|
||||
for (Annotation annotation : klass.getAnnotations())
|
||||
{
|
||||
if (!(annotation instanceof Table)) continue;
|
||||
t = (Table) annotation;
|
||||
break;
|
||||
}
|
||||
|
||||
if (t == null) throw new RuntimeException("Table annotation not found");
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.db;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Table
|
||||
{
|
||||
String name();
|
||||
String id() default "id";
|
||||
}
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package org.isoron.uhabits.core.models;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
|
||||
/**
|
||||
* Interface implemented by factories that provide concrete implementations of
|
||||
* the core model classes.
|
||||
@@ -44,4 +47,8 @@ public interface ModelFactory
|
||||
ScoreList buildScoreList(Habit habit);
|
||||
|
||||
StreakList buildStreakList(Habit habit);
|
||||
|
||||
Repository<HabitRecord> buildHabitListRepository();
|
||||
|
||||
Repository<RepetitionRecord> buildRepetitionListRepository();
|
||||
}
|
||||
|
||||
@@ -19,28 +19,12 @@
|
||||
|
||||
package org.isoron.uhabits.core.models.memory;
|
||||
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@Module
|
||||
public class MemoryModelFactory implements ModelFactory
|
||||
{
|
||||
@Provides
|
||||
@AppScope
|
||||
public static HabitList provideHabitList()
|
||||
{
|
||||
return new MemoryHabitList();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@AppScope
|
||||
public static ModelFactory provideModelFactory()
|
||||
{
|
||||
return new MemoryModelFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckmarkList buildCheckmarkList(Habit habit)
|
||||
{
|
||||
@@ -70,4 +54,16 @@ public class MemoryModelFactory implements ModelFactory
|
||||
{
|
||||
return new MemoryStreakList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository<HabitRecord> buildHabitListRepository()
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository<RepetitionRecord> buildRepetitionListRepository()
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* Factory that provides models backed by an SQLite database.
|
||||
*/
|
||||
public class SQLModelFactory implements ModelFactory
|
||||
{
|
||||
private final Database db;
|
||||
|
||||
@Inject
|
||||
public SQLModelFactory(Database db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckmarkList buildCheckmarkList(Habit habit)
|
||||
{
|
||||
return new MemoryCheckmarkList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HabitList buildHabitList()
|
||||
{
|
||||
return new SQLiteHabitList(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepetitionList buildRepetitionList(Habit habit)
|
||||
{
|
||||
return new SQLiteRepetitionList(habit, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreList buildScoreList(Habit habit)
|
||||
{
|
||||
return new MemoryScoreList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreakList buildStreakList(Habit habit)
|
||||
{
|
||||
return new MemoryStreakList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository<HabitRecord> buildHabitListRepository()
|
||||
{
|
||||
return new Repository<>(HabitRecord.class, db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository<RepetitionRecord> buildRepetitionListRepository()
|
||||
{
|
||||
return new Repository<>(RepetitionRecord.class, db);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* Implementation of a {@link HabitList} that is backed by SQLite.
|
||||
*/
|
||||
public class SQLiteHabitList extends HabitList
|
||||
{
|
||||
private static SQLiteHabitList instance;
|
||||
|
||||
@NonNull
|
||||
private final Repository<HabitRecord> repository;
|
||||
|
||||
@NonNull
|
||||
private final ModelFactory modelFactory;
|
||||
|
||||
@NonNull
|
||||
private final MemoryHabitList list;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
@Inject
|
||||
public SQLiteHabitList(@NonNull ModelFactory modelFactory)
|
||||
{
|
||||
super();
|
||||
this.modelFactory = modelFactory;
|
||||
this.list = new MemoryHabitList();
|
||||
this.repository = modelFactory.buildHabitListRepository();
|
||||
}
|
||||
|
||||
private void loadRecords()
|
||||
{
|
||||
if (loaded) return;
|
||||
loaded = true;
|
||||
|
||||
list.removeAll();
|
||||
List<HabitRecord> records = repository.findAll("order by position");
|
||||
for (HabitRecord rec : records)
|
||||
{
|
||||
Habit h = modelFactory.buildHabit();
|
||||
rec.copyTo(h);
|
||||
list.add(h);
|
||||
}
|
||||
}
|
||||
|
||||
public static SQLiteHabitList getInstance(
|
||||
@NonNull ModelFactory modelFactory)
|
||||
{
|
||||
if (instance == null) instance = new SQLiteHabitList(modelFactory);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(@NonNull Habit habit)
|
||||
{
|
||||
loadRecords();
|
||||
list.add(habit);
|
||||
|
||||
HabitRecord record = new HabitRecord();
|
||||
record.copyFrom(habit);
|
||||
record.position = list.indexOf(habit);
|
||||
repository.save(record);
|
||||
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Habit getById(long id)
|
||||
{
|
||||
loadRecords();
|
||||
return list.getById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Habit getByPosition(int position)
|
||||
{
|
||||
loadRecords();
|
||||
return list.getByPosition(position);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public HabitList getFiltered(HabitMatcher filter)
|
||||
{
|
||||
loadRecords();
|
||||
return list.getFiltered(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Order getOrder()
|
||||
{
|
||||
return list.getOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(@NonNull Order order)
|
||||
{
|
||||
list.setOrder(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(@NonNull Habit h)
|
||||
{
|
||||
loadRecords();
|
||||
return list.indexOf(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Habit> iterator()
|
||||
{
|
||||
loadRecords();
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
private void rebuildOrder()
|
||||
{
|
||||
// List<Habit> habits = toList();
|
||||
//
|
||||
// int i = 0;
|
||||
// for (Habit h : habits)
|
||||
// {
|
||||
// HabitRecord record = repository.find(h.getId());
|
||||
// if (record == null)
|
||||
// throw new RuntimeException("habit not in database");
|
||||
//
|
||||
// record.position = i++;
|
||||
// repository.save(record);
|
||||
// }
|
||||
//
|
||||
// update(habits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void remove(@NonNull Habit habit)
|
||||
{
|
||||
loadRecords();
|
||||
list.remove(habit);
|
||||
|
||||
HabitRecord record = repository.find(habit.getId());
|
||||
if (record == null) throw new RuntimeException("habit not in database");
|
||||
repository.executeAsTransaction(() ->
|
||||
{
|
||||
((SQLiteRepetitionList) habit.getRepetitions()).removeAll();
|
||||
repository.remove(record);
|
||||
});
|
||||
rebuildOrder();
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeAll()
|
||||
{
|
||||
list.removeAll();
|
||||
repository.execSQL("delete from habits");
|
||||
repository.execSQL("delete from repetitions");
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reorder(@NonNull Habit from, @NonNull Habit to)
|
||||
{
|
||||
loadRecords();
|
||||
list.reorder(from, to);
|
||||
|
||||
HabitRecord fromRecord = repository.find(from.getId());
|
||||
HabitRecord toRecord = repository.find(to.getId());
|
||||
|
||||
if (fromRecord == null)
|
||||
throw new RuntimeException("habit not in database");
|
||||
if (toRecord == null)
|
||||
throw new RuntimeException("habit not in database");
|
||||
|
||||
Integer fromPos = fromRecord.position;
|
||||
Integer toPos = toRecord.position;
|
||||
if (toPos < fromPos)
|
||||
{
|
||||
repository.execSQL("update habits set position = position + 1 " +
|
||||
"where position >= ? and position < ?",
|
||||
toPos, fromPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
repository.execSQL("update habits set position = position - 1 " +
|
||||
"where position > ? and position <= ?",
|
||||
fromPos, toPos);
|
||||
}
|
||||
|
||||
fromRecord.position = toPos;
|
||||
repository.save(fromRecord);
|
||||
update(from);
|
||||
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repair()
|
||||
{
|
||||
loadRecords();
|
||||
rebuildOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
loadRecords();
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update(List<Habit> habits)
|
||||
{
|
||||
loadRecords();
|
||||
for (Habit h : habits)
|
||||
{
|
||||
HabitRecord record = repository.find(h.getId());
|
||||
if (record == null)
|
||||
throw new RuntimeException("habit not in database");
|
||||
record.copyFrom(h);
|
||||
repository.save(record);
|
||||
}
|
||||
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
loaded = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite;
|
||||
|
||||
import android.support.annotation.*;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Implementation of a {@link RepetitionList} that is backed by SQLite.
|
||||
*/
|
||||
public class SQLiteRepetitionList extends RepetitionList
|
||||
{
|
||||
private final Repository<RepetitionRecord> repository;
|
||||
|
||||
private final MemoryRepetitionList list;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
public SQLiteRepetitionList(@NonNull Habit habit,
|
||||
@NonNull ModelFactory modelFactory)
|
||||
{
|
||||
super(habit);
|
||||
repository = modelFactory.buildRepetitionListRepository();
|
||||
list = new MemoryRepetitionList(habit);
|
||||
}
|
||||
|
||||
private void loadRecords()
|
||||
{
|
||||
if (loaded) return;
|
||||
loaded = true;
|
||||
|
||||
check(habit.getId());
|
||||
List<RepetitionRecord> records =
|
||||
repository.findAll("where habit = ? order by timestamp",
|
||||
habit.getId().toString());
|
||||
|
||||
for (RepetitionRecord rec : records)
|
||||
list.add(rec.toRepetition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Repetition rep)
|
||||
{
|
||||
loadRecords();
|
||||
list.add(rep);
|
||||
check(habit.getId());
|
||||
RepetitionRecord record = new RepetitionRecord();
|
||||
record.habit_id = habit.getId();
|
||||
record.copyFrom(rep);
|
||||
repository.save(record);
|
||||
observable.notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Repetition> getByInterval(long timeFrom, long timeTo)
|
||||
{
|
||||
loadRecords();
|
||||
return list.getByInterval(timeFrom, timeTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Repetition getByTimestamp(long timestamp)
|
||||
{
|
||||
loadRecords();
|
||||
return list.getByTimestamp(timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repetition getOldest()
|
||||
{
|
||||
loadRecords();
|
||||
return list.getOldest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repetition getNewest()
|
||||
{
|
||||
loadRecords();
|
||||
return list.getNewest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NonNull Repetition repetition)
|
||||
{
|
||||
loadRecords();
|
||||
list.remove(repetition);
|
||||
check(habit.getId());
|
||||
repository.execSQL(
|
||||
"delete from repetitions where habit = ? and timestamp = ?",
|
||||
habit.getId());
|
||||
observable.notifyListeners();
|
||||
}
|
||||
|
||||
public void removeAll()
|
||||
{
|
||||
loadRecords();
|
||||
list.removeAll();
|
||||
check(habit.getId());
|
||||
repository.execSQL("delete from repetitions where habit = ?",
|
||||
habit.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalCount()
|
||||
{
|
||||
loadRecords();
|
||||
return list.getTotalCount();
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
@Contract("null -> fail")
|
||||
private void check(Long value)
|
||||
{
|
||||
if (value == null) throw new RuntimeException("null check failed");
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,11 @@
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
public class MyClass
|
||||
{}
|
||||
/**
|
||||
* Provides SQLite implementations of the core models.
|
||||
*/
|
||||
package org.isoron.uhabits.core.models.sqlite;
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite.records;
|
||||
|
||||
import org.apache.commons.lang3.builder.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
|
||||
/**
|
||||
* The SQLite database record corresponding to a {@link Habit}.
|
||||
*/
|
||||
@Table(name = "habits")
|
||||
public class HabitRecord
|
||||
{
|
||||
@Column
|
||||
public String description;
|
||||
|
||||
@Column
|
||||
public String name;
|
||||
|
||||
@Column(name = "freq_num")
|
||||
public Integer freqNum;
|
||||
|
||||
@Column(name = "freq_den")
|
||||
public Integer freqDen;
|
||||
|
||||
@Column
|
||||
public Integer color;
|
||||
|
||||
@Column
|
||||
public Integer position;
|
||||
|
||||
@Column(name = "reminder_hour")
|
||||
public Integer reminderHour;
|
||||
|
||||
@Column(name = "reminder_min")
|
||||
public Integer reminderMin;
|
||||
|
||||
@Column(name = "reminder_days")
|
||||
public Integer reminderDays;
|
||||
|
||||
@Column
|
||||
public Integer highlight;
|
||||
|
||||
@Column
|
||||
public Integer archived;
|
||||
|
||||
@Column
|
||||
public Integer type;
|
||||
|
||||
@Column(name = "target_value")
|
||||
public Double targetValue;
|
||||
|
||||
@Column(name = "target_type")
|
||||
public Integer targetType;
|
||||
|
||||
@Column
|
||||
public String unit;
|
||||
|
||||
@Column
|
||||
public Long id;
|
||||
|
||||
public void copyFrom(Habit model)
|
||||
{
|
||||
this.id = model.getId();
|
||||
this.name = model.getName();
|
||||
this.description = model.getDescription();
|
||||
this.highlight = 0;
|
||||
this.color = model.getColor();
|
||||
this.archived = model.isArchived() ? 1 : 0;
|
||||
this.type = model.getType();
|
||||
this.targetType = model.getTargetType();
|
||||
this.targetValue = model.getTargetValue();
|
||||
this.unit = model.getUnit();
|
||||
|
||||
Frequency freq = model.getFrequency();
|
||||
this.freqNum = freq.getNumerator();
|
||||
this.freqDen = freq.getDenominator();
|
||||
this.reminderDays = 0;
|
||||
this.reminderMin = null;
|
||||
this.reminderHour = null;
|
||||
|
||||
if (model.hasReminder())
|
||||
{
|
||||
Reminder reminder = model.getReminder();
|
||||
this.reminderHour = reminder.getHour();
|
||||
this.reminderMin = reminder.getMinute();
|
||||
this.reminderDays = reminder.getDays().toInteger();
|
||||
}
|
||||
}
|
||||
|
||||
public void copyTo(Habit habit)
|
||||
{
|
||||
habit.setId(this.id);
|
||||
habit.setName(this.name);
|
||||
habit.setDescription(this.description);
|
||||
habit.setFrequency(new Frequency(this.freqNum, this.freqDen));
|
||||
habit.setColor(this.color);
|
||||
habit.setArchived(this.archived != 0);
|
||||
habit.setType(this.type);
|
||||
habit.setTargetType(this.targetType);
|
||||
habit.setTargetValue(this.targetValue);
|
||||
habit.setUnit(this.unit);
|
||||
|
||||
if (reminderHour != null && reminderMin != null)
|
||||
{
|
||||
habit.setReminder(new Reminder(reminderHour, reminderMin,
|
||||
new WeekdayList(reminderDays)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
HabitRecord that = (HabitRecord) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.appendSuper(super.equals(o))
|
||||
.append(freqNum, that.freqNum)
|
||||
.append(freqDen, that.freqDen)
|
||||
.append(color, that.color)
|
||||
.append(position, that.position)
|
||||
.append(reminderDays, that.reminderDays)
|
||||
.append(highlight, that.highlight)
|
||||
.append(archived, that.archived)
|
||||
.append(type, that.type)
|
||||
.append(targetValue, that.targetValue)
|
||||
.append(targetType, that.targetType)
|
||||
.append(name, that.name)
|
||||
.append(description, that.description)
|
||||
.append(reminderHour, that.reminderHour)
|
||||
.append(reminderMin, that.reminderMin)
|
||||
.append(unit, that.unit)
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.appendSuper(super.hashCode())
|
||||
.append(name)
|
||||
.append(description)
|
||||
.append(freqNum)
|
||||
.append(freqDen)
|
||||
.append(color)
|
||||
.append(position)
|
||||
.append(reminderHour)
|
||||
.append(reminderMin)
|
||||
.append(reminderDays)
|
||||
.append(highlight)
|
||||
.append(archived)
|
||||
.append(type)
|
||||
.append(targetValue)
|
||||
.append(targetType)
|
||||
.append(unit)
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return new ToStringBuilder(this)
|
||||
.append("name", name)
|
||||
.append("description", description)
|
||||
.append("freqNum", freqNum)
|
||||
.append("freqDen", freqDen)
|
||||
.append("color", color)
|
||||
.append("position", position)
|
||||
.append("reminderHour", reminderHour)
|
||||
.append("reminderMin", reminderMin)
|
||||
.append("reminderDays", reminderDays)
|
||||
.append("highlight", highlight)
|
||||
.append("archived", archived)
|
||||
.append("type", type)
|
||||
.append("targetValue", targetValue)
|
||||
.append("targetType", targetType)
|
||||
.append("unit", unit)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite.records;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
|
||||
/**
|
||||
* The SQLite database record corresponding to a {@link Repetition}.
|
||||
*/
|
||||
@Table(name = "Repetitions")
|
||||
public class RepetitionRecord
|
||||
{
|
||||
public HabitRecord habit;
|
||||
|
||||
@Column(name = "habit")
|
||||
public Long habit_id;
|
||||
|
||||
@Column
|
||||
public Long timestamp;
|
||||
|
||||
@Column
|
||||
public Integer value;
|
||||
|
||||
@Column
|
||||
public Long id;
|
||||
|
||||
public void copyFrom(Repetition repetition)
|
||||
{
|
||||
timestamp = repetition.getTimestamp();
|
||||
value = repetition.getValue();
|
||||
}
|
||||
|
||||
public Repetition toRepetition()
|
||||
{
|
||||
return new Repetition(timestamp, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes that represent rows in the SQLite database.
|
||||
*/
|
||||
package org.isoron.uhabits.core.models.sqlite.records;
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite.records;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
import org.junit.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
|
||||
public class HabitRecordTest extends BaseUnitTest
|
||||
{
|
||||
private Habit habit;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp()
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
habit = modelFactory.buildHabit();
|
||||
habit.setName("Hello world");
|
||||
habit.setDescription("Did you greet the world today?");
|
||||
habit.setColor(1);
|
||||
habit.setArchived(true);
|
||||
habit.setFrequency(Frequency.THREE_TIMES_PER_WEEK);
|
||||
habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
|
||||
habit.setId(1000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFrom()
|
||||
{
|
||||
HabitRecord rec = new HabitRecord();
|
||||
rec.copyFrom(habit);
|
||||
|
||||
assertThat(rec.name, equalTo(habit.getName()));
|
||||
assertThat(rec.description, equalTo(habit.getDescription()));
|
||||
assertThat(rec.color, equalTo(habit.getColor()));
|
||||
assertThat(rec.archived, equalTo(1));
|
||||
assertThat(rec.freqDen, equalTo(7));
|
||||
assertThat(rec.freqNum, equalTo(3));
|
||||
|
||||
Reminder reminder = habit.getReminder();
|
||||
assertThat(rec.reminderDays, equalTo(reminder.getDays().toInteger()));
|
||||
assertThat(rec.reminderHour, equalTo(reminder.getHour()));
|
||||
assertThat(rec.reminderMin, equalTo(reminder.getMinute()));
|
||||
|
||||
habit.setReminder(null);
|
||||
rec.copyFrom(habit);
|
||||
|
||||
assertThat(rec.reminderMin, equalTo(null));
|
||||
assertThat(rec.reminderHour, equalTo(null));
|
||||
assertThat(rec.reminderDays, equalTo(0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Á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.core.models.sqlite.records;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
import org.junit.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
|
||||
public class RepetitionRecordTest extends BaseUnitTest
|
||||
{
|
||||
@Test
|
||||
public void testRecord() throws Exception
|
||||
{
|
||||
Repetition rep = new Repetition(2000L, 50);
|
||||
RepetitionRecord record = new RepetitionRecord();
|
||||
record.copyFrom(rep);
|
||||
assertThat(rep, equalTo(record.toRepetition()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user