mirror of https://github.com/tasks/tasks
Use paging library
parent
3009004dcf
commit
4762a7330f
@ -0,0 +1,97 @@
|
||||
package org.tasks.data;
|
||||
|
||||
import android.arch.paging.PositionalDataSource;
|
||||
import android.arch.persistence.room.RoomDatabase;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.WorkerThread;
|
||||
|
||||
import com.todoroo.astrid.data.Task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class LimitOffsetDataSource extends PositionalDataSource<Task> {
|
||||
|
||||
private final String mCountQuery;
|
||||
private final String mLimitOffsetQuery;
|
||||
private final RoomDatabase mDb;
|
||||
|
||||
protected LimitOffsetDataSource(RoomDatabase db, String query) {
|
||||
mDb = db;
|
||||
mCountQuery = "SELECT COUNT(*) FROM ( " + query + " )";
|
||||
mLimitOffsetQuery = "SELECT * FROM ( " + query + " ) LIMIT ? OFFSET ?";
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public int countItems() {
|
||||
Cursor cursor = mDb.query(mCountQuery, null);
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
return 0;
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected List<Task> convertRows(Cursor cursor) {
|
||||
List<Task> result = new ArrayList<>();
|
||||
while (cursor.moveToNext()) {
|
||||
result.add(new Task(cursor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@WorkerThread
|
||||
public List<Task> loadRange(int startPosition, int loadCount) {
|
||||
Cursor cursor = mDb.query(mLimitOffsetQuery, new Object[] { loadCount, startPosition });
|
||||
//noinspection TryFinallyCanBeTryWithResources
|
||||
try {
|
||||
return convertRows(cursor);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadInitial(@NonNull LoadInitialParams params,
|
||||
@NonNull LoadInitialCallback<Task> callback) {
|
||||
int totalCount = countItems();
|
||||
if (totalCount == 0) {
|
||||
callback.onResult(Collections.emptyList(), 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// bound the size requested, based on known count
|
||||
final int firstLoadPosition = computeInitialLoadPosition(params, totalCount);
|
||||
final int firstLoadSize = computeInitialLoadSize(params, firstLoadPosition, totalCount);
|
||||
|
||||
// convert from legacy behavior
|
||||
List<Task> list = loadRange(firstLoadPosition, firstLoadSize);
|
||||
if (list != null && list.size() == firstLoadSize) {
|
||||
callback.onResult(list, firstLoadPosition, totalCount);
|
||||
} else {
|
||||
// null list, or size doesn't match request
|
||||
// The size check is a WAR for Room 1.0, subsequent versions do the check in Room
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@Override
|
||||
public void loadRange(@NonNull LoadRangeParams params,
|
||||
@NonNull LoadRangeCallback<Task> callback) {
|
||||
List<Task> list = loadRange(params.startPosition, params.loadSize);
|
||||
if (list != null) {
|
||||
callback.onResult(list);
|
||||
} else {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue