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:
@@ -23,7 +23,6 @@ package org.isoron.uhabits;
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.tasks.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@@ -32,7 +31,6 @@ import dagger.*;
|
||||
AppContextModule.class,
|
||||
HabitsModule.class,
|
||||
SingleThreadModule.class,
|
||||
SQLModelFactory.class
|
||||
})
|
||||
public interface AndroidTestComponent extends HabitsApplicationComponent
|
||||
{
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class HabitRecordTest extends BaseAndroidTest
|
||||
{
|
||||
private Habit habit;
|
||||
|
||||
private SQLiteRepository<HabitRecord> sqlite =
|
||||
new SQLiteRepository<>(HabitRecord.class, DatabaseUtils.openDatabase());
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp()
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
habit = component.getModelFactory().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));
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,12 @@ import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.*;
|
||||
@@ -52,7 +54,7 @@ public class SQLiteHabitListTest extends BaseAndroidTest
|
||||
|
||||
private ModelFactory modelFactory;
|
||||
|
||||
private SQLiteRepository<HabitRecord> repository;
|
||||
private Repository<HabitRecord> repository;
|
||||
|
||||
private ModelObservable.Listener listener;
|
||||
|
||||
@@ -64,9 +66,8 @@ public class SQLiteHabitListTest extends BaseAndroidTest
|
||||
fixtures.purgeHabits(habitList);
|
||||
|
||||
modelFactory = component.getModelFactory();
|
||||
repository =
|
||||
new SQLiteRepository<>(HabitRecord.class,
|
||||
DatabaseUtils.openDatabase());
|
||||
repository = new Repository<>(HabitRecord.class,
|
||||
new AndroidSQLiteDatabase(DatabaseUtils.openDatabase()));
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
|
||||
@@ -23,11 +23,12 @@ import android.support.annotation.*;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
@@ -50,7 +51,7 @@ public class SQLiteRepetitionListTest extends BaseAndroidTest
|
||||
|
||||
private long day;
|
||||
|
||||
private SQLiteRepository<RepetitionRecord> sqlite;
|
||||
private Repository<RepetitionRecord> sqlite;
|
||||
|
||||
@Override
|
||||
public void setUp()
|
||||
@@ -61,8 +62,8 @@ public class SQLiteRepetitionListTest extends BaseAndroidTest
|
||||
repetitions = habit.getRepetitions();
|
||||
today = DateUtils.getStartOfToday();
|
||||
day = DateUtils.millisecondsInOneDay;
|
||||
sqlite = new SQLiteRepository<>(RepetitionRecord.class,
|
||||
DatabaseUtils.openDatabase());
|
||||
sqlite = new Repository<>(RepetitionRecord.class,
|
||||
new AndroidSQLiteDatabase(DatabaseUtils.openDatabase()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
|
||||
package org.isoron.uhabits.models.sqlite;
|
||||
|
||||
import android.database.sqlite.*;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.apache.commons.lang3.builder.*;
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
@@ -37,7 +38,7 @@ import static org.junit.Assert.assertThat;
|
||||
@MediumTest
|
||||
public class SQLiteRepositoryTest extends BaseAndroidTest
|
||||
{
|
||||
private SQLiteRepository<ThingRecord> repository;
|
||||
private Repository<ThingRecord> repository;
|
||||
|
||||
private SQLiteDatabase db;
|
||||
|
||||
@@ -47,7 +48,8 @@ public class SQLiteRepositoryTest extends BaseAndroidTest
|
||||
{
|
||||
super.setUp();
|
||||
this.db = DatabaseUtils.openDatabase();
|
||||
repository = new SQLiteRepository<>(ThingRecord.class, db);
|
||||
repository = new Repository<>(ThingRecord.class,
|
||||
new AndroidSQLiteDatabase((db)));
|
||||
|
||||
db.execSQL("drop table if exists tests");
|
||||
db.execSQL("create table tests(" +
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.core.reminders.*;
|
||||
import org.isoron.uhabits.core.tasks.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.isoron.uhabits.widgets.*;
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.isoron.uhabits.core.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.io.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
import org.isoron.uhabits.sync.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.widgets.*;
|
||||
@@ -42,7 +41,9 @@ import dagger.*;
|
||||
|
||||
@AppScope
|
||||
@Component(modules = {
|
||||
AppContextModule.class, HabitsModule.class, AndroidTaskRunner.class, SQLModelFactory.class
|
||||
AppContextModule.class,
|
||||
HabitsModule.class,
|
||||
AndroidTaskRunner.class,
|
||||
})
|
||||
public interface HabitsApplicationComponent
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ package org.isoron.uhabits;
|
||||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
|
||||
|
||||
public class HabitsDatabaseOpener extends BaseSQLiteOpenHelper
|
||||
|
||||
@@ -22,13 +22,16 @@ package org.isoron.uhabits;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.sqlite.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.core.reminders.*;
|
||||
import org.isoron.uhabits.core.tasks.*;
|
||||
import org.isoron.uhabits.core.ui.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@@ -69,5 +72,19 @@ public class HabitsModule
|
||||
{
|
||||
return new WidgetPreferences(storage);
|
||||
}
|
||||
|
||||
@Provides
|
||||
public ModelFactory getModelFactory()
|
||||
{
|
||||
return new SQLModelFactory(
|
||||
new AndroidSQLiteDatabase(DatabaseUtils.openDatabase()));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@AppScope
|
||||
public HabitList getHabitList(SQLiteHabitList list)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.database;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
|
||||
public class AndroidCursor implements Cursor
|
||||
{
|
||||
private android.database.Cursor cursor;
|
||||
|
||||
public AndroidCursor(android.database.Cursor cursor)
|
||||
{
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNext()
|
||||
{
|
||||
return cursor.moveToNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(int index)
|
||||
{
|
||||
return cursor.getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(int index)
|
||||
{
|
||||
return cursor.getLong(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDouble(int index)
|
||||
{
|
||||
return cursor.getDouble(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(int index)
|
||||
{
|
||||
return cursor.getString(index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.database;
|
||||
|
||||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AndroidSQLiteDatabase implements Database
|
||||
{
|
||||
private final SQLiteDatabase db;
|
||||
|
||||
public AndroidSQLiteDatabase(SQLiteDatabase db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor select(String query, String... params)
|
||||
{
|
||||
return new AndroidCursor(db.rawQuery(query, params));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execSQL(String query, Object... params)
|
||||
{
|
||||
db.execSQL(query, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginTransaction()
|
||||
{
|
||||
db.beginTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransactionSuccessful()
|
||||
{
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction()
|
||||
{
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(String tableName,
|
||||
Map<String, Object> map,
|
||||
String where,
|
||||
String... params)
|
||||
{
|
||||
ContentValues values = mapToContentValues(map);
|
||||
return db.update(tableName, values, where, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long insert(String tableName, Map<String, Object> map)
|
||||
{
|
||||
ContentValues values = mapToContentValues(map);
|
||||
return db.insert(tableName, null, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String tableName, String where, String... params)
|
||||
{
|
||||
db.delete(tableName, where, params);
|
||||
}
|
||||
|
||||
private ContentValues mapToContentValues(Map<String, Object> map)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
for (Map.Entry<String, Object> entry : map.entrySet())
|
||||
{
|
||||
if (entry.getValue() == null) continue;
|
||||
if (entry.getValue() instanceof Integer)
|
||||
values.put(entry.getKey(), (Integer) entry.getValue());
|
||||
else if (entry.getValue() instanceof Long)
|
||||
values.put(entry.getKey(), (Long) entry.getValue());
|
||||
else if (entry.getValue() instanceof Double)
|
||||
values.put(entry.getKey(), (Double) entry.getValue());
|
||||
else if (entry.getValue() instanceof String)
|
||||
values.put(entry.getKey(), (String) entry.getValue());
|
||||
else throw new IllegalStateException(
|
||||
"unsupported type: " + entry.getValue());
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -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.database;
|
||||
|
||||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class BaseSQLiteOpenHelper extends SQLiteOpenHelper
|
||||
{
|
||||
private final Context context;
|
||||
|
||||
private final int version;
|
||||
|
||||
public BaseSQLiteOpenHelper(@AppContext Context context,
|
||||
String databaseFilename,
|
||||
int version)
|
||||
{
|
||||
super(context, databaseFilename, null, version);
|
||||
this.context = context;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db)
|
||||
{
|
||||
executeMigrations(db, -1, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||
{
|
||||
executeMigrations(db, oldVersion, newVersion);
|
||||
}
|
||||
|
||||
private void executeMigrations(SQLiteDatabase db,
|
||||
int oldVersion,
|
||||
int newVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int v = oldVersion + 1; v <= newVersion; v++)
|
||||
{
|
||||
String fname = String.format(Locale.US, "migrations/%d.sql", v);
|
||||
InputStream stream = context.getAssets().open(fname);
|
||||
for (String command : SQLParser.parse(stream))
|
||||
db.execSQL(command);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||
{
|
||||
throw new UnsupportedDatabaseVersionException();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
@@ -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.models.sqlite;
|
||||
package org.isoron.uhabits.database;
|
||||
|
||||
public class InconsistentDatabaseException extends RuntimeException
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
@@ -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.models.sqlite;
|
||||
package org.isoron.uhabits.database;
|
||||
|
||||
public class InvalidDatabaseVersionException extends RuntimeException
|
||||
{
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.database;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class Tokenizer {
|
||||
|
||||
private final InputStream mStream;
|
||||
|
||||
private boolean mIsNext;
|
||||
private int mCurrent;
|
||||
|
||||
public Tokenizer(final InputStream in) {
|
||||
this.mStream = in;
|
||||
}
|
||||
|
||||
public boolean hasNext() throws IOException {
|
||||
|
||||
if (!this.mIsNext) {
|
||||
this.mIsNext = true;
|
||||
this.mCurrent = this.mStream.read();
|
||||
}
|
||||
return this.mCurrent != -1;
|
||||
}
|
||||
|
||||
public int next() throws IOException {
|
||||
|
||||
if (!this.mIsNext) {
|
||||
this.mCurrent = this.mStream.read();
|
||||
}
|
||||
this.mIsNext = false;
|
||||
return this.mCurrent;
|
||||
}
|
||||
|
||||
public boolean skip(final String s) throws IOException {
|
||||
|
||||
if (s == null || s.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s.charAt(0) != this.mCurrent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int len = s.length();
|
||||
this.mStream.mark(len - 1);
|
||||
|
||||
for (int n = 1; n < len; n++) {
|
||||
final int value = this.mStream.read();
|
||||
|
||||
if (value != s.charAt(n)) {
|
||||
this.mStream.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SQLParser {
|
||||
|
||||
public final static int STATE_NONE = 0;
|
||||
public final static int STATE_STRING = 1;
|
||||
public final static int STATE_COMMENT = 2;
|
||||
public final static int STATE_COMMENT_BLOCK = 3;
|
||||
|
||||
public static List<String> parse(final InputStream stream) throws IOException {
|
||||
|
||||
final BufferedInputStream buffer = new BufferedInputStream(stream);
|
||||
final List<String> commands = new ArrayList<String>();
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
|
||||
try {
|
||||
final Tokenizer tokenizer = new Tokenizer(buffer);
|
||||
int state = STATE_NONE;
|
||||
|
||||
while (tokenizer.hasNext()) {
|
||||
final char c = (char) tokenizer.next();
|
||||
|
||||
if (state == STATE_COMMENT_BLOCK) {
|
||||
if (tokenizer.skip("*/")) {
|
||||
state = STATE_NONE;
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (state == STATE_COMMENT) {
|
||||
if (isNewLine(c)) {
|
||||
state = STATE_NONE;
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (state == STATE_NONE && tokenizer.skip("/*")) {
|
||||
state = STATE_COMMENT_BLOCK;
|
||||
continue;
|
||||
|
||||
} else if (state == STATE_NONE && tokenizer.skip("--")) {
|
||||
state = STATE_COMMENT;
|
||||
continue;
|
||||
|
||||
} else if (state == STATE_NONE && c == ';') {
|
||||
final String command = sb.toString().trim();
|
||||
commands.add(command);
|
||||
sb.setLength(0);
|
||||
continue;
|
||||
|
||||
} else if (state == STATE_NONE && c == '\'') {
|
||||
state = STATE_STRING;
|
||||
|
||||
} else if (state == STATE_STRING && c == '\'') {
|
||||
state = STATE_NONE;
|
||||
|
||||
}
|
||||
|
||||
if (state == STATE_NONE || state == STATE_STRING) {
|
||||
if (state == STATE_NONE && isWhitespace(c)) {
|
||||
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != ' ') {
|
||||
sb.append(' ');
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
if (sb.length() > 0) {
|
||||
commands.add(sb.toString().trim());
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
private static boolean isNewLine(final char c) {
|
||||
return c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(final char c) {
|
||||
return c == '\r' || c == '\n' || c == '\t' || c == ' ';
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
@@ -15,9 +15,12 @@
|
||||
*
|
||||
* 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 SQLite implementations of the core models.
|
||||
*/
|
||||
package org.isoron.uhabits.models.sqlite;
|
||||
package org.isoron.uhabits.database;
|
||||
|
||||
public class UnsupportedDatabaseVersionException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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 org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
/**
|
||||
* Factory that provides models backed by an SQLite database.
|
||||
*/
|
||||
@Module
|
||||
public class SQLModelFactory implements ModelFactory
|
||||
{
|
||||
@Provides
|
||||
public static ModelFactory provideModelFactory()
|
||||
{
|
||||
return new SQLModelFactory();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@AppScope
|
||||
public static HabitList provideHabitList(ModelFactory modelFactory)
|
||||
{
|
||||
return new SQLiteHabitList(modelFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckmarkList buildCheckmarkList(Habit habit)
|
||||
{
|
||||
return new MemoryCheckmarkList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HabitList buildHabitList()
|
||||
{
|
||||
return SQLiteHabitList.getInstance(provideModelFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepetitionList buildRepetitionList(Habit habit)
|
||||
{
|
||||
return new SQLiteRepetitionList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreList buildScoreList(Habit habit)
|
||||
{
|
||||
return new MemoryScoreList(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreakList buildStreakList(Habit habit)
|
||||
{
|
||||
return new MemoryStreakList(habit);
|
||||
}
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
/*
|
||||
* 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.sqlite.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.isoron.uhabits.utils.DatabaseUtils.executeAsTransaction;
|
||||
|
||||
/**
|
||||
* Implementation of a {@link HabitList} that is backed by SQLite.
|
||||
*/
|
||||
public class SQLiteHabitList extends HabitList
|
||||
{
|
||||
private static SQLiteHabitList instance;
|
||||
|
||||
@NonNull
|
||||
private final SQLiteRepository<HabitRecord> repository;
|
||||
|
||||
@NonNull
|
||||
private final ModelFactory modelFactory;
|
||||
|
||||
@NonNull
|
||||
private final MemoryHabitList list;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
public SQLiteHabitList(@NonNull ModelFactory modelFactory)
|
||||
{
|
||||
super();
|
||||
this.modelFactory = modelFactory;
|
||||
this.list = new MemoryHabitList();
|
||||
|
||||
repository =
|
||||
new SQLiteRepository<>(HabitRecord.class, DatabaseUtils.openDatabase());
|
||||
}
|
||||
|
||||
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");
|
||||
executeAsTransaction(() ->
|
||||
{
|
||||
((SQLiteRepetitionList) habit.getRepetitions()).removeAll();
|
||||
repository.remove(record);
|
||||
});
|
||||
rebuildOrder();
|
||||
getObservable().notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeAll()
|
||||
{
|
||||
list.removeAll();
|
||||
SQLiteDatabase db = DatabaseUtils.openDatabase();
|
||||
db.execSQL("delete from habits");
|
||||
db.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;
|
||||
SQLiteDatabase db = DatabaseUtils.openDatabase();
|
||||
if (toPos < fromPos)
|
||||
{
|
||||
db.execSQL("update habits set position = position + 1 " +
|
||||
"where position >= ? and position < ?",
|
||||
new String[]{ toPos.toString(), fromPos.toString() });
|
||||
}
|
||||
else
|
||||
{
|
||||
db.execSQL("update habits set position = position - 1 " +
|
||||
"where position > ? and position <= ?",
|
||||
new String[]{ fromPos.toString(), toPos.toString() });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* 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.support.annotation.*;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.isoron.uhabits.core.models.memory.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Implementation of a {@link RepetitionList} that is backed by SQLite.
|
||||
*/
|
||||
public class SQLiteRepetitionList extends RepetitionList
|
||||
{
|
||||
private final SQLiteRepository<RepetitionRecord> repository;
|
||||
|
||||
private final MemoryRepetitionList list;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
public SQLiteRepetitionList(@NonNull Habit habit)
|
||||
{
|
||||
super(habit);
|
||||
repository = new SQLiteRepository<>(RepetitionRecord.class,
|
||||
DatabaseUtils.openDatabase());
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.commons.lang3.builder.*;
|
||||
import org.isoron.androidbase.storage.*;
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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 org.isoron.androidbase.storage.*;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes that represent rows in the SQLite database.
|
||||
*/
|
||||
package org.isoron.uhabits.models.sqlite.records;
|
||||
@@ -21,7 +21,7 @@ package org.isoron.uhabits.sync;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
|
||||
@Table(name = "Events")
|
||||
public class Event
|
||||
|
||||
@@ -23,11 +23,12 @@ import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.storage.*;
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.core.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
import org.isoron.uhabits.core.db.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.json.*;
|
||||
|
||||
@@ -97,7 +98,7 @@ public class SyncManager implements CommandRunner.Listener
|
||||
|
||||
private SSLContextProvider sslProvider;
|
||||
|
||||
private final SQLiteRepository<Event> repository;
|
||||
private final Repository<Event> repository;
|
||||
|
||||
@Inject
|
||||
public SyncManager(@NonNull SSLContextProvider sslProvider,
|
||||
@@ -113,8 +114,8 @@ public class SyncManager implements CommandRunner.Listener
|
||||
this.commandParser = commandParser;
|
||||
this.isListening = false;
|
||||
|
||||
repository =
|
||||
new SQLiteRepository<>(Event.class, DatabaseUtils.openDatabase());
|
||||
repository = new Repository<>(Event.class,
|
||||
new AndroidSQLiteDatabase(DatabaseUtils.openDatabase()));
|
||||
pendingConfirmation = new LinkedList<>();
|
||||
pendingEmit = new LinkedList<>(repository.findAll("order by timestamp"));
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.support.annotation.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.utils.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
import org.isoron.uhabits.database.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
@@ -36,6 +36,7 @@ public abstract class DatabaseUtils
|
||||
@Nullable
|
||||
private static HabitsDatabaseOpener opener = null;
|
||||
|
||||
@Deprecated
|
||||
public static void executeAsTransaction(Callback callback)
|
||||
{
|
||||
try (SQLiteDatabase db = openDatabase())
|
||||
|
||||
Reference in New Issue
Block a user