From b96385c4a72be0e1f3ddf7e19c1bae4b6b5355cb Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Tue, 20 Jun 2017 12:50:57 -0400 Subject: [PATCH] Move models.sqlite to uhabits-core --- .../isoron/uhabits/AndroidTestComponent.java | 2 - .../models/sqlite/SQLiteHabitListTest.java | 13 +- .../sqlite/SQLiteRepetitionListTest.java | 11 +- .../models/sqlite/SQLiteRepositoryTest.java | 10 +- .../org/isoron/uhabits/HabitsApplication.java | 2 +- .../uhabits/HabitsApplicationComponent.java | 5 +- .../isoron/uhabits/HabitsDatabaseOpener.java | 2 +- .../java/org/isoron/uhabits/HabitsModule.java | 17 +++ .../uhabits/database/AndroidCursor.java | 70 ++++++++++ .../database/AndroidSQLiteDatabase.java | 113 +++++++++++++++++ .../database}/BaseSQLiteOpenHelper.java | 2 +- .../InconsistentDatabaseException.java | 6 +- .../InvalidDatabaseVersionException.java | 6 +- .../isoron/uhabits/database}/SQLParser.java | 27 ++-- .../UnsupportedDatabaseVersionException.java | 2 +- .../java/org/isoron/uhabits/sync/Event.java | 2 +- .../org/isoron/uhabits/sync/SyncManager.java | 9 +- .../isoron/uhabits/utils/DatabaseUtils.java | 3 +- uhabits-core/build.gradle | 1 + .../org/isoron/uhabits/core/db}/Column.java | 2 +- .../org/isoron/uhabits/core/db/Cursor.java | 25 +++- .../org/isoron/uhabits/core/db/Database.java | 46 +++++++ .../isoron/uhabits/core/db/Repository.java | 120 ++++++++++++------ .../org/isoron/uhabits/core/db}/Table.java | 2 +- .../uhabits/core/models/ModelFactory.java | 7 + .../models/memory/MemoryModelFactory.java | 32 ++--- .../core}/models/sqlite/SQLModelFactory.java | 41 +++--- .../core}/models/sqlite/SQLiteHabitList.java | 43 +++---- .../models/sqlite/SQLiteRepetitionList.java | 19 +-- .../sqlite/package-info.java} | 10 +- .../models/sqlite/records/HabitRecord.java | 8 +- .../sqlite/records/RepetitionRecord.java | 8 +- .../models/sqlite/records/package-info.java | 6 +- .../sqlite/records}/HabitRecordTest.java | 23 +--- .../sqlite/records/RepetitionRecordTest.java | 42 ++++++ 35 files changed, 550 insertions(+), 187 deletions(-) create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.java create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidSQLiteDatabase.java rename {android-base/src/main/java/org/isoron/androidbase/storage => uhabits-android/src/main/java/org/isoron/uhabits/database}/BaseSQLiteOpenHelper.java (98%) rename uhabits-android/src/main/java/org/isoron/uhabits/{models/sqlite => database}/InconsistentDatabaseException.java (89%) rename uhabits-android/src/main/java/org/isoron/uhabits/{models/sqlite => database}/InvalidDatabaseVersionException.java (88%) rename {android-base/src/main/java/org/isoron/androidbase/storage => uhabits-android/src/main/java/org/isoron/uhabits/database}/SQLParser.java (83%) rename {android-base/src/main/java/org/isoron/androidbase/storage => uhabits-android/src/main/java/org/isoron/uhabits/database}/UnsupportedDatabaseVersionException.java (95%) rename {android-base/src/main/java/org/isoron/androidbase/storage => uhabits-core/src/main/java/org/isoron/uhabits/core/db}/Column.java (95%) rename uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/package-info.java => uhabits-core/src/main/java/org/isoron/uhabits/core/db/Cursor.java (67%) create mode 100644 uhabits-core/src/main/java/org/isoron/uhabits/core/db/Database.java rename android-base/src/main/java/org/isoron/androidbase/storage/SQLiteRepository.java => uhabits-core/src/main/java/org/isoron/uhabits/core/db/Repository.java (70%) rename {android-base/src/main/java/org/isoron/androidbase/storage => uhabits-core/src/main/java/org/isoron/uhabits/core/db}/Table.java (95%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/SQLModelFactory.java (67%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/SQLiteHabitList.java (82%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/SQLiteRepetitionList.java (88%) rename uhabits-core/src/main/java/org/isoron/uhabits/core/{MyClass.java => models/sqlite/package-info.java} (87%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/records/HabitRecord.java (97%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/records/RepetitionRecord.java (89%) rename {uhabits-android/src/main/java/org/isoron/uhabits => uhabits-core/src/main/java/org/isoron/uhabits/core}/models/sqlite/records/package-info.java (86%) rename {uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite => uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records}/HabitRecordTest.java (78%) create mode 100644 uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecordTest.java diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/AndroidTestComponent.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/AndroidTestComponent.java index 6f1a01489..ffd27be59 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/AndroidTestComponent.java +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/AndroidTestComponent.java @@ -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 { diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java index beb9f3b2a..6cb649562 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteHabitListTest.java @@ -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 repository; + private Repository 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++) { diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionListTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionListTest.java index 2927d3198..14cf52255 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionListTest.java +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionListTest.java @@ -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 sqlite; + private Repository 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 diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepositoryTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepositoryTest.java index 57bde37cb..d00dc9bdf 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepositoryTest.java +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/SQLiteRepositoryTest.java @@ -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 repository; + private Repository 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(" + diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.java b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.java index a4b05e391..b220e500d 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplication.java @@ -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.*; diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplicationComponent.java b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplicationComponent.java index 88f7b5e65..0b89acf52 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplicationComponent.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsApplicationComponent.java @@ -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 { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsDatabaseOpener.java b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsDatabaseOpener.java index e75368bf8..ffb43fc7f 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsDatabaseOpener.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsDatabaseOpener.java @@ -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 diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsModule.java b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsModule.java index 6c3841474..a00729b8a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/HabitsModule.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/HabitsModule.java @@ -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; + } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.java new file mode 100644 index 000000000..2531836a5 --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidCursor.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * + */ + +package org.isoron.uhabits.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); + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidSQLiteDatabase.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidSQLiteDatabase.java new file mode 100644 index 000000000..96618bcf0 --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/AndroidSQLiteDatabase.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * + */ + +package org.isoron.uhabits.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 map, + String where, + String... params) + { + ContentValues values = mapToContentValues(map); + return db.update(tableName, values, where, params); + } + + @Override + public Long insert(String tableName, Map 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 map) + { + ContentValues values = new ContentValues(); + for (Map.Entry 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; + } +} diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/BaseSQLiteOpenHelper.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/BaseSQLiteOpenHelper.java similarity index 98% rename from android-base/src/main/java/org/isoron/androidbase/storage/BaseSQLiteOpenHelper.java rename to uhabits-android/src/main/java/org/isoron/uhabits/database/BaseSQLiteOpenHelper.java index 64d99b170..abc698856 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/BaseSQLiteOpenHelper.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/BaseSQLiteOpenHelper.java @@ -19,7 +19,7 @@ * */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.database; import android.content.*; import android.database.sqlite.*; diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InconsistentDatabaseException.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/InconsistentDatabaseException.java similarity index 89% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InconsistentDatabaseException.java rename to uhabits-android/src/main/java/org/isoron/uhabits/database/InconsistentDatabaseException.java index 2a3d862ca..2775aa623 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InconsistentDatabaseException.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/InconsistentDatabaseException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * 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 . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.database; public class InconsistentDatabaseException extends RuntimeException { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InvalidDatabaseVersionException.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/InvalidDatabaseVersionException.java similarity index 88% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InvalidDatabaseVersionException.java rename to uhabits-android/src/main/java/org/isoron/uhabits/database/InvalidDatabaseVersionException.java index 6fb417cc4..26af5d3a0 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/InvalidDatabaseVersionException.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/InvalidDatabaseVersionException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * 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 . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.database; public class InvalidDatabaseVersionException extends RuntimeException { diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/SQLParser.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/SQLParser.java similarity index 83% rename from android-base/src/main/java/org/isoron/androidbase/storage/SQLParser.java rename to uhabits-android/src/main/java/org/isoron/uhabits/database/SQLParser.java index d995ffeb0..b72959b4e 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/SQLParser.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/SQLParser.java @@ -1,20 +1,25 @@ /* - * Copyright (C) 2014 Markus Pfeiffer + * Copyright (C) 2017 Álinson Santos Xavier * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.database; import java.io.BufferedInputStream; import java.io.IOException; diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/UnsupportedDatabaseVersionException.java b/uhabits-android/src/main/java/org/isoron/uhabits/database/UnsupportedDatabaseVersionException.java similarity index 95% rename from android-base/src/main/java/org/isoron/androidbase/storage/UnsupportedDatabaseVersionException.java rename to uhabits-android/src/main/java/org/isoron/uhabits/database/UnsupportedDatabaseVersionException.java index 7e00f7d55..aec1d8f2b 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/UnsupportedDatabaseVersionException.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/database/UnsupportedDatabaseVersionException.java @@ -19,7 +19,7 @@ * */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.database; public class UnsupportedDatabaseVersionException extends RuntimeException { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/sync/Event.java b/uhabits-android/src/main/java/org/isoron/uhabits/sync/Event.java index 5f683928c..037eb2dbf 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/sync/Event.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/sync/Event.java @@ -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 diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/sync/SyncManager.java b/uhabits-android/src/main/java/org/isoron/uhabits/sync/SyncManager.java index 761c8e7a9..80f5997d6 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/sync/SyncManager.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/sync/SyncManager.java @@ -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 repository; + private final Repository 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")); diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java index fd3f399c1..b82ec86a1 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/DatabaseUtils.java @@ -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()) diff --git a/uhabits-core/build.gradle b/uhabits-core/build.gradle index cb77f2da7..cb3478308 100644 --- a/uhabits-core/build.gradle +++ b/uhabits-core/build.gradle @@ -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' diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/Column.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Column.java similarity index 95% rename from android-base/src/main/java/org/isoron/androidbase/storage/Column.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/db/Column.java index e4c228a58..be55efd44 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/Column.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Column.java @@ -19,7 +19,7 @@ * */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.core.db; import java.lang.annotation.*; diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/package-info.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Cursor.java similarity index 67% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/package-info.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/db/Cursor.java index 469894365..4d65b93b1 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/package-info.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Cursor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,9 +15,24 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -/** - * Provides SQLite implementations of the core models. - */ -package org.isoron.uhabits.models.sqlite; \ No newline at end of file +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); +} diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Database.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Database.java new file mode 100644 index 000000000..dbf3bf2f8 --- /dev/null +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Database.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * + */ + +package org.isoron.uhabits.core.db; + +import java.util.*; + +public interface Database +{ + Cursor select(String query, String... params); + + int update(String tableName, + Map values, + String where, + String... params); + + Long insert(String tableName, Map values); + + void delete(String tableName, String where, String... params); + + void execSQL(String query, Object... params); + + void beginTransaction(); + + void setTransactionSuccessful(); + + void endTransaction(); +} diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/SQLiteRepository.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Repository.java similarity index 70% rename from android-base/src/main/java/org/isoron/androidbase/storage/SQLiteRepository.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/db/Repository.java index 4fd3f1906..6f476666d 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/SQLiteRepository.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Repository.java @@ -19,34 +19,35 @@ * */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.core.db; -import android.content.*; -import android.database.*; -import android.database.sqlite.*; import android.support.annotation.*; -import android.util.*; import org.apache.commons.lang3.*; +import org.apache.commons.lang3.tuple.*; import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; -public class SQLiteRepository +public class Repository { @NonNull private final Class klass; @NonNull - private final SQLiteDatabase db; + private final Database db; - public SQLiteRepository(@NonNull Class klass, @NonNull SQLiteDatabase db) + public Repository(@NonNull Class 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) { @@ -54,30 +55,85 @@ public class SQLiteRepository 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 findAll(String query, String... params) + public List findAll(@NonNull String query, @NonNull String... params) { - try (Cursor c = db.rawQuery(buildSelectQuery() + query, 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.rawQuery(buildSelectQuery() + query, 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 @@ -85,9 +141,9 @@ public class SQLiteRepository Field fields[] = getFields(); String columns[] = getColumnNames(); - ContentValues values = new ContentValues(); + Map values = new HashMap<>(); for (int i = 0; i < fields.length; i++) - fieldToContentValue(values, columns[i], fields[i], record); + values.put(columns[i], fields[i].get(record)); Long id = (Long) getIdField().get(record); int affectedRows = 0; @@ -98,7 +154,7 @@ public class SQLiteRepository if (id == null || affectedRows == 0) { - id = db.insertOrThrow(getTableName(), null, values); + id = db.insert(getTableName(), values); getIdField().set(record, id); } @@ -109,6 +165,10 @@ public class SQLiteRepository } } + /** + * Removes the given record from the repository. + * The id of the given record is also set to null. + */ public void remove(T record) { try @@ -170,30 +230,6 @@ public class SQLiteRepository field.getName()); } - private void fieldToContentValue(ContentValues values, - String columnName, - Field field, - T record) - { - try - { - if (field.getType().isAssignableFrom(Integer.class)) - values.put(columnName, (Integer) field.get(record)); - else if (field.getType().isAssignableFrom(Long.class)) - values.put(columnName, (Long) field.get(record)); - else if (field.getType().isAssignableFrom(Double.class)) - values.put(columnName, (Double) field.get(record)); - else if (field.getType().isAssignableFrom(String.class)) - values.put(columnName, (String) field.get(record)); - else throw new RuntimeException( - "Type not supported: " + field.getName()); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } - } - private String buildSelectQuery() { return String.format("select %s from %s ", @@ -208,7 +244,7 @@ public class SQLiteRepository { if (!(annotation instanceof Column)) continue; Column column = (Column) annotation; - fields.add(new Pair<>(field, column)); + fields.add(new ImmutablePair<>(field, column)); } return fields; } @@ -218,7 +254,7 @@ public class SQLiteRepository { List fields = new ArrayList<>(); List> columns = getFieldColumnPairs(); - for (Pair pair : columns) fields.add(pair.first); + for (Pair pair : columns) fields.add(pair.getLeft()); return fields.toArray(new Field[]{}); } @@ -229,8 +265,8 @@ public class SQLiteRepository List> columns = getFieldColumnPairs(); for (Pair pair : columns) { - String cname = pair.second.name(); - if (cname.isEmpty()) cname = pair.first.getName(); + 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); diff --git a/android-base/src/main/java/org/isoron/androidbase/storage/Table.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Table.java similarity index 95% rename from android-base/src/main/java/org/isoron/androidbase/storage/Table.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/db/Table.java index c56711191..97aa0f16d 100644 --- a/android-base/src/main/java/org/isoron/androidbase/storage/Table.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/db/Table.java @@ -19,7 +19,7 @@ * */ -package org.isoron.androidbase.storage; +package org.isoron.uhabits.core.db; import java.lang.annotation.*; diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/ModelFactory.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/ModelFactory.java index 5c6a548c1..6bfae61b7 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/ModelFactory.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/ModelFactory.java @@ -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 buildHabitListRepository(); + + Repository buildRepetitionListRepository(); } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryModelFactory.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryModelFactory.java index bbb67a1b0..7e636f076 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryModelFactory.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryModelFactory.java @@ -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 buildHabitListRepository() + { + throw new IllegalStateException(); + } + + @Override + public Repository buildRepetitionListRepository() + { + throw new IllegalStateException(); + } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java similarity index 67% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java index 795c60ae4..044703c23 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLModelFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,33 +15,30 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.core.models.sqlite; -import org.isoron.uhabits.core.*; +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 dagger.*; +import javax.inject.*; /** * Factory that provides models backed by an SQLite database. */ -@Module public class SQLModelFactory implements ModelFactory { - @Provides - public static ModelFactory provideModelFactory() - { - return new SQLModelFactory(); - } + private final Database db; - @Provides - @AppScope - public static HabitList provideHabitList(ModelFactory modelFactory) + @Inject + public SQLModelFactory(Database db) { - return new SQLiteHabitList(modelFactory); + this.db = db; } @Override @@ -53,13 +50,13 @@ public class SQLModelFactory implements ModelFactory @Override public HabitList buildHabitList() { - return SQLiteHabitList.getInstance(provideModelFactory()); + return new SQLiteHabitList(this); } @Override public RepetitionList buildRepetitionList(Habit habit) { - return new SQLiteRepetitionList(habit); + return new SQLiteRepetitionList(habit, this); } @Override @@ -73,4 +70,16 @@ public class SQLModelFactory implements ModelFactory { return new MemoryStreakList(habit); } + + @Override + public Repository buildHabitListRepository() + { + return new Repository<>(HabitRecord.class, db); + } + + @Override + public Repository buildRepetitionListRepository() + { + return new Repository<>(RepetitionRecord.class, db); + } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java similarity index 82% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java index 3d0496936..c5eaf9c29 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteHabitList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,22 +15,22 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.core.models.sqlite; -import android.database.sqlite.*; import android.support.annotation.*; -import org.isoron.androidbase.storage.*; +import org.isoron.uhabits.core.db.*; 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.isoron.uhabits.core.models.sqlite.records.*; import java.util.*; -import static org.isoron.uhabits.utils.DatabaseUtils.executeAsTransaction; +import javax.inject.*; /** * Implementation of a {@link HabitList} that is backed by SQLite. @@ -40,7 +40,7 @@ public class SQLiteHabitList extends HabitList private static SQLiteHabitList instance; @NonNull - private final SQLiteRepository repository; + private final Repository repository; @NonNull private final ModelFactory modelFactory; @@ -50,19 +50,18 @@ public class SQLiteHabitList extends HabitList private boolean loaded = false; + @Inject public SQLiteHabitList(@NonNull ModelFactory modelFactory) { super(); this.modelFactory = modelFactory; this.list = new MemoryHabitList(); - - repository = - new SQLiteRepository<>(HabitRecord.class, DatabaseUtils.openDatabase()); + this.repository = modelFactory.buildHabitListRepository(); } private void loadRecords() { - if(loaded) return; + if (loaded) return; loaded = true; list.removeAll(); @@ -173,7 +172,7 @@ public class SQLiteHabitList extends HabitList HabitRecord record = repository.find(habit.getId()); if (record == null) throw new RuntimeException("habit not in database"); - executeAsTransaction(() -> + repository.executeAsTransaction(() -> { ((SQLiteRepetitionList) habit.getRepetitions()).removeAll(); repository.remove(record); @@ -186,9 +185,8 @@ public class SQLiteHabitList extends HabitList public synchronized void removeAll() { list.removeAll(); - SQLiteDatabase db = DatabaseUtils.openDatabase(); - db.execSQL("delete from habits"); - db.execSQL("delete from repetitions"); + repository.execSQL("delete from habits"); + repository.execSQL("delete from repetitions"); getObservable().notifyListeners(); } @@ -208,18 +206,17 @@ public class SQLiteHabitList extends HabitList 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() }); + repository.execSQL("update habits set position = position + 1 " + + "where position >= ? and position < ?", + toPos, fromPos); } else { - db.execSQL("update habits set position = position - 1 " + - "where position > ? and position <= ?", - new String[]{ fromPos.toString(), toPos.toString() }); + repository.execSQL("update habits set position = position - 1 " + + "where position > ? and position <= ?", + fromPos, toPos); } fromRecord.position = toPos; diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java similarity index 88% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionList.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java index 9a7bfea9c..9ae44a15f 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/SQLiteRepetitionList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,18 +15,19 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.core.models.sqlite; import android.support.annotation.*; import android.support.annotation.Nullable; -import org.isoron.androidbase.storage.*; +import org.isoron.uhabits.core.db.*; 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.isoron.uhabits.core.models.sqlite.records.*; import org.jetbrains.annotations.*; import java.util.*; @@ -36,17 +37,17 @@ import java.util.*; */ public class SQLiteRepetitionList extends RepetitionList { - private final SQLiteRepository repository; + private final Repository repository; private final MemoryRepetitionList list; private boolean loaded = false; - public SQLiteRepetitionList(@NonNull Habit habit) + public SQLiteRepetitionList(@NonNull Habit habit, + @NonNull ModelFactory modelFactory) { super(habit); - repository = new SQLiteRepository<>(RepetitionRecord.class, - DatabaseUtils.openDatabase()); + repository = modelFactory.buildRepetitionListRepository(); list = new MemoryRepetitionList(habit); } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/MyClass.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/package-info.java similarity index 87% rename from uhabits-core/src/main/java/org/isoron/uhabits/core/MyClass.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/package-info.java index dd5cdb01d..f67932d83 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/MyClass.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/package-info.java @@ -15,9 +15,11 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.core; - -public class MyClass -{} +/** + * Provides SQLite implementations of the core models. + */ +package org.isoron.uhabits.core.models.sqlite; \ No newline at end of file diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecord.java similarity index 97% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecord.java index 9943941c9..076a36f30 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/HabitRecord.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecord.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,12 +15,14 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite.records; +package org.isoron.uhabits.core.models.sqlite.records; import org.apache.commons.lang3.builder.*; -import org.isoron.androidbase.storage.*; +import org.isoron.uhabits.core.db.*; import org.isoron.uhabits.core.models.*; /** diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/RepetitionRecord.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecord.java similarity index 89% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/RepetitionRecord.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecord.java index 8cd871c78..b6dee41a0 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/RepetitionRecord.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecord.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,11 +15,13 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite.records; +package org.isoron.uhabits.core.models.sqlite.records; -import org.isoron.androidbase.storage.*; +import org.isoron.uhabits.core.db.*; import org.isoron.uhabits.core.models.*; /** diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/package-info.java similarity index 86% rename from uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java rename to uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/package-info.java index 379d6a6e0..74a9ac796 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/records/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * 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 . + * + * */ /** * Provides classes that represent rows in the SQLite database. */ -package org.isoron.uhabits.models.sqlite.records; \ No newline at end of file +package org.isoron.uhabits.core.models.sqlite.records; \ No newline at end of file diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/HabitRecordTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecordTest.java similarity index 78% rename from uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/HabitRecordTest.java rename to uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecordTest.java index 18c393b2a..5b94e8a1e 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/models/sqlite/HabitRecordTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/HabitRecordTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Álinson Santos Xavier + * Copyright (C) 2017 Álinson Santos Xavier * * This file is part of Loop Habit Tracker. * @@ -15,40 +15,31 @@ * * You should have received a copy of the GNU General Public License along * with this program. If not, see . + * + * */ -package org.isoron.uhabits.models.sqlite; +package org.isoron.uhabits.core.models.sqlite.records; -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.isoron.uhabits.core.models.sqlite.records.*; 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 +public class HabitRecordTest extends BaseUnitTest { private Habit habit; - private SQLiteRepository sqlite = - new SQLiteRepository<>(HabitRecord.class, DatabaseUtils.openDatabase()); - @Before @Override public void setUp() { super.setUp(); - habit = component.getModelFactory().buildHabit(); + habit = modelFactory.buildHabit(); habit.setName("Hello world"); habit.setDescription("Did you greet the world today?"); habit.setColor(1); diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecordTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecordTest.java new file mode 100644 index 000000000..640777e42 --- /dev/null +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/records/RepetitionRecordTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * + */ + +package org.isoron.uhabits.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())); + } +}