Implementing Room library for database

Creating a repository for abstraction
This commit is contained in:
BONNEVILLE Geoffroy
2018-11-15 18:37:19 +01:00
parent 96ff19eab0
commit cc09397ba2
16 changed files with 375 additions and 0 deletions

View File

@@ -10,6 +10,11 @@ android {
targetSdkVersion 28
versionCode 28
versionName "1.7"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
release {
@@ -40,7 +45,21 @@ dependencies {
implementation 'net.danlew:android.joda:2.9.7'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
testImplementation 'junit:junit:4.12'
// App Center
def appCenterSdkVersion = '1.9.0'
implementation "com.microsoft.appcenter:appcenter-analytics:${appCenterSdkVersion}"
implementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
// Room components
def roomVersion = "2.1.0-alpha02"
implementation "androidx.room:room-runtime:$roomVersion"
annotationProcessor "androidx.room:room-compiler:$roomVersion"
testImplementation "androidx.room:room-testing:$roomVersion"
// Lifecycle components
def archLifecycleVersion = '2.0.0'
implementation "android.arch.lifecycle:extensions:$archLifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$archLifecycleVersion"
}

View File

@@ -8,6 +8,8 @@ import org.joda.time.LocalDate;
* Created by geoffroy on 15-11-25.
* Data access object class that represents a Task
*/
@Deprecated
public class Task {
private long id;
private String name;

View File

@@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
* Created by geoffroy on 15-11-25.
* Data access object class that represents a Task List
*/
@Deprecated
public class TaskList {
private long id;
private String name;

View File

@@ -0,0 +1,32 @@
package com.wismna.geoffroy.donext.data;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
@Database(entities = {Task.class, TaskList.class}, views = {TodayTasksView.class}, version = 6)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract TaskDao taskDao();
public abstract TaskListDao taskListDao();
private static volatile AppDatabase INSTANCE;
public static AppDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "donext.db")
.addMigrations(Migrations.MIGRATION_1_2, Migrations.MIGRATION_2_3,
Migrations.MIGRATION_3_4, Migrations.MIGRATION_4_6)
.build();
}
}
}
return INSTANCE;
}
}

View File

@@ -0,0 +1,17 @@
package com.wismna.geoffroy.donext.data;
import org.joda.time.LocalDate;
import androidx.room.TypeConverter;
public class Converters {
@TypeConverter
public static LocalDate fromDateString(String value) {
return LocalDate.parse(value);
}
@TypeConverter
public static String toLocalDate(LocalDate value) {
return value.toString();
}
}

View File

@@ -0,0 +1,33 @@
package com.wismna.geoffroy.donext.data;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
public class Migrations {
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE tasklist ADD COLUMN displayorder INTEGER");
}
};
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE tasklist ADD COLUMN visible INTEGER DEFAULT 1");
database.execSQL("ALTER TABLE tasks ADD COLUMN duedate DATE");
}
};
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE tasks ADD COLUMN todaydate DATE");
}
};
static final Migration MIGRATION_4_6 = new Migration(4, 6) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE tasks ADD COLUMN todayorder INTEGER");
}
};
}

View File

@@ -0,0 +1,53 @@
package com.wismna.geoffroy.donext.data;
import org.joda.time.LocalDate;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Index;
import androidx.room.PrimaryKey;
@Entity(tableName = "tasks",
indices = {@Index("list")},
foreignKeys = @ForeignKey(entity = TaskList.class,
parentColumns = "_id",
childColumns = "list"))
public class Task {
@PrimaryKey(autoGenerate = true)
public long _id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "description")
public String description;
@ColumnInfo(name = "cycle")
public int cycle = 0;
@ColumnInfo(name = "priority")
public int priority = 1;
@ColumnInfo(name = "done")
public boolean done = false;
@ColumnInfo(name = "deleted")
public boolean deleted = false;
@ColumnInfo(name = "displayorder")
public int order;
@ColumnInfo(name = "todayorder")
public int todayOrder;
@ColumnInfo(name = "list")
public long taskList;
@ColumnInfo(name = "duedate")
public LocalDate dueDate;
@ColumnInfo(name = "todaydate")
public LocalDate todayDate;
}

View File

