updated ObjectCursor

This commit is contained in:
Mariotaku Lee 2017-03-05 16:08:09 +08:00
parent 7310f10cc5
commit a59035ed55
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
42 changed files with 332 additions and 243 deletions

5
.gitignore vendored
View File

@ -28,4 +28,7 @@ Thumbs.db
/private /private
# Local files # Local files
/captures /captures
# JRE error dumps
hs_err_*.log

View File

@ -37,7 +37,7 @@ subprojects {
SupportLib : '25.2.0', SupportLib : '25.2.0',
MariotakuCommons: '0.9.11', MariotakuCommons: '0.9.11',
RestFu : '0.9.35', RestFu : '0.9.35',
ObjectCursor : '0.9.13', ObjectCursor : '0.9.16',
PlayServices : '10.2.0', PlayServices : '10.2.0',
MapsUtils : '0.4.4', MapsUtils : '0.4.4',
Crashlyrics : '2.6.6', Crashlyrics : '2.6.6',

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.extension package org.mariotaku.twidere.extension
import android.support.test.runner.AndroidJUnit4 import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
/** /**
@ -28,4 +29,9 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class ViewExtensionsKtTest { class ViewExtensionsKtTest {
@Test
fun testEmpty() {
}
} }

View File

@ -0,0 +1,47 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program 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.
*
* This program 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.mariotaku.twidere.util
import android.database.MatrixCursor
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.ParcelableStatus
/**
* Created by mariotaku on 2017/3/5.
*/
@RunWith(AndroidJUnit4::class)
class ObjectCursorTest {
@Test
fun testSimple() {
val cur = MatrixCursor(emptyArray(), 0)
ObjectCursor.indicesFrom(cur, ParcelableStatus::class.java)
}
@Test
fun testMemberClass() {
val cur = MatrixCursor(emptyArray(), 0)
ObjectCursor.indicesFrom(cur, FiltersData.BaseItem::class.java)
}
}

View File

@ -22,7 +22,6 @@ package org.mariotaku.twidere.loader;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import org.mariotaku.library.objectcursor.ObjectCursor;
import org.mariotaku.twidere.loader.iface.IExtendedLoader; import org.mariotaku.twidere.loader.iface.IExtendedLoader;
/** /**
@ -30,9 +29,8 @@ import org.mariotaku.twidere.loader.iface.IExtendedLoader;
*/ */
public class ExtendedObjectCursorLoader<E> extends ObjectCursorLoader<E> implements IExtendedLoader { public class ExtendedObjectCursorLoader<E> extends ObjectCursorLoader<E> implements IExtendedLoader {
public ExtendedObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<E>> indicesClass, public ExtendedObjectCursorLoader(Context context, Class<E> indicesClass, Uri uri,
Uri uri, String[] projection, String selection, String[] selectionArgs, String[] projection, String selection, String[] selectionArgs, String sortOrder, boolean fromUser) {
String sortOrder, boolean fromUser) {
super(context, indicesClass, uri, projection, selection, selectionArgs, sortOrder); super(context, indicesClass, uri, projection, selection, selectionArgs, sortOrder);
setFromUser(fromUser); setFromUser(fromUser);
} }

View File

@ -30,7 +30,6 @@ import org.mariotaku.library.objectcursor.ObjectCursor;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -40,7 +39,7 @@ import java.util.List;
public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> { public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> {
final ForceLoadContentObserver mObserver; final ForceLoadContentObserver mObserver;
final Class<? extends ObjectCursor.CursorIndices<T>> mIndicesClass; final Class<T> mObjectClass;
Uri mUri; Uri mUri;
String[] mProjection; String[] mProjection;
@ -71,17 +70,7 @@ public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> {
@SuppressWarnings("TryWithIdenticalCatches") @SuppressWarnings("TryWithIdenticalCatches")
@NonNull @NonNull
private ObjectCursor.CursorIndices<T> createIndices(final Cursor cursor) { private ObjectCursor.CursorIndices<T> createIndices(final Cursor cursor) {
try { return ObjectCursor.indicesFrom(cursor, mObjectClass);
return mIndicesClass.getConstructor(Cursor.class).newInstance(cursor);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
} }
/* Runs on the UI thread */ /* Runs on the UI thread */
@ -112,9 +101,9 @@ public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> {
* calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc * calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc
* to specify the query to perform. * to specify the query to perform.
*/ */
public ObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<T>> indicesClass) { public ObjectCursorLoader(Context context, Class<T> objectClass) {
super(context); super(context);
mIndicesClass = indicesClass; mObjectClass = objectClass;
mObserver = new ForceLoadContentObserver(); mObserver = new ForceLoadContentObserver();
} }
@ -124,11 +113,10 @@ public class ObjectCursorLoader<T> extends FixedAsyncTaskLoader<List<T>> {
* ContentResolver.query()} for documentation on the meaning of the * ContentResolver.query()} for documentation on the meaning of the
* parameters. These will be passed as-is to that call. * parameters. These will be passed as-is to that call.
*/ */
public ObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<T>> indicesClass, public ObjectCursorLoader(Context context, Class<T> objectClass, Uri uri, String[] projection,
Uri uri, String[] projection, String selection, String selection, String[] selectionArgs, String sortOrder) {
String[] selectionArgs, String sortOrder) {
super(context); super(context);
mIndicesClass = indicesClass; mObjectClass = objectClass;
mObserver = new ForceLoadContentObserver(); mObserver = new ForceLoadContentObserver();
mUri = uri; mUri = uri;
mProjection = projection; mProjection = projection;

View File

@ -43,13 +43,7 @@ import org.mariotaku.twidere.annotation.Preference;
import org.mariotaku.twidere.annotation.PreferenceType; import org.mariotaku.twidere.annotation.PreferenceType;
import org.mariotaku.twidere.constant.SharedPreferenceConstants; import org.mariotaku.twidere.constant.SharedPreferenceConstants;
import org.mariotaku.twidere.model.FiltersData; import org.mariotaku.twidere.model.FiltersData;
import org.mariotaku.twidere.model.FiltersData$BaseItemCursorIndices;
import org.mariotaku.twidere.model.FiltersData$BaseItemValuesCreator;
import org.mariotaku.twidere.model.FiltersData$UserItemCursorIndices;
import org.mariotaku.twidere.model.FiltersData$UserItemValuesCreator;
import org.mariotaku.twidere.model.Tab; import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.TabCursorIndices;
import org.mariotaku.twidere.model.TabValuesCreator;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters; import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs; import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
import org.mariotaku.twidere.util.content.ContentResolverUtils; import org.mariotaku.twidere.util.content.ContentResolverUtils;
@ -115,13 +109,13 @@ public class DataImportExportUtils implements Constants {
final ContentResolver cr = context.getContentResolver(); final ContentResolver cr = context.getContentResolver();
data.setUsers(queryAll(cr, Filters.Users.CONTENT_URI, Filters.Users.COLUMNS, data.setUsers(queryAll(cr, Filters.Users.CONTENT_URI, Filters.Users.COLUMNS,
FiltersData$UserItemCursorIndices.class)); FiltersData.UserItem.class));
data.setKeywords(queryAll(cr, Filters.Keywords.CONTENT_URI, Filters.Keywords.COLUMNS, data.setKeywords(queryAll(cr, Filters.Keywords.CONTENT_URI, Filters.Keywords.COLUMNS,
FiltersData$BaseItemCursorIndices.class)); FiltersData.BaseItem.class));
data.setSources(queryAll(cr, Filters.Sources.CONTENT_URI, Filters.Sources.COLUMNS, data.setSources(queryAll(cr, Filters.Sources.CONTENT_URI, Filters.Sources.COLUMNS,
FiltersData$BaseItemCursorIndices.class)); FiltersData.BaseItem.class));
data.setLinks(queryAll(cr, Filters.Links.CONTENT_URI, Filters.Links.COLUMNS, data.setLinks(queryAll(cr, Filters.Links.CONTENT_URI, Filters.Links.COLUMNS,
FiltersData$BaseItemCursorIndices.class)); FiltersData.BaseItem.class));
exportItem(zos, ENTRY_FILTERS, FiltersData.class, data); exportItem(zos, ENTRY_FILTERS, FiltersData.class, data);
} }
if (hasFlag(flags, FLAG_TABS)) { if (hasFlag(flags, FLAG_TABS)) {
@ -131,7 +125,7 @@ public class DataImportExportUtils implements Constants {
if (c != null) { if (c != null) {
final List<Tab> tabs = new ArrayList<>(c.getCount()); final List<Tab> tabs = new ArrayList<>(c.getCount());
try { try {
TabCursorIndices ci = new TabCursorIndices(c); final ObjectCursor.CursorIndices<Tab> ci = ObjectCursor.indicesFrom(c, Tab.class);
c.moveToFirst(); c.moveToFirst();
while (!c.isAfterLast()) { while (!c.isAfterLast()) {
tabs.add(ci.newObject(c)); tabs.add(ci.newObject(c));
@ -152,16 +146,11 @@ public class DataImportExportUtils implements Constants {
} }
private static <T> List<T> queryAll(ContentResolver cr, Uri uri, String[] projection, private static <T> List<T> queryAll(ContentResolver cr, Uri uri, String[] projection,
Class<? extends ObjectCursor.CursorIndices<T>> cls) throws IOException { Class<T> cls) throws IOException {
Cursor c = cr.query(uri, projection, null, null, null); Cursor c = cr.query(uri, projection, null, null, null);
if (c == null) return null; if (c == null) return null;
try { try {
final ObjectCursor.CursorIndices<T> ci; final ObjectCursor.CursorIndices<T> ci = ObjectCursor.indicesFrom(c, cls);
try {
ci = cls.getConstructor(Cursor.class).newInstance(c);
} catch (Exception e) {
throw new RuntimeException(e);
}
List<T> items = new ArrayList<>(c.getCount()); List<T> items = new ArrayList<>(c.getCount());
c.moveToFirst(); c.moveToFirst();
while (!c.isAfterLast()) { while (!c.isAfterLast()) {
@ -252,31 +241,36 @@ public class DataImportExportUtils implements Constants {
void insertBase(ContentResolver cr, Uri uri, List<FiltersData.BaseItem> items) throws IOException { void insertBase(ContentResolver cr, Uri uri, List<FiltersData.BaseItem> items) throws IOException {
if (items == null) return; if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.BaseItem> baseItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem.class);
List<ContentValues> values = new ArrayList<>(items.size()); List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.BaseItem item : items) { for (FiltersData.BaseItem item : items) {
values.add(FiltersData$BaseItemValuesCreator.create(item)); values.add(baseItemCreator.create(item));
} }
ContentResolverUtils.bulkInsert(cr, uri, values); ContentResolverUtils.bulkInsert(cr, uri, values);
} }
void insertUser(ContentResolver cr, Uri uri, List<FiltersData.UserItem> items) throws IOException { void insertUser(ContentResolver cr, Uri uri, List<FiltersData.UserItem> items) throws IOException {
if (items == null) return; if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.UserItem> userItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.UserItem.class);
List<ContentValues> values = new ArrayList<>(items.size()); List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.UserItem item : items) { for (FiltersData.UserItem item : items) {
values.add(FiltersData$UserItemValuesCreator.create(item)); values.add(userItemCreator.create(item));
} }
ContentResolverUtils.bulkInsert(cr, uri, values); ContentResolverUtils.bulkInsert(cr, uri, values);
} }
}); });
} }
if (hasFlag(flags, FLAG_TABS)) { if (hasFlag(flags, FLAG_TABS)) {
final ObjectCursor.ValuesCreator<Tab> creator = ObjectCursor.valuesCreatorFrom(Tab.class);
importItemsList(context, zipFile, ENTRY_TABS, Tab.class, new ContentResolverProcessStrategy<List<Tab>>() { importItemsList(context, zipFile, ENTRY_TABS, Tab.class, new ContentResolverProcessStrategy<List<Tab>>() {
@Override @Override
public boolean importItem(ContentResolver cr, List<Tab> items) throws IOException { public boolean importItem(ContentResolver cr, List<Tab> items) throws IOException {
if (items == null) return false; if (items == null) return false;
List<ContentValues> values = new ArrayList<>(items.size()); List<ContentValues> values = new ArrayList<>(items.size());
for (Tab item : items) { for (Tab item : items) {
values.add(TabValuesCreator.create(item)); values.add(creator.create(item));
} }
cr.delete(Tabs.CONTENT_URI, null, null); cr.delete(Tabs.CONTENT_URI, null, null);
ContentResolverUtils.bulkInsert(cr, Tabs.CONTENT_URI, values); ContentResolverUtils.bulkInsert(cr, Tabs.CONTENT_URI, values);
@ -292,8 +286,8 @@ public class DataImportExportUtils implements Constants {
} }
private static void importSharedPreferencesData(@NonNull final ZipFile zipFile, @NonNull final Context context, private static void importSharedPreferencesData(@NonNull final ZipFile zipFile, @NonNull final Context context,
@NonNull final String preferencesName, @NonNull final String entryName, @NonNull final String preferencesName, @NonNull final String entryName,
@NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName); final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return; if (entry == null) return;
final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(zipFile.getInputStream(entry)); final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(zipFile.getInputStream(entry));
@ -314,8 +308,8 @@ public class DataImportExportUtils implements Constants {
} }
private static void exportSharedPreferencesData(@NonNull final ZipOutputStream zos, final Context context, private static void exportSharedPreferencesData(@NonNull final ZipOutputStream zos, final Context context,
@NonNull final String preferencesName, @NonNull final String entryName, @NonNull final String preferencesName, @NonNull final String entryName,
@NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException {
final SharedPreferences preferences = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE); final SharedPreferences preferences = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
final Map<String, ?> map = preferences.getAll(); final Map<String, ?> map = preferences.getAll();
zos.putNextEntry(new ZipEntry(entryName)); zos.putNextEntry(new ZipEntry(entryName));
@ -330,10 +324,10 @@ public class DataImportExportUtils implements Constants {
} }
private static <T> void importItemsList(@NonNull final Context context, private static <T> void importItemsList(@NonNull final Context context,
@NonNull final ZipFile zipFile, @NonNull final ZipFile zipFile,
@NonNull final String entryName, @NonNull final String entryName,
@NonNull final Class<T> itemCls, @NonNull final Class<T> itemCls,
@NonNull final ContentResolverProcessStrategy<List<T>> strategy) @NonNull final ContentResolverProcessStrategy<List<T>> strategy)
throws IOException { throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName); final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return; if (entry == null) return;
@ -344,9 +338,9 @@ public class DataImportExportUtils implements Constants {
private static <T> void exportItemsList(@NonNull final ZipOutputStream zos, private static <T> void exportItemsList(@NonNull final ZipOutputStream zos,
@NonNull final String entryName, @NonNull final String entryName,
@NonNull final Class<T> itemCls, @NonNull final Class<T> itemCls,
@NonNull final List<T> itemList) throws IOException { @NonNull final List<T> itemList) throws IOException {
zos.putNextEntry(new ZipEntry(entryName)); zos.putNextEntry(new ZipEntry(entryName));
final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos); final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos);
LoganSquareMapperFinder.mapperFor(itemCls).serialize(itemList, jsonGenerator); LoganSquareMapperFinder.mapperFor(itemCls).serialize(itemList, jsonGenerator);
@ -355,10 +349,10 @@ public class DataImportExportUtils implements Constants {
} }
private static <T> void importItem(@NonNull final Context context, private static <T> void importItem(@NonNull final Context context,
@NonNull final ZipFile zipFile, @NonNull final ZipFile zipFile,
@NonNull final String entryName, @NonNull final String entryName,
@NonNull final Class<T> itemCls, @NonNull final Class<T> itemCls,
@NonNull final ContentResolverProcessStrategy<T> strategy) @NonNull final ContentResolverProcessStrategy<T> strategy)
throws IOException { throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName); final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return; if (entry == null) return;
@ -369,9 +363,9 @@ public class DataImportExportUtils implements Constants {
private static <T> void exportItem(@NonNull final ZipOutputStream zos, private static <T> void exportItem(@NonNull final ZipOutputStream zos,
@NonNull final String entryName, @NonNull final String entryName,
@NonNull final Class<T> itemCls, @NonNull final Class<T> itemCls,
@NonNull final T item) throws IOException { @NonNull final T item) throws IOException {
zos.putNextEntry(new ZipEntry(entryName)); zos.putNextEntry(new ZipEntry(entryName));
final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos); final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos);
LoganSquareMapperFinder.mapperFor(itemCls).serialize(item, jsonGenerator, true); LoganSquareMapperFinder.mapperFor(itemCls).serialize(item, jsonGenerator, true);

View File

@ -64,6 +64,7 @@ import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.* import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.pickncrop.library.MediaPickerActivity import org.mariotaku.pickncrop.library.MediaPickerActivity
import org.mariotaku.twidere.Constants.* import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
@ -452,7 +453,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
this.inReplyToStatus = this@ComposeActivity.inReplyToStatus this.inReplyToStatus = this@ComposeActivity.inReplyToStatus
this.isPossiblySensitive = this@ComposeActivity.possiblySensitive this.isPossiblySensitive = this@ComposeActivity.possiblySensitive
} }
val values = DraftValuesCreator.create(draft) val values = ObjectCursor.valuesCreatorFrom(Draft::class.java).create(draft)
val draftUri = contentResolver.insert(Drafts.CONTENT_URI, values) val draftUri = contentResolver.insert(Drafts.CONTENT_URI, values)
displayNewDraftNotification(text, draftUri) displayNewDraftNotification(text, draftUri)
return draftUri return draftUri

View File

@ -82,16 +82,20 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
} }
} }
internal class ExportSettingsTask(private val activity: DataExportActivity, private val mPath: String?, private val mFlags: Int) : AsyncTask<Any, Any, Boolean>() { internal class ExportSettingsTask(
private val activity: DataExportActivity,
private val path: String?,
private val flags: Int
) : AsyncTask<Any, Any, Boolean>() {
override fun doInBackground(vararg params: Any): Boolean? { override fun doInBackground(vararg params: Any): Boolean? {
if (mPath == null) return false if (path == null) return false
val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US) val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US)
val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date())) val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date()))
val file = File(mPath, fileName) val file = File(path, fileName)
file.delete() file.delete()
try { try {
DataImportExportUtils.exportData(activity, file, mFlags) DataImportExportUtils.exportData(activity, file, flags)
return true return true
} catch (e: IOException) { } catch (e: IOException) {
Log.w(LOGTAG, e) Log.w(LOGTAG, e)

View File

@ -26,14 +26,16 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.bumptech.glide.RequestManager import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.mediaPreviewStyleKey import org.mariotaku.twidere.constant.mediaPreviewStyleKey
import org.mariotaku.twidere.extension.model.getActionName import org.mariotaku.twidere.extension.model.getActionName
import org.mariotaku.twidere.model.Draft import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.DraftCursorIndices
import org.mariotaku.twidere.model.draft.StatusObjectExtras import org.mariotaku.twidere.model.draft.StatusObjectExtras
import org.mariotaku.twidere.model.util.ParcelableMediaUtils import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.view.holder.DraftViewHolder import org.mariotaku.twidere.view.holder.DraftViewHolder
import javax.inject.Inject import javax.inject.Inject
@ -53,7 +55,7 @@ class DraftsAdapter(
field = value field = value
notifyDataSetChanged() notifyDataSetChanged()
} }
private var indices: DraftCursorIndices? = null private var indices: ObjectCursor.CursorIndices<Draft>? = null
init { init {
GeneralComponentHelper.build(context).inject(this) GeneralComponentHelper.build(context).inject(this)
@ -122,9 +124,7 @@ class DraftsAdapter(
override fun swapCursor(c: Cursor?): Cursor? { override fun swapCursor(c: Cursor?): Cursor? {
val old = super.swapCursor(c) val old = super.swapCursor(c)
if (c != null) { indices = c?.let { ObjectCursor.indicesFrom(it, Draft::class.java) }
indices = DraftCursorIndices(c)
}
return old return old
} }

View File

@ -29,6 +29,7 @@ import android.view.View
import android.widget.TextView import android.widget.TextView
import com.bumptech.glide.RequestManager import com.bumptech.glide.RequestManager
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.sqliteqb.library.OrderBy import org.mariotaku.sqliteqb.library.OrderBy
@ -36,10 +37,9 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.displayProfileImageKey import org.mariotaku.twidere.constant.displayProfileImageKey
import org.mariotaku.twidere.constant.profileImageStyleKey import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.extension.loadProfileImage import org.mariotaku.twidere.extension.loadProfileImage
import org.mariotaku.twidere.model.ParcelableUserCursorIndices import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.SharedPreferencesWrapper import org.mariotaku.twidere.util.SharedPreferencesWrapper
import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
@ -61,7 +61,7 @@ class UserAutoCompleteAdapter(
private val displayProfileImage: Boolean private val displayProfileImage: Boolean
private var profileImageStyle: Int private var profileImageStyle: Int
private var indices: ParcelableUserCursorIndices? = null private var indices: ObjectCursor.CursorIndices<ParcelableUser>? = null
var accountKey: UserKey? = null var accountKey: UserKey? = null
@ -79,11 +79,11 @@ class UserAutoCompleteAdapter(
icon.style = profileImageStyle icon.style = profileImageStyle
text1.text = userColorNameManager.getUserNickname(cursor.getString(indices.key), cursor.getString(indices.name)) text1.text = userColorNameManager.getUserNickname(cursor.getString(indices[CachedUsers.USER_KEY]), cursor.getString(indices[CachedUsers.NAME]))
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
text2.text = "@${cursor.getString(indices.screen_name)}" text2.text = "@${cursor.getString(indices[CachedUsers.SCREEN_NAME])}"
if (displayProfileImage) { if (displayProfileImage) {
val profileImageUrl = cursor.getString(indices.profile_image_url) val profileImageUrl = cursor.getString(indices[CachedUsers.PROFILE_IMAGE_URL])
requestManager.loadProfileImage(context, profileImageUrl, profileImageStyle).into(icon) requestManager.loadProfileImage(context, profileImageUrl, profileImageStyle).into(icon)
} else { } else {
//TODO cancel image load //TODO cancel image load
@ -101,7 +101,7 @@ class UserAutoCompleteAdapter(
} }
override fun convertToString(cursor: Cursor?): CharSequence { override fun convertToString(cursor: Cursor?): CharSequence {
return cursor!!.getString(indices!!.screen_name) return cursor!!.getString(indices!![CachedUsers.SCREEN_NAME])
} }
override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? { override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? {
@ -127,9 +127,7 @@ class UserAutoCompleteAdapter(
} }
override fun swapCursor(cursor: Cursor?): Cursor? { override fun swapCursor(cursor: Cursor?): Cursor? {
if (cursor != null) { indices = cursor?.let { ObjectCursor.indicesFrom(it, ParcelableUser::class.java) }
indices = ParcelableUserCursorIndices(cursor)
}
return super.swapCursor(cursor) return super.swapCursor(cursor)
} }

View File

@ -5,8 +5,10 @@ import android.net.Uri
import org.mariotaku.ktextension.addAllEnhanced import org.mariotaku.ktextension.addAllEnhanced
import org.mariotaku.ktextension.isNullOrEmpty import org.mariotaku.ktextension.isNullOrEmpty
import org.mariotaku.ktextension.map import org.mariotaku.ktextension.map
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.content.ContentResolverUtils
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
@ -24,7 +26,8 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) {
val c = cr.query(uri, Filters.COLUMNS, where, null, null) ?: return null val c = cr.query(uri, Filters.COLUMNS, where, null, null) ?: return null
@Suppress("ConvertTryFinallyToUseCall") @Suppress("ConvertTryFinallyToUseCall")
try { try {
return c.map(`FiltersData$BaseItemCursorIndices`(c)) val indices = ObjectCursor.indicesFrom(c, FiltersData.BaseItem::class.java)
return c.map(indices)
} finally { } finally {
c.close() c.close()
} }
@ -34,7 +37,8 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) {
val c = cr.query(Filters.Users.CONTENT_URI, Filters.Users.COLUMNS, where, null, null) ?: return@run null val c = cr.query(Filters.Users.CONTENT_URI, Filters.Users.COLUMNS, where, null, null) ?: return@run null
@Suppress("ConvertTryFinallyToUseCall") @Suppress("ConvertTryFinallyToUseCall")
try { try {
return@run c.map(`FiltersData$UserItemCursorIndices`(c)) val indices = ObjectCursor.indicesFrom(c, FiltersData.UserItem::class.java)
return@run c.map(indices)
} finally { } finally {
c.close() c.close()
} }
@ -45,33 +49,31 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) {
} }
fun FiltersData.write(cr: ContentResolver, deleteOld: Boolean = true) { fun FiltersData.write(cr: ContentResolver, deleteOld: Boolean = true) {
val baseCreator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java)
val userCreator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java)
if (users != null) { if (users != null) {
if (deleteOld) { if (deleteOld) {
cr.delete(Filters.Users.CONTENT_URI, null, null) cr.delete(Filters.Users.CONTENT_URI, null, null)
} }
ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, users.map(userCreator::create))
users.map(`FiltersData$UserItemValuesCreator`::create))
} }
if (keywords != null) { if (keywords != null) {
if (deleteOld) { if (deleteOld) {
cr.delete(Filters.Keywords.CONTENT_URI, null, null) cr.delete(Filters.Keywords.CONTENT_URI, null, null)
} }
ContentResolverUtils.bulkInsert(cr, Filters.Keywords.CONTENT_URI, ContentResolverUtils.bulkInsert(cr, Filters.Keywords.CONTENT_URI, keywords.map(baseCreator::create))
keywords.map(`FiltersData$BaseItemValuesCreator`::create))
} }
if (sources != null) { if (sources != null) {
if (deleteOld) { if (deleteOld) {
cr.delete(Filters.Sources.CONTENT_URI, null, null) cr.delete(Filters.Sources.CONTENT_URI, null, null)
} }
ContentResolverUtils.bulkInsert(cr, Filters.Sources.CONTENT_URI, ContentResolverUtils.bulkInsert(cr, Filters.Sources.CONTENT_URI, sources.map(baseCreator::create))
sources.map(`FiltersData$BaseItemValuesCreator`::create))
} }
if (links != null) { if (links != null) {
if (deleteOld) { if (deleteOld) {
cr.delete(Filters.Links.CONTENT_URI, null, null) cr.delete(Filters.Links.CONTENT_URI, null, null)
} }
ContentResolverUtils.bulkInsert(cr, Filters.Links.CONTENT_URI, ContentResolverUtils.bulkInsert(cr, Filters.Links.CONTENT_URI, links.map(baseCreator::create))
links.map(`FiltersData$BaseItemValuesCreator`::create))
} }
} }

View File

@ -339,7 +339,9 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() {
class CursorActivitiesLoader(context: Context, uri: Uri, projection: Array<String>, class CursorActivitiesLoader(context: Context, uri: Uri, projection: Array<String>,
selection: String, selectionArgs: Array<String>, selection: String, selectionArgs: Array<String>,
sortOrder: String, fromUser: Boolean) : ExtendedObjectCursorLoader<ParcelableActivity>(context, ParcelableActivityCursorIndices::class.java, uri, projection, selection, selectionArgs, sortOrder, fromUser) { sortOrder: String, fromUser: Boolean
) : ExtendedObjectCursorLoader<ParcelableActivity>(context, ParcelableActivity::class.java, uri,
projection, selection, selectionArgs, sortOrder, fromUser) {
override fun createObjectCursor(cursor: Cursor, indices: ObjectCursor.CursorIndices<ParcelableActivity>): ObjectCursor<ParcelableActivity> { override fun createObjectCursor(cursor: Cursor, indices: ObjectCursor.CursorIndices<ParcelableActivity>): ObjectCursor<ParcelableActivity> {
val filteredUserIds = DataStoreUtils.getFilteredUserIds(context) val filteredUserIds = DataStoreUtils.getFilteredUserIds(context)

View File

@ -43,7 +43,10 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.ParameterizedExpression
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.SimpleRefreshTaskParam
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.* import org.mariotaku.twidere.model.event.*
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
@ -98,8 +101,8 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
accountKeys[it].toString() accountKeys[it].toString()
} }
val expression = processWhere(where, selectionArgs) val expression = processWhere(where, selectionArgs)
return ExtendedObjectCursorLoader(context, ParcelableStatusCursorIndices::class.java, uri, return ExtendedObjectCursorLoader(context, ParcelableStatus::class.java, uri, projection,
projection, expression.sql, expression.parameters, sortOrder, fromUser) expression.sql, expression.parameters, sortOrder, fromUser)
} }
override fun createMessageBusCallback(): Any { override fun createMessageBusCallback(): Any {

View File

@ -47,6 +47,7 @@ import org.mariotaku.chameleon.Chameleon
import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.contains import org.mariotaku.ktextension.contains
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Columns.Column
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.sqliteqb.library.RawItemArray import org.mariotaku.sqliteqb.library.RawItemArray
@ -60,8 +61,6 @@ import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.Tab import org.mariotaku.twidere.model.Tab
import org.mariotaku.twidere.model.TabCursorIndices
import org.mariotaku.twidere.model.TabValuesCreator
import org.mariotaku.twidere.model.tab.DrawableHolder import org.mariotaku.twidere.model.tab.DrawableHolder
import org.mariotaku.twidere.model.tab.TabConfiguration import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.model.tab.iface.AccountCallback import org.mariotaku.twidere.model.tab.iface.AccountCallback
@ -378,14 +377,15 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
return@setOnClickListener return@setOnClickListener
} }
} }
val valuesCreator = ObjectCursor.valuesCreatorFrom(Tab::class.java)
when (tag) { when (tag) {
TAG_EDIT_TAB -> { TAG_EDIT_TAB -> {
val where = Expression.equalsArgs(Tabs._ID).sql val where = Expression.equalsArgs(Tabs._ID).sql
val whereArgs = arrayOf(tab.id.toString()) val whereArgs = arrayOf(tab.id.toString())
context.contentResolver.update(Tabs.CONTENT_URI, TabValuesCreator.create(tab), where, whereArgs) context.contentResolver.update(Tabs.CONTENT_URI, valuesCreator.create(tab), where, whereArgs)
} }
TAG_ADD_TAB -> { TAG_ADD_TAB -> {
context.contentResolver.insert(Tabs.CONTENT_URI, TabValuesCreator.create(tab)) context.contentResolver.insert(Tabs.CONTENT_URI, valuesCreator.create(tab))
} }
} }
SettingsActivity.setShouldRestart(activity) SettingsActivity.setShouldRestart(activity)
@ -473,7 +473,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
private val iconColor: Int = ThemeUtils.getThemeForegroundColor(context) private val iconColor: Int = ThemeUtils.getThemeForegroundColor(context)
private val tempTab: Tab = Tab() private val tempTab: Tab = Tab()
private var indices: TabCursorIndices? = null private var indices: ObjectCursor.CursorIndices<Tab>? = null
override fun bindView(view: View, context: Context?, cursor: Cursor) { override fun bindView(view: View, context: Context?, cursor: Cursor) {
super.bindView(view, context, cursor) super.bindView(view, context, cursor)
@ -504,9 +504,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, MultiChoice
} }
override fun changeCursor(cursor: Cursor?) { override fun changeCursor(cursor: Cursor?) {
if (cursor != null) { indices = cursor?.let { ObjectCursor.indicesFrom(it, Tab::class.java) }
indices = TabCursorIndices(cursor)
}
super.changeCursor(cursor) super.changeCursor(cursor)
} }

View File

@ -72,6 +72,7 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.applyFontFamily import org.mariotaku.ktextension.applyFontFamily
import org.mariotaku.ktextension.contains import org.mariotaku.ktextension.contains
import org.mariotaku.ktextension.findPositionByItemId import org.mariotaku.ktextension.findPositionByItemId
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.TranslationResult import org.mariotaku.microblog.library.twitter.model.TranslationResult
@ -2134,13 +2135,14 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
val pStatus = ParcelableStatusUtils.fromStatus(status, val pStatus = ParcelableStatusUtils.fromStatus(status,
accountKey, false) accountKey, false)
cr.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(pStatus)) cr.insert(CachedStatuses.CONTENT_URI, ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java).create(pStatus))
val activityCursor = cr.query(Activities.AboutMe.CONTENT_URI, val activityCursor = cr.query(Activities.AboutMe.CONTENT_URI,
Activities.COLUMNS, activityWhere.sql, statusWhereArgs, null)!! Activities.COLUMNS, activityWhere.sql, statusWhereArgs, null)!!
try { try {
activityCursor.moveToFirst() activityCursor.moveToFirst()
val ci = ParcelableActivityCursorIndices(activityCursor) val ci = ObjectCursor.indicesFrom(activityCursor, ParcelableActivity::class.java)
val vc = ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java)
while (!activityCursor.isAfterLast) { while (!activityCursor.isAfterLast) {
val activity = ci.newObject(activityCursor) val activity = ci.newObject(activityCursor)
val activityStatus = activity.getActivityStatus() val activityStatus = activity.getActivityStatus()
@ -2149,7 +2151,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
activityStatus.reply_count = activitySummary.replyCount activityStatus.reply_count = activitySummary.replyCount
activityStatus.retweet_count = activitySummary.retweetCount activityStatus.retweet_count = activitySummary.retweetCount
} }
cr.update(Activities.AboutMe.CONTENT_URI, ParcelableActivityValuesCreator.create(activity), cr.update(Activities.AboutMe.CONTENT_URI, vc.create(activity),
Expression.equals(Activities._ID, activity._id).sql, null) Expression.equals(Activities._ID, activity._id).sql, null)
activityCursor.moveToNext() activityCursor.moveToNext()
} }

View File

@ -83,6 +83,7 @@ import org.mariotaku.chameleon.Chameleon
import org.mariotaku.chameleon.ChameleonUtils import org.mariotaku.chameleon.ChameleonUtils
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.* import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate
@ -325,8 +326,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val resolver = context.applicationContext.contentResolver val resolver = context.applicationContext.contentResolver
task { task {
resolver.insert(CachedUsers.CONTENT_URI, ParcelableUserValuesCreator.create(user)) resolver.insert(CachedUsers.CONTENT_URI, ObjectCursor.valuesCreatorFrom(ParcelableUser::class.java).create(user))
resolver.insert(CachedRelationships.CONTENT_URI, ParcelableRelationshipValuesCreator.create(userRelationship)) resolver.insert(CachedRelationships.CONTENT_URI, ObjectCursor.valuesCreatorFrom(ParcelableRelationship::class.java).create(userRelationship))
} }
followContainer.follow.visibility = View.VISIBLE followContainer.follow.visibility = View.VISIBLE
} }
@ -1599,7 +1600,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val data = ParcelableRelationshipUtils.create(accountKey, userKey, relationship, val data = ParcelableRelationshipUtils.create(accountKey, userKey, relationship,
isFiltering) isFiltering)
val resolver = context.contentResolver val resolver = context.contentResolver
val values = ParcelableRelationshipValuesCreator.create(data) val values = ObjectCursor.valuesCreatorFrom(ParcelableRelationship::class.java).create(data)
resolver.insert(CachedRelationships.CONTENT_URI, values) resolver.insert(CachedRelationships.CONTENT_URI, values)
return SingleResponse.getInstance(data) return SingleResponse.getInstance(data)
} catch (e: MicroBlogException) { } catch (e: MicroBlogException) {

View File

@ -44,6 +44,7 @@ import android.widget.AbsListView.MultiChoiceModeListener
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_content_listview.* import kotlinx.android.synthetic.main.fragment_content_listview.*
import org.mariotaku.ktextension.setGroupAvailability import org.mariotaku.ktextension.setGroupAvailability
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
@ -56,7 +57,6 @@ import org.mariotaku.twidere.extension.*
import org.mariotaku.twidere.fragment.AbsContentListViewFragment import org.mariotaku.twidere.fragment.AbsContentListViewFragment
import org.mariotaku.twidere.fragment.BaseDialogFragment import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.FiltersData import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.`FiltersData$BaseItemCursorIndices`
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.text.style.EmojiSpan import org.mariotaku.twidere.text.style.EmojiSpan
import org.mariotaku.twidere.util.DataStoreUtils import org.mariotaku.twidere.util.DataStoreUtils
@ -331,15 +331,12 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null, ) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null,
emptyArray(), intArrayOf(), 0), SelectableItemAdapter { emptyArray(), intArrayOf(), 0), SelectableItemAdapter {
private var indices: `FiltersData$BaseItemCursorIndices`? = null private var indices: ObjectCursor.CursorIndices<FiltersData.BaseItem>? = null
private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context) private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context)
override fun swapCursor(c: Cursor?): Cursor? { override fun swapCursor(c: Cursor?): Cursor? {
val old = super.swapCursor(c) indices = c?.let { ObjectCursor.indicesFrom(it, FiltersData.BaseItem::class.java) }
if (c != null) { return super.swapCursor(c)
indices = `FiltersData$BaseItemCursorIndices`(c)
}
return old
} }
override fun bindView(view: View, context: Context, cursor: Cursor) { override fun bindView(view: View, context: Context, cursor: Cursor) {
@ -347,8 +344,8 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
val indices = this.indices!! val indices = this.indices!!
val text1 = view.findViewById(android.R.id.text1) as TextView val text1 = view.findViewById(android.R.id.text1) as TextView
val ssb = SpannableStringBuilder(cursor.getString(indices.value)) val ssb = SpannableStringBuilder(cursor.getString(indices[Filters.VALUE]))
if (cursor.getLong(indices.source) >= 0) { if (cursor.getLong(indices[Filters.SOURCE]) >= 0) {
val start = ssb.length val start = ssb.length
ssb.append("*") ssb.append("*")
val end = start + 1 val end = start + 1
@ -363,7 +360,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
override fun isSelectable(position: Int): Boolean { override fun isSelectable(position: Int): Boolean {
val cursor = this.cursor ?: return false val cursor = this.cursor ?: return false
if (cursor.moveToPosition(position)) { if (cursor.moveToPosition(position)) {
return cursor.getLong(indices!!.source) < 0 return cursor.getLong(indices!![Filters.SOURCE]) < 0
} }
return false return false
} }

View File

@ -20,6 +20,7 @@ import android.widget.TextView
import kotlinx.android.synthetic.main.fragment_content_listview.* import kotlinx.android.synthetic.main.fragment_content_listview.*
import org.mariotaku.kpreferences.KPreferences import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.AccountSelectorActivity import org.mariotaku.twidere.activity.AccountSelectorActivity
@ -29,9 +30,9 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_HOST
import org.mariotaku.twidere.constant.nameFirstKey import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.fragment.AddUserFilterDialogFragment import org.mariotaku.twidere.fragment.AddUserFilterDialogFragment
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.`FiltersData$UserItemCursorIndices`
import org.mariotaku.twidere.model.analyzer.PurchaseFinished import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.text.style.EmojiSpan import org.mariotaku.twidere.text.style.EmojiSpan
@ -165,7 +166,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
private val nameFirst: Boolean private val nameFirst: Boolean
private var indices: `FiltersData$UserItemCursorIndices`? = null private var indices: ObjectCursor.CursorIndices<FiltersData.UserItem>? = null
private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context) private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context)
init { init {
@ -182,15 +183,15 @@ class FilteredUsersFragment : BaseFiltersFragment() {
icon.visibility = View.GONE icon.visibility = View.GONE
val userId = UserKey.valueOf(cursor.getString(indices.userKey)) val userId = UserKey.valueOf(cursor.getString(indices[Filters.Users.USER_KEY]))
val name = cursor.getString(indices.name) val name = cursor.getString(indices[Filters.Users.NAME])
val screenName = cursor.getString(indices.screenName) val screenName = cursor.getString(indices[Filters.Users.SCREEN_NAME])
val displayName = userColorNameManager.getDisplayName(userId, name, screenName, val displayName = userColorNameManager.getDisplayName(userId, name, screenName,
nameFirst) nameFirst)
text1.text = displayName text1.text = displayName
val ssb = SpannableStringBuilder(displayName) val ssb = SpannableStringBuilder(displayName)
if (cursor.getLong(indices.source) >= 0) { if (cursor.getLong(indices[Filters.Users.SOURCE]) >= 0) {
val start = ssb.length val start = ssb.length
ssb.append("*") ssb.append("*")
val end = start + 1 val end = start + 1
@ -203,17 +204,14 @@ class FilteredUsersFragment : BaseFiltersFragment() {
} }
override fun swapCursor(c: Cursor?): Cursor? { override fun swapCursor(c: Cursor?): Cursor? {
val old = super.swapCursor(c) indices = c?.let { ObjectCursor.indicesFrom(it, FiltersData.UserItem::class.java) }
if (c != null) { return super.swapCursor(c)
indices = `FiltersData$UserItemCursorIndices`(c)
}
return old
} }
override fun isSelectable(position: Int): Boolean { override fun isSelectable(position: Int): Boolean {
val cursor = this.cursor ?: return false val cursor = this.cursor ?: return false
if (cursor.moveToPosition(position)) { if (cursor.moveToPosition(position)) {
return cursor.getLong(indices!!.source) < 0 return cursor.getLong(indices!![Filters.Users.SOURCE]) < 0
} }
return false return false
} }
@ -221,7 +219,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
fun getUserKeyString(position: Int): String? { fun getUserKeyString(position: Int): String? {
val cursor = this.cursor ?: return null val cursor = this.cursor ?: return null
if (cursor.moveToPosition(position)) { if (cursor.moveToPosition(position)) {
return cursor.getString(indices!!.userKey) return cursor.getString(indices!![Filters.Users.USER_KEY])
} }
return null return null
} }

View File

@ -23,6 +23,7 @@ import kotlinx.android.synthetic.main.layout_list_with_empty_view.*
import okhttp3.HttpUrl import okhttp3.HttpUrl
import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.ktextension.* import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.REQUEST_PURCHASE_EXTRA_FEATURES import org.mariotaku.twidere.TwidereConstants.REQUEST_PURCHASE_EXTRA_FEATURES
@ -37,8 +38,6 @@ import org.mariotaku.twidere.fragment.BaseFragment
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.FiltersSubscription import org.mariotaku.twidere.model.FiltersSubscription
import org.mariotaku.twidere.model.FiltersSubscriptionCursorIndices
import org.mariotaku.twidere.model.FiltersSubscriptionValuesCreator
import org.mariotaku.twidere.model.analyzer.PurchaseFinished import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask
@ -229,7 +228,7 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac
val whereArgs = ids.toStringArray() val whereArgs = ids.toStringArray()
resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, where, resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, where,
whereArgs, null)?.useCursor { cursor -> whereArgs, null)?.useCursor { cursor ->
val indices = FiltersSubscriptionCursorIndices(cursor) val indices = ObjectCursor.indicesFrom(cursor, FiltersSubscription::class.java)
cursor.moveToFirst() cursor.moveToFirst()
while (!cursor.isAfterLast) { while (!cursor.isAfterLast) {
val subscription = indices.newObject(cursor) val subscription = indices.newObject(cursor)
@ -261,11 +260,11 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac
class FilterSubscriptionsAdapter(context: Context) : SimpleCursorAdapter(context, class FilterSubscriptionsAdapter(context: Context) : SimpleCursorAdapter(context,
R.layout.list_item_two_line, null, arrayOf(Filters.Subscriptions.NAME), R.layout.list_item_two_line, null, arrayOf(Filters.Subscriptions.NAME),
intArrayOf(android.R.id.text1), 0) { intArrayOf(android.R.id.text1), 0) {
private var indices: FiltersSubscriptionCursorIndices? = null private var indices: ObjectCursor.CursorIndices<FiltersSubscription>? = null
private var tempObject: FiltersSubscription = FiltersSubscription() private var tempObject: FiltersSubscription = FiltersSubscription()
override fun swapCursor(c: Cursor?): Cursor? { override fun swapCursor(c: Cursor?): Cursor? {
indices = if (c != null) FiltersSubscriptionCursorIndices(c) else null indices = c?.let { ObjectCursor.indicesFrom(it, FiltersSubscription::class.java) }
return super.swapCursor(c) return super.swapCursor(c)
} }
@ -295,7 +294,8 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac
subscription.setupUrl(editUrl.text.toString()) subscription.setupUrl(editUrl.text.toString())
val component = subscription.instantiateComponent(context) ?: return@setPositiveButton val component = subscription.instantiateComponent(context) ?: return@setPositiveButton
component.firstAdded() component.firstAdded()
context.contentResolver.insert(Filters.Subscriptions.CONTENT_URI, FiltersSubscriptionValuesCreator.create(subscription)) val vc = ObjectCursor.valuesCreatorFrom(FiltersSubscription::class.java)
context.contentResolver.insert(Filters.Subscriptions.CONTENT_URI, vc.create(subscription))
} }
builder.setNegativeButton(android.R.string.cancel, null) builder.setNegativeButton(android.R.string.cancel, null)
val dialog = builder.create() val dialog = builder.create()

View File

@ -57,6 +57,7 @@ import org.mariotaku.chameleon.ChameleonUtils
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.ktextension.useCursor import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.TwitterUpload import org.mariotaku.microblog.library.twitter.TwitterUpload
@ -455,7 +456,8 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where,
whereArgs, null).useCursor { cur -> whereArgs, null).useCursor { cur ->
if (cur.moveToFirst()) { if (cur.moveToFirst()) {
return ParcelableMessageConversationCursorIndices.fromCursor(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java)
return indices.newObject(cur)
} }
} }
return null return null

View File

@ -40,6 +40,7 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SelectableUsersAdapter import org.mariotaku.twidere.adapter.SelectableUsersAdapter
@ -48,8 +49,10 @@ import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.fragment.BaseFragment import org.mariotaku.twidere.fragment.BaseFragment
import org.mariotaku.twidere.loader.CacheUserSearchLoader import org.mariotaku.twidere.loader.CacheUserSearchLoader
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
import org.mariotaku.twidere.task.twitter.message.SendMessageTask import org.mariotaku.twidere.task.twitter.message.SendMessageTask
@ -247,7 +250,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks<List<Parc
} }
} }
val values = ParcelableMessageConversationValuesCreator.create(conversation) val values = ObjectCursor.valuesCreatorFrom(ParcelableMessageConversation::class.java).create(conversation)
context.contentResolver.insert(Conversations.CONTENT_URI, values) context.contentResolver.insert(Conversations.CONTENT_URI, values)
activity.startActivity(IntentUtils.messageConversation(accountKey, conversation.id)) activity.startActivity(IntentUtils.messageConversation(accountKey, conversation.id))
activity.finish() activity.finish()
@ -301,7 +304,8 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks<List<Parc
val cur = resolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null) ?: return null val cur = resolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null) ?: return null
try { try {
if (cur.moveToFirst()) { if (cur.moveToFirst()) {
return ParcelableMessageConversationCursorIndices.fromCursor(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java)
return indices.newObject(cur)
} }
} finally { } finally {
cur.close() cur.close()

View File

@ -535,7 +535,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
context: Context, context: Context,
val accountKey: UserKey, val accountKey: UserKey,
val conversationId: String val conversationId: String
) : ObjectCursorLoader<ParcelableMessage>(context, ParcelableMessageCursorIndices::class.java) { ) : ObjectCursorLoader<ParcelableMessage>(context, ParcelableMessage::class.java) {
private val atomicConversation = AtomicReference<ParcelableMessageConversation?>() private val atomicConversation = AtomicReference<ParcelableMessageConversation?>()
val conversation: ParcelableMessageConversation? get() = atomicConversation.get() val conversation: ParcelableMessageConversation? get() = atomicConversation.get()

View File

@ -44,7 +44,6 @@ import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment
import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment.ActionInfo import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment.ActionInfo
import org.mariotaku.twidere.loader.ObjectCursorLoader import org.mariotaku.twidere.loader.ObjectCursorLoader
import org.mariotaku.twidere.model.ParcelableMessageConversation import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.model.ParcelableMessageConversationCursorIndices
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
import org.mariotaku.twidere.provider.TwidereDataStore.Messages import org.mariotaku.twidere.provider.TwidereDataStore.Messages
@ -84,7 +83,7 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
} }
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ParcelableMessageConversation>?> { override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<ParcelableMessageConversation>?> {
val loader = ObjectCursorLoader(context, ParcelableMessageConversationCursorIndices::class.java) val loader = ObjectCursorLoader(context, ParcelableMessageConversation::class.java)
val projection = (Conversations.COLUMNS + Conversations.UNREAD_COUNT).map { val projection = (Conversations.COLUMNS + Conversations.UNREAD_COUNT).map {
TwidereQueryBuilder.mapConversationsProjection(it) TwidereQueryBuilder.mapConversationsProjection(it)
}.toTypedArray() }.toTypedArray()

View File

@ -1,13 +1,13 @@
package org.mariotaku.twidere.loader package org.mariotaku.twidere.loader
import android.content.Context import android.content.Context
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.microblog.library.twitter.model.User
import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.ParcelableUserCursorIndices
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.UserColorNameManager
@ -47,10 +47,10 @@ class CacheUserSearchLoader(
val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys) val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys)
val c = context.contentResolver.query(CachedUsers.CONTENT_URI, CachedUsers.BASIC_COLUMNS, val c = context.contentResolver.query(CachedUsers.CONTENT_URI, CachedUsers.BASIC_COLUMNS,
selection.sql, selectionArgs, null)!! selection.sql, selectionArgs, null)!!
val i = ParcelableUserCursorIndices(c) val i = ObjectCursor.indicesFrom(c, ParcelableUser::class.java)
c.moveToFirst() c.moveToFirst()
while (!c.isAfterLast) { while (!c.isAfterLast) {
if (list.none { it.key.toString() == c.getString(i.key) }) { if (list.none { it.key.toString() == c.getString(i[CachedUsers.USER_KEY]) }) {
list.add(i.newObject(c)) list.add(i.newObject(c))
} }
c.moveToNext() c.moveToNext()

View File

@ -27,6 +27,7 @@ import android.text.TextUtils
import android.util.Log import android.util.Log
import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.microblog.library.twitter.model.User
@ -38,13 +39,16 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableUserUtils import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.model.util.UserKeyUtils import org.mariotaku.twidere.model.util.UserKeyUtils
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.task.UpdateAccountInfoTask import org.mariotaku.twidere.task.UpdateAccountInfoTask
import org.mariotaku.twidere.util.ContentValuesCreator.createCachedUser import org.mariotaku.twidere.util.ContentValuesCreator
import org.mariotaku.twidere.util.TwitterWrapper import org.mariotaku.twidere.util.TwitterWrapper
import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
@ -85,7 +89,7 @@ class ParcelableUserLoader(
if (!omitIntentExtra && extras != null) { if (!omitIntentExtra && extras != null) {
val user = extras.getParcelable<ParcelableUser>(EXTRA_USER) val user = extras.getParcelable<ParcelableUser>(EXTRA_USER)
if (user != null) { if (user != null) {
val values = ParcelableUserValuesCreator.create(user) val values = ObjectCursor.valuesCreatorFrom(ParcelableUser::class.java).create(user)
resolver.insert(CachedUsers.CONTENT_URI, values) resolver.insert(CachedUsers.CONTENT_URI, values)
ParcelableUserUtils.updateExtraInformation(user, details, userColorNameManager) ParcelableUserUtils.updateExtraInformation(user, details, userColorNameManager)
return SingleResponse(user).apply { return SingleResponse(user).apply {
@ -118,7 +122,7 @@ class ParcelableUserLoader(
whereArgs, null)?.let { cur -> whereArgs, null)?.let { cur ->
try { try {
cur.moveToFirst() cur.moveToFirst()
val indices = ParcelableUserCursorIndices(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableUser::class.java)
while (!cur.isAfterLast) { while (!cur.isAfterLast) {
val user = indices.newObject(cur) val user = indices.newObject(cur)
if (TextUtils.equals(UserKeyUtils.getUserHost(user), user.key.host)) { if (TextUtils.equals(UserKeyUtils.getUserHost(user), user.key.host)) {
@ -152,7 +156,7 @@ class ParcelableUserLoader(
twitterUser = TwitterWrapper.tryShowUser(twitter, id, screenName, details.type) twitterUser = TwitterWrapper.tryShowUser(twitter, id, screenName, details.type)
} }
} }
val cachedUserValues = createCachedUser(twitterUser, profileImageSize) val cachedUserValues = ContentValuesCreator.createCachedUser(twitterUser, profileImageSize)
resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues) resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues)
val user = ParcelableUserUtils.fromUser(twitterUser, accountKey, val user = ParcelableUserUtils.fromUser(twitterUser, accountKey,
profileImageSize = profileImageSize) profileImageSize = profileImageSize)

View File

@ -41,6 +41,7 @@ import okhttp3.Dns
import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.ArrayUtils
import org.mariotaku.ktextension.isNullOrEmpty import org.mariotaku.ktextension.isNullOrEmpty
import org.mariotaku.ktextension.toNulls import org.mariotaku.ktextension.toNulls
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Columns.Column
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.sqliteqb.library.RawItemArray import org.mariotaku.sqliteqb.library.RawItemArray
@ -52,7 +53,6 @@ import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.app.TwidereApplication import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.model.AccountPreferences import org.mariotaku.twidere.model.AccountPreferences
import org.mariotaku.twidere.model.Draft import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.DraftCursorIndices
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.*
@ -360,7 +360,7 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback {
val draftId = values.getAsLong(BaseColumns._ID) ?: return -1 val draftId = values.getAsLong(BaseColumns._ID) ?: return -1
val where = Expression.equals(Drafts._ID, draftId) val where = Expression.equals(Drafts._ID, draftId)
val c = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null) ?: return -1 val c = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null) ?: return -1
val i = DraftCursorIndices(c) val i = ObjectCursor.indicesFrom(c, Draft::class.java)
val item: Draft val item: Draft
try { try {
if (!c.moveToFirst()) return -1 if (!c.moveToFirst()) return -1

View File

@ -47,6 +47,7 @@ import org.mariotaku.ktextension.configure
import org.mariotaku.ktextension.toLong import org.mariotaku.ktextension.toLong
import org.mariotaku.ktextension.toTypedArray import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.ktextension.useCursor import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.TwitterUpload import org.mariotaku.microblog.library.twitter.TwitterUpload
import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse
@ -121,7 +122,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
val where = Expression.equals(Drafts._ID, draftId) val where = Expression.equals(Drafts._ID, draftId)
@SuppressLint("Recycle") @SuppressLint("Recycle")
val draft: Draft = contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null)?.useCursor { val draft: Draft = contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null)?.useCursor {
val i = DraftCursorIndices(it) val i = ObjectCursor.indicesFrom(it, Draft::class.java)
if (!it.moveToFirst()) return@useCursor null if (!it.moveToFirst()) return@useCursor null
return@useCursor i.newObject(it) return@useCursor i.newObject(it)
} ?: return } ?: return

View File

@ -8,11 +8,15 @@ import android.content.Context
import android.support.v4.util.LongSparseArray import android.support.v4.util.LongSparseArray
import android.text.TextUtils import android.text.TextUtils
import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE
import org.mariotaku.twidere.extension.model.setAccountKey import org.mariotaku.twidere.extension.model.setAccountKey
import org.mariotaku.twidere.extension.model.setAccountUser import org.mariotaku.twidere.extension.model.setAccountUser
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.Tab
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.*
import java.io.IOException import java.io.IOException
@ -57,7 +61,8 @@ class UpdateAccountInfoTask(
private fun updateTabs(resolver: ContentResolver, accountKey: UserKey) { private fun updateTabs(resolver: ContentResolver, accountKey: UserKey) {
val tabsCursor = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, null) ?: return val tabsCursor = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, null) ?: return
try { try {
val indices = TabCursorIndices(tabsCursor) val indices = ObjectCursor.indicesFrom(tabsCursor, Tab::class.java)
val creator = ObjectCursor.valuesCreatorFrom(Tab::class.java)
tabsCursor.moveToFirst() tabsCursor.moveToFirst()
val values = LongSparseArray<ContentValues>() val values = LongSparseArray<ContentValues>()
while (!tabsCursor.isAfterLast) { while (!tabsCursor.isAfterLast) {
@ -68,7 +73,7 @@ class UpdateAccountInfoTask(
val keys = arguments.accountKeys val keys = arguments.accountKeys
if (TextUtils.equals(accountKey.id, accountId) && keys == null) { if (TextUtils.equals(accountKey.id, accountId) && keys == null) {
arguments.accountKeys = arrayOf(accountKey) arguments.accountKeys = arrayOf(accountKey)
values.put(tab.id, TabValuesCreator.create(tab)) values.put(tab.id, creator.create(tab))
} }
} }
tabsCursor.moveToNext() tabsCursor.moveToNext()

View File

@ -6,12 +6,11 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.ktextension.useCursor import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.extension.model.instantiateComponent import org.mariotaku.twidere.extension.model.instantiateComponent
import org.mariotaku.twidere.model.FiltersData import org.mariotaku.twidere.model.FiltersData
import org.mariotaku.twidere.model.FiltersSubscriptionCursorIndices import org.mariotaku.twidere.model.FiltersSubscription
import org.mariotaku.twidere.model.`FiltersData$BaseItemValuesCreator`
import org.mariotaku.twidere.model.`FiltersData$UserItemValuesCreator`
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.content.ContentResolverUtils
@ -26,7 +25,7 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask<Unit?
val resolver = context.contentResolver val resolver = context.contentResolver
val sourceIds = ArrayList<Long>() val sourceIds = ArrayList<Long>()
resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, null, null, null)?.useCursor { cursor -> resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, null, null, null)?.useCursor { cursor ->
val indices = FiltersSubscriptionCursorIndices(cursor) val indices = ObjectCursor.indicesFrom(cursor, FiltersSubscription::class.java)
cursor.moveToFirst() cursor.moveToFirst()
while (!cursor.isAfterLast) { while (!cursor.isAfterLast) {
val subscription = indices.newObject(cursor) val subscription = indices.newObject(cursor)
@ -72,9 +71,10 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask<Unit?
private fun updateUserItems(resolver: ContentResolver, items: List<FiltersData.UserItem>?, sourceId: Long) { private fun updateUserItems(resolver: ContentResolver, items: List<FiltersData.UserItem>?, sourceId: Long) {
resolver.delete(Filters.Users.CONTENT_URI, Expression.equalsArgs(Filters.Users.SOURCE).sql, resolver.delete(Filters.Users.CONTENT_URI, Expression.equalsArgs(Filters.Users.SOURCE).sql,
arrayOf(sourceId.toString())) arrayOf(sourceId.toString()))
val creator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java)
items?.map { item -> items?.map { item ->
item.source = sourceId item.source = sourceId
return@map `FiltersData$UserItemValuesCreator`.create(item) return@map creator.create(item)
}?.let { items -> }?.let { items ->
ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, items) ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, items)
} }
@ -83,9 +83,10 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask<Unit?
private fun updateBaseItems(resolver: ContentResolver, items: List<FiltersData.BaseItem>?, uri: Uri, sourceId: Long) { private fun updateBaseItems(resolver: ContentResolver, items: List<FiltersData.BaseItem>?, uri: Uri, sourceId: Long) {
resolver.delete(uri, Expression.equalsArgs(Filters.SOURCE).sql, resolver.delete(uri, Expression.equalsArgs(Filters.SOURCE).sql,
arrayOf(sourceId.toString())) arrayOf(sourceId.toString()))
val creator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java)
items?.map { item -> items?.map { item ->
item.source = sourceId item.source = sourceId
return@map `FiltersData$BaseItemValuesCreator`.create(item) return@map creator.create(item)
}?.let { items -> }?.let { items ->
ContentResolverUtils.bulkInsert(resolver, uri, items) ContentResolverUtils.bulkInsert(resolver, uri, items)
} }

View File

@ -10,6 +10,7 @@ import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.math.NumberUtils import org.apache.commons.lang3.math.NumberUtils
import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.Paging
@ -23,7 +24,7 @@ import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_NOTIFY_CHANGE
import org.mariotaku.twidere.constant.loadItemLimitKey import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatusValuesCreator import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.RefreshTaskParam import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetStatusesTaskEvent import org.mariotaku.twidere.model.event.GetStatusesTaskEvent
@ -165,6 +166,7 @@ abstract class GetStatusesTask(
// Get id diff of first and last item // Get id diff of first and last item
val sortDiff = firstSortId - lastSortId val sortDiff = firstSortId - lastSortId
val creator = ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java)
for (i in 0 until statuses.size) { for (i in 0 until statuses.size) {
val item = statuses[i] val item = statuses[i]
val status = ParcelableStatusUtils.fromStatus(item, accountKey, false, profileImageSize) val status = ParcelableStatusUtils.fromStatus(item, accountKey, false, profileImageSize)
@ -173,7 +175,7 @@ abstract class GetStatusesTask(
sortDiff, i, statuses.size) sortDiff, i, statuses.size)
status.inserted_date = System.currentTimeMillis() status.inserted_date = System.currentTimeMillis()
mediaLoader.preloadStatus(status) mediaLoader.preloadStatus(status)
values[i] = ParcelableStatusValuesCreator.create(status) values[i] = creator.create(status)
if (minIdx == -1 || item < statuses[minIdx]) { if (minIdx == -1 || item < statuses[minIdx]) {
minIdx = i minIdx = i
minPositionKey = status.position_key minPositionKey = status.position_key

View File

@ -25,64 +25,66 @@ import android.content.ContentValues
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.support.v4.util.ArraySet import android.support.v4.util.ArraySet
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Trends import org.mariotaku.microblog.library.twitter.model.Trends
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression.and
import org.mariotaku.sqliteqb.library.Expression.equalsArgs
import org.mariotaku.twidere.TwidereConstants.LOGTAG import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType.FANFOU
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.ParcelableTrend import org.mariotaku.twidere.model.ParcelableTrend
import org.mariotaku.twidere.model.ParcelableTrendValuesCreator
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.TrendsRefreshedEvent import org.mariotaku.twidere.model.event.TrendsRefreshedEvent
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends
import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.task.BaseAbstractTask
import org.mariotaku.twidere.util.DebugLog.w
import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.content.ContentResolverUtils
import org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert
import java.util.* import java.util.*
/** /**
* Created by mariotaku on 16/2/24. * Created by mariotaku on 16/2/24.
*/ */
class GetTrendsTask( class GetTrendsTask(
context: android.content.Context, context: Context,
private val accountKey: org.mariotaku.twidere.model.UserKey, private val accountKey: UserKey,
private val woeId: Int private val woeId: Int
) : org.mariotaku.twidere.task.BaseAbstractTask<Any?, Unit, Any?>(context) { ) : BaseAbstractTask<Any?, Unit, Any?>(context) {
override fun doLongOperation(param: Any?) { override fun doLongOperation(param: Any?) {
val details = org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails(android.accounts.AccountManager.get(context), accountKey, true) ?: return val details = getAccountDetails(AccountManager.get(context), accountKey, true) ?: return
val twitter = details.newMicroBlogInstance(context, cls = org.mariotaku.microblog.library.MicroBlog::class.java) val twitter = details.newMicroBlogInstance(context, cls = MicroBlog::class.java)
try { try {
val trends = when { val trends = when {
details.type == org.mariotaku.twidere.annotation.AccountType.FANFOU -> twitter.fanfouTrends details.type == FANFOU -> twitter.fanfouTrends
else -> twitter.getLocationTrends(woeId).firstOrNull() else -> twitter.getLocationTrends(woeId).firstOrNull()
} ?: return } ?: return
storeTrends(context.contentResolver, org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, trends) storeTrends(context.contentResolver, CachedTrends.Local.CONTENT_URI, trends)
} catch (e: org.mariotaku.microblog.library.MicroBlogException) { } catch (e: MicroBlogException) {
org.mariotaku.twidere.util.DebugLog.w(LOGTAG, tr = e) w(LOGTAG, tr = e)
} }
} }
override fun afterExecute(handler: Any?, result: Unit) { override fun afterExecute(handler: Any?, result: Unit) {
bus.post(org.mariotaku.twidere.model.event.TrendsRefreshedEvent()) bus.post(TrendsRefreshedEvent())
} }
private fun storeTrends(cr: android.content.ContentResolver, uri: android.net.Uri, trends: org.mariotaku.microblog.library.twitter.model.Trends) { private fun storeTrends(cr: ContentResolver, uri: Uri, trends: Trends) {
val hashtags = android.support.v4.util.ArraySet<String>() val hashtags = ArraySet<String>()
val deleteWhere = org.mariotaku.sqliteqb.library.Expression.and(org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.ACCOUNT_KEY), val deleteWhere = and(equalsArgs(CachedTrends.ACCOUNT_KEY), equalsArgs(CachedTrends.WOEID)).sql
org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.WOEID)).sql
val deleteWhereArgs = arrayOf(accountKey.toString(), woeId.toString()) val deleteWhereArgs = arrayOf(accountKey.toString(), woeId.toString())
cr.delete(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs) cr.delete(CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs)
val allTrends = java.util.ArrayList<org.mariotaku.twidere.model.ParcelableTrend>() val allTrends = ArrayList<ParcelableTrend>()
trends.trends.forEachIndexed { idx, trend -> trends.trends.forEachIndexed { idx, trend ->
val hashtag = trend.name.replaceFirst("#", "") val hashtag = trend.name.replaceFirst("#", "")
hashtags.add(hashtag) hashtags.add(hashtag)
allTrends.add(org.mariotaku.twidere.model.ParcelableTrend().apply { allTrends.add(ParcelableTrend().apply {
this.account_key = accountKey this.account_key = accountKey
this.woe_id = woeId this.woe_id = woeId
this.name = trend.name this.name = trend.name
@ -90,10 +92,11 @@ class GetTrendsTask(
this.trend_order = idx this.trend_order = idx
}) })
} }
org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert(cr, uri, allTrends.map(org.mariotaku.twidere.model.ParcelableTrendValuesCreator::create)) val creator = ObjectCursor.valuesCreatorFrom(ParcelableTrend::class.java)
bulkInsert(cr, uri, allTrends.map(creator::create))
ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false, ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false,
hashtags, null, null) hashtags, null, null)
ContentResolverUtils.bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map { bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map {
val values = ContentValues() val values = ContentValues()
values.put(CachedHashtags.NAME, it) values.put(CachedHashtags.NAME, it)
return@map values return@map values

View File

@ -21,6 +21,7 @@ import net.ypresto.androidtranscoder.format.MediaFormatStrategyPresets
import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.math.NumberUtils import org.apache.commons.lang3.math.NumberUtils
import org.mariotaku.ktextension.* import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.fanfou.model.PhotoStatusUpdate import org.mariotaku.microblog.library.fanfou.model.PhotoStatusUpdate
@ -646,8 +647,8 @@ class UpdateStatusTask(
val sizeLimit = account.mediaSizeLimit val sizeLimit = account.mediaSizeLimit
body = getBodyFromMedia(context, media, sizeLimit, chucked, body = getBodyFromMedia(context, media, sizeLimit, chucked,
ContentLengthInputStream.ReadListener { length, position -> ContentLengthInputStream.ReadListener { length, position ->
callback?.onUploadingProgressChanged(index, position, length) callback?.onUploadingProgressChanged(index, position, length)
}) })
val mediaUploadEvent = MediaUploadEvent.create(context, media) val mediaUploadEvent = MediaUploadEvent.create(context, media)
mediaUploadEvent.setFileSize(body.body.length()) mediaUploadEvent.setFileSize(body.body.length())
body.geometry?.let { geometry -> body.geometry?.let { geometry ->
@ -927,7 +928,8 @@ class UpdateStatusTask(
draft.timestamp = System.currentTimeMillis() draft.timestamp = System.currentTimeMillis()
config(draft) config(draft)
val resolver = context.contentResolver val resolver = context.contentResolver
val draftUri = resolver.insert(Drafts.CONTENT_URI, DraftValuesCreator.create(draft)) ?: return -1 val creator = ObjectCursor.valuesCreatorFrom(Draft::class.java)
val draftUri = resolver.insert(Drafts.CONTENT_URI, creator.create(draft)) ?: return -1
return NumberUtils.toLong(draftUri.lastPathSegment, -1) return NumberUtils.toLong(draftUri.lastPathSegment, -1)
} }

View File

@ -25,6 +25,7 @@ import android.content.Context
import org.mariotaku.ktextension.toInt import org.mariotaku.ktextension.toInt
import org.mariotaku.ktextension.toLong import org.mariotaku.ktextension.toLong
import org.mariotaku.ktextension.useCursor import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.DMResponse import org.mariotaku.microblog.library.twitter.model.DMResponse
@ -429,18 +430,20 @@ class GetMessagesTask(
fun storeMessages(context: Context, data: DatabaseUpdateData, details: AccountDetails, fun storeMessages(context: Context, data: DatabaseUpdateData, details: AccountDetails,
showNotification: Boolean = false) { showNotification: Boolean = false) {
val resolver = context.contentResolver val resolver = context.contentResolver
val conversationCreator = ObjectCursor.valuesCreatorFrom(ParcelableMessageConversation::class.java)
val conversationsValues = data.conversations.filterNot { val conversationsValues = data.conversations.filterNot {
it.id in data.deleteConversations it.id in data.deleteConversations
}.map { }.map {
val values = ParcelableMessageConversationValuesCreator.create(it) val values = conversationCreator.create(it)
if (it._id > 0) { if (it._id > 0) {
values.put(Conversations._ID, it._id) values.put(Conversations._ID, it._id)
} }
return@map values return@map values
} }
val messageCreator = ObjectCursor.valuesCreatorFrom(ParcelableMessage::class.java)
val messagesValues = data.messages.filterNot { val messagesValues = data.messages.filterNot {
data.deleteMessages[it.conversation_id]?.contains(it.id) ?: false data.deleteMessages[it.conversation_id]?.contains(it.id) ?: false
}.map(ParcelableMessageValuesCreator::create) }.map(messageCreator::create)
for ((conversationId, messageIds) in data.deleteMessages) { for ((conversationId, messageIds) in data.deleteMessages) {
val where = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY), val where = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
@ -480,11 +483,11 @@ class GetMessagesTask(
val whereArgs = newIds.toTypedArray() + accountKey.toString() val whereArgs = newIds.toTypedArray() + accountKey.toString()
return context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, return context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS,
where, whereArgs, null).useCursor { cur -> where, whereArgs, null).useCursor { cur ->
val indices = ParcelableMessageConversationCursorIndices(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java)
cur.moveToFirst() cur.moveToFirst()
while (!cur.isAfterLast) { while (!cur.isAfterLast) {
val conversationId = cur.getString(indices.id) val conversationId = cur.getString(indices[Conversations.CONVERSATION_ID])
val timestamp = cur.getLong(indices.local_timestamp) val timestamp = cur.getLong(indices[Conversations.LOCAL_TIMESTAMP])
val conversation = this[conversationId] ?: run { val conversation = this[conversationId] ?: run {
val obj = indices.newObject(cur) val obj = indices.newObject(cur)
this[conversationId] = obj this[conversationId] = obj

View File

@ -23,6 +23,7 @@ import android.accounts.AccountManager
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
@ -31,7 +32,10 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.model.timestamp import org.mariotaku.twidere.extension.model.timestamp
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableMessage
import org.mariotaku.twidere.model.ParcelableMessageConversation
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Messages import org.mariotaku.twidere.provider.TwidereDataStore.Messages
@ -103,7 +107,8 @@ class MarkMessageReadTask(
where, whereArgs, OrderBy(Messages.LOCAL_TIMESTAMP, false).sql) ?: return null where, whereArgs, OrderBy(Messages.LOCAL_TIMESTAMP, false).sql) ?: return null
try { try {
if (cur.moveToFirst()) { if (cur.moveToFirst()) {
return ParcelableMessageCursorIndices.fromCursor(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessage::class.java)
return indices.newObject(cur)
} }
} finally { } finally {
cur.close() cur.close()

View File

@ -6,10 +6,10 @@ import android.database.sqlite.SQLiteDatabase
import com.bluelinelabs.logansquare.LoganSquare import com.bluelinelabs.logansquare.LoganSquare
import org.mariotaku.ktextension.HexColorFormat import org.mariotaku.ktextension.HexColorFormat
import org.mariotaku.ktextension.toHexColor import org.mariotaku.ktextension.toHexColor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.annotation.AuthTypeInt import org.mariotaku.twidere.annotation.AuthTypeInt
import org.mariotaku.twidere.model.ParcelableCredentials import org.mariotaku.twidere.model.ParcelableCredentials
import org.mariotaku.twidere.model.ParcelableCredentialsCursorIndices
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.account.cred.BasicCredentials import org.mariotaku.twidere.model.account.cred.BasicCredentials
@ -27,7 +27,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Accounts
fun migrateAccounts(am: AccountManager, db: SQLiteDatabase) { fun migrateAccounts(am: AccountManager, db: SQLiteDatabase) {
val cur = db.query(Accounts.TABLE_NAME, Accounts.COLUMNS, null, null, null, null, null) ?: return val cur = db.query(Accounts.TABLE_NAME, Accounts.COLUMNS, null, null, null, null, null) ?: return
try { try {
val indices = ParcelableCredentialsCursorIndices(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableCredentials::class.java)
cur.moveToFirst() cur.moveToFirst()
while (!cur.isAfterLast) { while (!cur.isAfterLast) {
val credentials = indices.newObject(cur) val credentials = indices.newObject(cur)

View File

@ -30,6 +30,7 @@ import android.net.Uri
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.isEmpty import org.mariotaku.ktextension.isEmpty
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.twitter.model.Activity import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.sqliteqb.library.* import org.mariotaku.sqliteqb.library.*
import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Columns.Column
@ -99,22 +100,22 @@ class ContentNotificationManager(
val usersCount = userCursor.count val usersCount = userCursor.count
val statusesCount = statusCursor.count val statusesCount = statusCursor.count
if (statusesCount == 0 || usersCount == 0) return if (statusesCount == 0 || usersCount == 0) return
val statusIndices = ParcelableStatusCursorIndices(statusCursor) val statusIndices = ObjectCursor.indicesFrom(statusCursor, ParcelableStatus::class.java)
val userIndices = ParcelableStatusCursorIndices(userCursor) val userIndices = ObjectCursor.indicesFrom(userCursor, ParcelableStatus::class.java)
val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices.position_key) else -1L val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices[Statuses.POSITION_KEY]) else -1L
val notificationTitle = resources.getQuantityString(R.plurals.N_new_statuses, val notificationTitle = resources.getQuantityString(R.plurals.N_new_statuses,
statusesCount, statusesCount) statusesCount, statusesCount)
val notificationContent: String val notificationContent: String
userCursor.moveToFirst() userCursor.moveToFirst()
val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key), val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices[Statuses.USER_KEY]),
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name), userCursor.getString(userIndices[Statuses.USER_NAME]), userCursor.getString(userIndices[Statuses.USER_SCREEN_NAME]),
nameFirst) nameFirst)
if (usersCount == 1) { if (usersCount == 1) {
notificationContent = context.getString(R.string.from_name, displayName) notificationContent = context.getString(R.string.from_name, displayName)
} else if (usersCount == 2) { } else if (usersCount == 2) {
userCursor.moveToPosition(1) userCursor.moveToPosition(1)
val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key), val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices[Statuses.USER_KEY]),
userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name), userCursor.getString(userIndices[Statuses.USER_NAME]), userCursor.getString(userIndices[Statuses.USER_SCREEN_NAME]),
nameFirst) nameFirst)
notificationContent = resources.getString(R.string.from_name_and_name, displayName, othersName) notificationContent = resources.getString(R.string.from_name_and_name, displayName, othersName)
} else { } else {
@ -178,7 +179,7 @@ class ContentNotificationManager(
builder.setStyle(style) builder.setStyle(style)
builder.setAutoCancel(true) builder.setAutoCancel(true)
style.setSummaryText(accountName) style.setSummaryText(accountName)
val ci = ParcelableActivityCursorIndices(c) val ci = ObjectCursor.indicesFrom(c, ParcelableActivity::class.java)
var timestamp: Long = -1 var timestamp: Long = -1
val filteredUserIds = DataStoreUtils.getFilteredUserIds(context) val filteredUserIds = DataStoreUtils.getFilteredUserIds(context)
@ -276,11 +277,11 @@ class ContentNotificationManager(
try { try {
if (cur.isEmpty) return if (cur.isEmpty) return
val indices = ParcelableMessageConversationCursorIndices(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java)
var messageSum: Int = 0 var messageSum: Int = 0
cur.forEachRow { cur, pos -> cur.forEachRow { cur, pos ->
messageSum += cur.getInt(indices.unread_count) messageSum += cur.getInt(indices[Conversations.UNREAD_COUNT])
return@forEachRow true return@forEachRow true
} }

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.util package org.mariotaku.twidere.util
import android.content.ContentValues import android.content.ContentValues
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.twitter.model.SavedSearch import org.mariotaku.microblog.library.twitter.model.SavedSearch
import org.mariotaku.microblog.library.twitter.model.Status import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.microblog.library.twitter.model.User
@ -34,7 +35,7 @@ object ContentValuesCreator {
fun createCachedUser(user: User, profileImageSize: String = "normal"): ContentValues { fun createCachedUser(user: User, profileImageSize: String = "normal"): ContentValues {
val values = ContentValues() val values = ContentValues()
ParcelableUserValuesCreator.writeTo(ParcelableUserUtils.fromUser(user, null, ObjectCursor.valuesCreatorFrom(ParcelableUser::class.java).writeTo(ParcelableUserUtils.fromUser(user, null,
profileImageSize = profileImageSize), values) profileImageSize = profileImageSize), values)
return values return values
} }
@ -78,8 +79,8 @@ object ContentValuesCreator {
} }
fun createStatus(orig: Status, accountKey: UserKey, profileImageSize: String): ContentValues { fun createStatus(orig: Status, accountKey: UserKey, profileImageSize: String): ContentValues {
return ParcelableStatusValuesCreator.create(ParcelableStatusUtils.fromStatus(orig, return ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java)
accountKey, false, profileImageSize)) .create(ParcelableStatusUtils.fromStatus(orig, accountKey, false, profileImageSize))
} }
fun createActivity(activity: ParcelableActivity, details: AccountDetails): ContentValues { fun createActivity(activity: ParcelableActivity, details: AccountDetails): ContentValues {
@ -109,7 +110,7 @@ object ContentValuesCreator {
activity.status_text_plain = status.text_plain activity.status_text_plain = status.text_plain
activity.status_source = status.source activity.status_source = status.source
} }
ParcelableActivityValuesCreator.writeTo(activity, values) ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java).writeTo(activity, values)
return values return values
} }

View File

@ -10,11 +10,15 @@ import android.support.annotation.WorkerThread
import android.support.v4.util.LongSparseArray import android.support.v4.util.LongSparseArray
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.useCursor import org.mariotaku.ktextension.useCursor
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.* import org.mariotaku.sqliteqb.library.*
import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey
import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.util.DataStoreUtils.ACTIVITIES_URIS import org.mariotaku.twidere.util.DataStoreUtils.ACTIVITIES_URIS
import java.io.IOException import java.io.IOException
@ -94,7 +98,7 @@ fun deleteDrafts(context: Context, draftIds: LongArray): Int {
context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where, whereArgs, context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where, whereArgs,
null).useCursor { cursor -> null).useCursor { cursor ->
val indices = DraftCursorIndices(cursor) val indices = ObjectCursor.indicesFrom(cursor, Draft::class.java)
cursor.moveToFirst() cursor.moveToFirst()
while (!cursor.isAfterLast) { while (!cursor.isAfterLast) {
val draft = indices.newObject(cursor) val draft = indices.newObject(cursor)
@ -194,12 +198,13 @@ fun updateActivity(cr: ContentResolver, uri: Uri,
val c = cr.query(uri, Activities.COLUMNS, where, whereArgs, null) ?: return val c = cr.query(uri, Activities.COLUMNS, where, whereArgs, null) ?: return
val values = LongSparseArray<ContentValues>() val values = LongSparseArray<ContentValues>()
try { try {
val ci = ParcelableActivityCursorIndices(c) val ci = ObjectCursor.indicesFrom(c, ParcelableActivity::class.java)
val vc = ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java)
c.moveToFirst() c.moveToFirst()
while (!c.isAfterLast) { while (!c.isAfterLast) {
val activity = ci.newObject(c) val activity = ci.newObject(c)
action(activity) action(activity)
values.put(activity._id, ParcelableActivityValuesCreator.create(activity)) values.put(activity._id, vc.create(activity))
c.moveToNext() c.moveToNext()
} }
} catch (e: IOException) { } catch (e: IOException) {

View File

@ -159,7 +159,8 @@ object DataStoreUtils {
if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size) if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size)
return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS, return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS,
OrderBy(SQLFunctions.MIN(Messages.LOCAL_TIMESTAMP)), null, null, OrderBy(SQLFunctions.MIN(Messages.LOCAL_TIMESTAMP)), null, null,
::ParcelableMessageConversationCursorIndices, { arrayOfNulls<ParcelableMessageConversation>(it) }) { ObjectCursor.indicesFrom(it, ParcelableMessageConversation::class.java) },
{ arrayOfNulls<ParcelableMessageConversation>(it) })
} }
fun getNewestConversations(context: Context, uri: Uri, accountKeys: Array<UserKey?>, fun getNewestConversations(context: Context, uri: Uri, accountKeys: Array<UserKey?>,
@ -167,7 +168,8 @@ object DataStoreUtils {
if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size) if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size)
return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS, return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS,
OrderBy(SQLFunctions.MAX(Messages.LOCAL_TIMESTAMP)), extraWhere, extraWhereArgs, OrderBy(SQLFunctions.MAX(Messages.LOCAL_TIMESTAMP)), extraWhere, extraWhereArgs,
::ParcelableMessageConversationCursorIndices, { arrayOfNulls<ParcelableMessageConversation>(it) }) { ObjectCursor.indicesFrom(it, ParcelableMessageConversation::class.java) },
{ arrayOfNulls<ParcelableMessageConversation>(it) })
} }
fun getNewestStatusSortIds(context: Context, uri: Uri, accountKeys: Array<UserKey?>): LongArray { fun getNewestStatusSortIds(context: Context, uri: Uri, accountKeys: Array<UserKey?>): LongArray {
@ -800,6 +802,8 @@ object DataStoreUtils {
val cr = context.contentResolver val cr = context.contentResolver
try { try {
val baseCreator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java)
val userCreator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java)
val userValues = ArrayList<ContentValues>() val userValues = ArrayList<ContentValues>()
val keywordValues = ArrayList<ContentValues>() val keywordValues = ArrayList<ContentValues>()
val linkValues = ArrayList<ContentValues>() val linkValues = ArrayList<ContentValues>()
@ -808,12 +812,12 @@ object DataStoreUtils {
userItem.userKey = user.key userItem.userKey = user.key
userItem.screenName = user.screen_name userItem.screenName = user.screen_name
userItem.name = user.name userItem.name = user.name
userValues.add(`FiltersData$UserItemValuesCreator`.create(userItem)) userValues.add(userCreator.create(userItem))
val keywordItem = FiltersData.BaseItem() val keywordItem = FiltersData.BaseItem()
keywordItem.value = "@" + user.screen_name keywordItem.value = "@" + user.screen_name
keywordItem.userKey = user.key keywordItem.userKey = user.key
keywordValues.add(`FiltersData$BaseItemValuesCreator`.create(keywordItem)) keywordValues.add(baseCreator.create(keywordItem))
// Insert user link (without scheme) to links // Insert user link (without scheme) to links
val linkItem = FiltersData.BaseItem() val linkItem = FiltersData.BaseItem()
@ -821,7 +825,7 @@ object DataStoreUtils {
val linkWithoutScheme = userLink.toString().substringAfter("://") val linkWithoutScheme = userLink.toString().substringAfter("://")
linkItem.value = linkWithoutScheme linkItem.value = linkWithoutScheme
linkItem.userKey = user.key linkItem.userKey = user.key
linkValues.add(`FiltersData$BaseItemValuesCreator`.create(linkItem)) linkValues.add(baseCreator.create(linkItem))
} }
ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, userValues) ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, userValues)
@ -861,8 +865,9 @@ object DataStoreUtils {
for (uri in DataStoreUtils.STATUSES_URIS) { for (uri in DataStoreUtils.STATUSES_URIS) {
val cur = resolver.query(uri, Statuses.COLUMNS, where, whereArgs, null) ?: continue val cur = resolver.query(uri, Statuses.COLUMNS, where, whereArgs, null) ?: continue
try { try {
if (cur.count > 0 && cur.moveToFirst()) { if (cur.moveToFirst()) {
status = ParcelableStatusCursorIndices.fromCursor(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableStatus::class.java)
status = indices.newObject(cur)
} }
} finally { } finally {
cur.close() cur.close()
@ -885,7 +890,7 @@ object DataStoreUtils {
val resolver = context.contentResolver val resolver = context.contentResolver
val status = ParcelableStatusUtils.fromStatus(result, accountKey, false) val status = ParcelableStatusUtils.fromStatus(result, accountKey, false)
resolver.delete(CachedStatuses.CONTENT_URI, where, whereArgs) resolver.delete(CachedStatuses.CONTENT_URI, where, whereArgs)
resolver.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(status)) resolver.insert(CachedStatuses.CONTENT_URI, ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java).create(status))
return status return status
} }
@ -898,7 +903,8 @@ object DataStoreUtils {
val cur = resolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null) ?: return null val cur = resolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null) ?: return null
try { try {
if (cur.moveToFirst()) { if (cur.moveToFirst()) {
return ParcelableMessageConversationCursorIndices.fromCursor(cur) val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java)
return indices.newObject(cur)
} }
} finally { } finally {
cur.close() cur.close()

View File

@ -26,6 +26,7 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper import android.database.sqlite.SQLiteOpenHelper
import android.os.Build import android.os.Build
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.* import org.mariotaku.sqliteqb.library.*
import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Columns.Column
import org.mariotaku.sqliteqb.library.query.SQLCreateTriggerQuery.Event import org.mariotaku.sqliteqb.library.query.SQLCreateTriggerQuery.Event
@ -34,7 +35,6 @@ import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.annotation.CustomTabType import org.mariotaku.twidere.annotation.CustomTabType
import org.mariotaku.twidere.constant.defaultAPIConfigKey import org.mariotaku.twidere.constant.defaultAPIConfigKey
import org.mariotaku.twidere.model.Tab import org.mariotaku.twidere.model.Tab
import org.mariotaku.twidere.model.TabValuesCreator
import org.mariotaku.twidere.model.tab.TabConfiguration import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
@ -104,6 +104,7 @@ class TwidereSQLiteOpenHelper(
private fun setupDefaultTabs(db: SQLiteDatabase) { private fun setupDefaultTabs(db: SQLiteDatabase) {
val creator = ObjectCursor.valuesCreatorFrom(Tab::class.java)
db.beginTransaction() db.beginTransaction()
@CustomTabType @CustomTabType
val tabTypes = arrayOf(CustomTabType.HOME_TIMELINE, CustomTabType.NOTIFICATIONS_TIMELINE, val tabTypes = arrayOf(CustomTabType.HOME_TIMELINE, CustomTabType.NOTIFICATIONS_TIMELINE,
@ -117,7 +118,7 @@ class TwidereSQLiteOpenHelper(
this.icon = conf!!.icon.persistentKey this.icon = conf!!.icon.persistentKey
this.position = i this.position = i
} }
db.insert(Tabs.TABLE_NAME, null, TabValuesCreator.create(tab)) db.insert(Tabs.TABLE_NAME, null, creator.create(tab))
} }
db.setTransactionSuccessful() db.setTransactionSuccessful()
db.endTransaction() db.endTransaction()

View File

@ -4,12 +4,11 @@ import android.content.Context
import android.support.v4.util.LongSparseArray import android.support.v4.util.LongSparseArray
import org.mariotaku.ktextension.map import org.mariotaku.ktextension.map
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.extension.model.filename import org.mariotaku.twidere.extension.model.filename
import org.mariotaku.twidere.extension.model.unique_id_non_null import org.mariotaku.twidere.extension.model.unique_id_non_null
import org.mariotaku.twidere.model.Draft import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.DraftCursorIndices
import org.mariotaku.twidere.model.DraftValuesCreator
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.content.ContentResolverUtils
@ -45,7 +44,8 @@ abstract class FileBasedDraftsSyncAction<RemoteFileInfo>(val context: Context) :
val localDrafts = run { val localDrafts = run {
val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!! val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!!
try { try {
return@run cur.map(DraftCursorIndices(cur)) val indices = ObjectCursor.indicesFrom(cur, Draft::class.java)
return@run cur.map(indices)
} finally { } finally {
cur.close() cur.close()
} }
@ -121,19 +121,20 @@ abstract class FileBasedDraftsSyncAction<RemoteFileInfo>(val context: Context) :
val fileList = downloadRemoteInfoList.joinToString(",") { it.draftFileName } val fileList = downloadRemoteInfoList.joinToString(",") { it.draftFileName }
DebugLog.d(LOGTAG_SYNC, "Downloading remote drafts $fileList") DebugLog.d(LOGTAG_SYNC, "Downloading remote drafts $fileList")
ContentResolverUtils.bulkInsert(context.contentResolver, Drafts.CONTENT_URI, ContentResolverUtils.bulkInsert(context.contentResolver, Drafts.CONTENT_URI,
downloadDrafts(downloadRemoteInfoList).map { DraftValuesCreator.create(it) }) downloadDrafts(downloadRemoteInfoList).map { ObjectCursor.valuesCreatorFrom(Draft::class.java).create(it) })
} }
// Update local items // Update local items
if (updateLocalInfoList.size() > 0) { if (updateLocalInfoList.size() > 0) {
val fileList = (0 until updateLocalInfoList.size()).joinToString(",") { updateLocalInfoList.valueAt(it).draftFileName } val fileList = (0 until updateLocalInfoList.size()).joinToString(",") { updateLocalInfoList.valueAt(it).draftFileName }
DebugLog.d(LOGTAG_SYNC, "Updating local drafts $fileList") DebugLog.d(LOGTAG_SYNC, "Updating local drafts $fileList")
val creator = ObjectCursor.valuesCreatorFrom(Draft::class.java)
for (index in 0 until updateLocalInfoList.size()) { for (index in 0 until updateLocalInfoList.size()) {
val draft = Draft() val draft = Draft()
if (draft.loadFromRemote(updateLocalInfoList.valueAt(index))) { if (draft.loadFromRemote(updateLocalInfoList.valueAt(index))) {
val where = Expression.equalsArgs(Drafts._ID).sql val where = Expression.equalsArgs(Drafts._ID).sql
val whereArgs = arrayOf(updateLocalInfoList.keyAt(index).toString()) val whereArgs = arrayOf(updateLocalInfoList.keyAt(index).toString())
context.contentResolver.update(Drafts.CONTENT_URI, DraftValuesCreator.create(draft), where, whereArgs) context.contentResolver.update(Drafts.CONTENT_URI, creator.create(draft), where, whereArgs)
} }
} }
} }
@ -156,7 +157,8 @@ abstract class FileBasedDraftsSyncAction<RemoteFileInfo>(val context: Context) :
snapshotsListFile.writer().use { writer -> snapshotsListFile.writer().use { writer ->
val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!! val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!!
try { try {
cur.map(DraftCursorIndices(cur)).map { it.unique_id_non_null }.forEach { line -> val indices = ObjectCursor.indicesFrom(cur, Draft::class.java)
cur.map(indices).map { it.unique_id_non_null }.forEach { line ->
writer.write(line) writer.write(line)
writer.write("\n") writer.write("\n")
} }