@@ -0,0 +1,55 @@
package com.wismna.geoffroy.donext.data;
import java.util.List;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
@Dao
public interface TaskDao {
@Insert()
void createTask (Task task);
@Update()
void updateTask (Task task);
@Query("SELECT " +
"tasks._id," +
"tasks.name," +
"tasks.todaydate," +
"tasklist.name AS tasklistname " +
" FROM tasks" +
" LEFT JOIN tasklist ON tasks.list = tasklist._id" +
" WHERE tasks.done = 0 AND tasks.deleted = 0")
LiveData<List<TodayTask>> getAllTasks();
@Query("SELECT * FROM tasks WHERE list = :id AND done = 0 AND deleted = 0")
LiveData<List<Task>> getAllTasksFromList(long id);
@Query("SELECT * FROM tasks WHERE list = :id AND done = 1 OR deleted = 1")
LiveData<List<Task>> getAllTasksFromHistoryList(long id);
// TODO: replace query with view
//@Query("SELECT * FROM todaytasksview WHERE done = 0 AND deleted = 0")
@Query("SELECT * FROM tasks WHERE todaydate = date('now','localtime') AND done = 0 AND deleted = 0")
LiveData<List<Task>> getTodayTasks();
// TODO: replace this with item count from recycle view
@Query("SELECT MAX(displayorder) FROM tasks WHERE list = :id")
int getMaxOrder(long id);
@Query("UPDATE tasks SET displayorder = displayorder - 1" +
" WHERE displayorder > (SELECT displayorder FROM tasks WHERE _id = :id)")
void updateRemainingRowsOrder(long id);
@Query("UPDATE tasks SET todayorder = todayorder - 1" +
" WHERE todayorder > (SELECT todayorder FROM tasks WHERE _id = :id)")
void updateRemainingRowsTodayOrder(long id);
@Query("UPDATE tasks SET deleted = 1 WHERE list = :id")
void deleteAllTasks(long id);
}

View File

@@ -0,0 +1,25 @@
package com.wismna.geoffroy.donext.data;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "tasklist")
public class TaskList {
@PrimaryKey(autoGenerate = true)
public long _id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "visible")
public boolean visible = true;
@ColumnInfo(name = "displayorder")
public int order;
//@ColumnInfo(name = "taskcount")
public int taskCount;
}

View File

@@ -0,0 +1,27 @@
package com.wismna.geoffroy.donext.data;
import java.util.List;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
@Dao
public interface TaskListDao {
@Insert()
void createTaskList(TaskList taskList);
@Update()
void updateTaskList(TaskList taskList);
@Query("SELECT *,(SELECT COUNT(*) FROM tasks WHERE tasks.list = tasklist._id) AS taskcount" +
" FROM tasklist WHERE visible = 1 ORDER BY displayorder ASC ")
LiveData<List<TaskList>> getVisibleTaskLists();
@Query("SELECT *, (SELECT COUNT(*) FROM tasks WHERE tasks.list = tasklist._id AND (tasks.deleted = 1 OR tasks.done = 1)) AS taskcount" +
" FROM tasklist WHERE visible = 0 OR taskcount > 0 ORDER BY displayorder ASC ")
LiveData<List<TaskList>> getInvisibleTaskLists();
}

View File

@@ -0,0 +1,20 @@
package com.wismna.geoffroy.donext.data;
import org.joda.time.LocalDate;
import androidx.room.ColumnInfo;
import androidx.room.PrimaryKey;
public class TodayTask {
@PrimaryKey()
public long _id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "todaydate")
public LocalDate todayDate;
@ColumnInfo(name = "tasklistname")
public String taskListName;
}

View File

@@ -0,0 +1,20 @@
package com.wismna.geoffroy.donext.data;
import org.joda.time.LocalDate;
import androidx.room.DatabaseView;
@DatabaseView("SELECT * FROM tasks WHERE todaydate = date('now','localtime')")
public class TodayTasksView extends Task {
/*public long _id;
public String name;
public String description;
public int cycle;
public int priority;
public boolean done;
public boolean deleted;
public int order;
public int todayOrder;
public long taskList;
public LocalDate dueDate;*/
}

View File

@@ -16,6 +16,7 @@ import java.util.List;
* Created by geoffroy on 15-11-27.
* Data access class that handles Tasks
*/
@Deprecated
public class TaskDataAccess implements AutoCloseable {
public enum MODE {
READ,

View File

@@ -14,6 +14,7 @@ import java.util.List;
* Created by geoffroy on 15-11-25.
* Data access class that handles Task Lists
*/
@Deprecated
public class TaskListDataAccess implements AutoCloseable {
public enum MODE {
READ,

View File

@@ -0,0 +1,68 @@
package com.wismna.geoffroy.donext.repositories;
import android.app.Application;
import android.os.AsyncTask;
import com.wismna.geoffroy.donext.data.AppDatabase;
import com.wismna.geoffroy.donext.data.Task;
import com.wismna.geoffroy.donext.data.TaskDao;
import java.util.List;
import androidx.lifecycle.LiveData;
public class TaskRepository {
private TaskDao mTaskDao;
TaskRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mTaskDao = db.taskDao();
}
public void insert(Task task) {
new insertAsyncTask(mTaskDao).execute(task);
}
public void update(Task task) {
new updateAsyncTask(mTaskDao).execute(task);
}
public LiveData<List<Task>> getTasksInList(long taskId) {
return mTaskDao.getAllTasksFromList(taskId);
}
public LiveData<List<Task>> getTodayTasks() {
return mTaskDao.getTodayTasks();
}
// Async tasks
private static class insertAsyncTask extends AsyncTask<Task, Void, Void> {
private TaskDao mAsyncTaskDao;
insertAsyncTask(TaskDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Task... params) {
mAsyncTaskDao.createTask(params[0]);
return null;
}
}
private static class updateAsyncTask extends AsyncTask<Task, Void, Void> {
private TaskDao mAsyncTaskDao;
updateAsyncTask(TaskDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Task... params) {
mAsyncTaskDao.updateTask(params[0]);
return null;
}
}
}