Loading data/src/main/java/com/moez/QKSMS/extensions/CursorExtensions.kt +8 −29 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ package com.moez.QKSMS.extensions import android.database.Cursor import io.reactivex.Flowable import io.reactivex.Maybe import io.reactivex.subjects.MaybeSubject fun Cursor.forEach(closeOnComplete: Boolean = true, method: (Cursor) -> Unit = {}) { moveToPosition(-1) Loading @@ -41,21 +39,6 @@ fun <T> Cursor.map(map: (Cursor) -> T): List<T> { } } fun <T> Cursor.mapWhile(map: (Cursor) -> T, predicate: (T) -> Boolean): ArrayList<T> { val result = ArrayList<T>() moveToPosition(-1) while (moveToNext()) { val item = map(this) if (!predicate(item)) break result.add(item) } return result } /** * We're using this simple implementation with .range() because of the * complexities of dealing with Backpressure with a Cursor. We can't simply Loading @@ -72,18 +55,14 @@ fun Cursor.asFlowable(): Flowable<Cursor> { .doOnComplete { close() } } fun Cursor.asMaybe(): Maybe<Cursor> { val subject = MaybeSubject.create<Cursor>() /** * Dumps the contents of the cursor as a CSV string */ fun Cursor.dump(): String { val lines = mutableListOf<String>() if (moveToFirst()) { subject.onSuccess(this) } else { subject.onError(IndexOutOfBoundsException("The cursor has no items")) } lines += columnNames.joinToString(",") forEach { lines += (0 until columnCount).joinToString(",", transform = ::getString) } subject.doOnComplete { close() } return subject return lines.joinToString("\n") } data/src/main/java/com/moez/QKSMS/mapper/CursorToContactGroupImpl.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com> * * This file is part of QKSMS. * * QKSMS 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. * * QKSMS 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 QKSMS. If not, see <http://www.gnu.org/licenses/>. */ package com.moez.QKSMS.mapper import android.content.Context import android.database.Cursor import android.provider.ContactsContract import com.moez.QKSMS.model.ContactGroup import javax.inject.Inject class CursorToContactGroupImpl @Inject constructor( private val context: Context ) : CursorToContactGroup { companion object { private val URI = ContactsContract.Groups.CONTENT_URI private val PROJECTION = arrayOf( ContactsContract.Groups._ID, ContactsContract.Groups.TITLE) private const val SELECTION = "${ContactsContract.Groups.AUTO_ADD}=0 " + "AND ${ContactsContract.Groups.DELETED}=0 " + "AND ${ContactsContract.Groups.FAVORITES}=0" private const val ID = 0 private const val TITLE = 1 } override fun map(from: Cursor): ContactGroup { return ContactGroup(from.getLong(ID), from.getString(TITLE)) } override fun getContactGroupsCursor(): Cursor? { return context.contentResolver.query(URI, PROJECTION, SELECTION, null, null) } } data/src/main/java/com/moez/QKSMS/mapper/CursorToContactGroupMemberImpl.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com> * * This file is part of QKSMS. * * QKSMS 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. * * QKSMS 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 QKSMS. If not, see <http://www.gnu.org/licenses/>. */ package com.moez.QKSMS.mapper import android.content.Context import android.database.Cursor import android.provider.ContactsContract import javax.inject.Inject class CursorToContactGroupMemberImpl @Inject constructor( private val context: Context ) : CursorToContactGroupMember { companion object { private val URI = ContactsContract.Data.CONTENT_URI private val PROJECTION = arrayOf( ContactsContract.Data.LOOKUP_KEY, ContactsContract.Data.DATA1) private const val SELECTION = "${ContactsContract.Data.MIMETYPE}=?" private val SELECTION_ARGS = arrayOf( ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) private const val LOOKUP_KEY = 0 private const val GROUP_ID = 1 } override fun map(from: Cursor): CursorToContactGroupMember.GroupMember { return CursorToContactGroupMember.GroupMember(from.getString(LOOKUP_KEY), from.getLong(GROUP_ID)) } override fun getGroupMembersCursor(): Cursor? { return context.contentResolver.query(URI, PROJECTION, SELECTION, SELECTION_ARGS, null) } } data/src/main/java/com/moez/QKSMS/mapper/CursorToContactImpl.kt +5 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ class CursorToContactImpl @Inject constructor( Phone.TYPE, Phone.LABEL, Phone.DISPLAY_NAME, Phone.STARRED, Phone.CONTACT_LAST_UPDATED_TIMESTAMP ) Loading @@ -47,7 +48,8 @@ class CursorToContactImpl @Inject constructor( const val COLUMN_TYPE = 2 const val COLUMN_LABEL = 3 const val COLUMN_DISPLAY_NAME = 4 const val CONTACT_LAST_UPDATED = 5 const val COLUMN_STARRED = 5 const val CONTACT_LAST_UPDATED = 6 } override fun map(from: Cursor) = Contact().apply { Loading @@ -58,6 +60,7 @@ class CursorToContactImpl @Inject constructor( type = Phone.getTypeLabel(context.resources, from.getInt(COLUMN_TYPE), from.getString(COLUMN_LABEL)).toString() )) starred = from.getInt(COLUMN_STARRED) != 0 lastUpdate = from.getLong(CONTACT_LAST_UPDATED) } Loading data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt +13 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import io.realm.Sort class QkRealmMigration : RealmMigration { companion object { const val SCHEMA_VERSION: Long = 8 const val SCHEMA_VERSION: Long = 9 } override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Loading Loading @@ -118,6 +118,18 @@ class QkRealmMigration : RealmMigration { version++ } if (version == 8L) { realm.schema.create("ContactGroup") .addField("id", Long::class.java, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED) .addField("title", String::class.java, FieldAttribute.REQUIRED) .addRealmListField("contacts", realm.schema.get("Contact")) realm.schema.get("Contact") ?.addField("starred", Boolean::class.java, FieldAttribute.REQUIRED) version++ } check(version >= newVersion) { "Migration missing from v$oldVersion to v$newVersion" } } Loading Loading
data/src/main/java/com/moez/QKSMS/extensions/CursorExtensions.kt +8 −29 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ package com.moez.QKSMS.extensions import android.database.Cursor import io.reactivex.Flowable import io.reactivex.Maybe import io.reactivex.subjects.MaybeSubject fun Cursor.forEach(closeOnComplete: Boolean = true, method: (Cursor) -> Unit = {}) { moveToPosition(-1) Loading @@ -41,21 +39,6 @@ fun <T> Cursor.map(map: (Cursor) -> T): List<T> { } } fun <T> Cursor.mapWhile(map: (Cursor) -> T, predicate: (T) -> Boolean): ArrayList<T> { val result = ArrayList<T>() moveToPosition(-1) while (moveToNext()) { val item = map(this) if (!predicate(item)) break result.add(item) } return result } /** * We're using this simple implementation with .range() because of the * complexities of dealing with Backpressure with a Cursor. We can't simply Loading @@ -72,18 +55,14 @@ fun Cursor.asFlowable(): Flowable<Cursor> { .doOnComplete { close() } } fun Cursor.asMaybe(): Maybe<Cursor> { val subject = MaybeSubject.create<Cursor>() /** * Dumps the contents of the cursor as a CSV string */ fun Cursor.dump(): String { val lines = mutableListOf<String>() if (moveToFirst()) { subject.onSuccess(this) } else { subject.onError(IndexOutOfBoundsException("The cursor has no items")) } lines += columnNames.joinToString(",") forEach { lines += (0 until columnCount).joinToString(",", transform = ::getString) } subject.doOnComplete { close() } return subject return lines.joinToString("\n") }
data/src/main/java/com/moez/QKSMS/mapper/CursorToContactGroupImpl.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com> * * This file is part of QKSMS. * * QKSMS 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. * * QKSMS 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 QKSMS. If not, see <http://www.gnu.org/licenses/>. */ package com.moez.QKSMS.mapper import android.content.Context import android.database.Cursor import android.provider.ContactsContract import com.moez.QKSMS.model.ContactGroup import javax.inject.Inject class CursorToContactGroupImpl @Inject constructor( private val context: Context ) : CursorToContactGroup { companion object { private val URI = ContactsContract.Groups.CONTENT_URI private val PROJECTION = arrayOf( ContactsContract.Groups._ID, ContactsContract.Groups.TITLE) private const val SELECTION = "${ContactsContract.Groups.AUTO_ADD}=0 " + "AND ${ContactsContract.Groups.DELETED}=0 " + "AND ${ContactsContract.Groups.FAVORITES}=0" private const val ID = 0 private const val TITLE = 1 } override fun map(from: Cursor): ContactGroup { return ContactGroup(from.getLong(ID), from.getString(TITLE)) } override fun getContactGroupsCursor(): Cursor? { return context.contentResolver.query(URI, PROJECTION, SELECTION, null, null) } }
data/src/main/java/com/moez/QKSMS/mapper/CursorToContactGroupMemberImpl.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com> * * This file is part of QKSMS. * * QKSMS 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. * * QKSMS 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 QKSMS. If not, see <http://www.gnu.org/licenses/>. */ package com.moez.QKSMS.mapper import android.content.Context import android.database.Cursor import android.provider.ContactsContract import javax.inject.Inject class CursorToContactGroupMemberImpl @Inject constructor( private val context: Context ) : CursorToContactGroupMember { companion object { private val URI = ContactsContract.Data.CONTENT_URI private val PROJECTION = arrayOf( ContactsContract.Data.LOOKUP_KEY, ContactsContract.Data.DATA1) private const val SELECTION = "${ContactsContract.Data.MIMETYPE}=?" private val SELECTION_ARGS = arrayOf( ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) private const val LOOKUP_KEY = 0 private const val GROUP_ID = 1 } override fun map(from: Cursor): CursorToContactGroupMember.GroupMember { return CursorToContactGroupMember.GroupMember(from.getString(LOOKUP_KEY), from.getLong(GROUP_ID)) } override fun getGroupMembersCursor(): Cursor? { return context.contentResolver.query(URI, PROJECTION, SELECTION, SELECTION_ARGS, null) } }
data/src/main/java/com/moez/QKSMS/mapper/CursorToContactImpl.kt +5 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ class CursorToContactImpl @Inject constructor( Phone.TYPE, Phone.LABEL, Phone.DISPLAY_NAME, Phone.STARRED, Phone.CONTACT_LAST_UPDATED_TIMESTAMP ) Loading @@ -47,7 +48,8 @@ class CursorToContactImpl @Inject constructor( const val COLUMN_TYPE = 2 const val COLUMN_LABEL = 3 const val COLUMN_DISPLAY_NAME = 4 const val CONTACT_LAST_UPDATED = 5 const val COLUMN_STARRED = 5 const val CONTACT_LAST_UPDATED = 6 } override fun map(from: Cursor) = Contact().apply { Loading @@ -58,6 +60,7 @@ class CursorToContactImpl @Inject constructor( type = Phone.getTypeLabel(context.resources, from.getInt(COLUMN_TYPE), from.getString(COLUMN_LABEL)).toString() )) starred = from.getInt(COLUMN_STARRED) != 0 lastUpdate = from.getLong(CONTACT_LAST_UPDATED) } Loading
data/src/main/java/com/moez/QKSMS/migration/QkRealmMigration.kt +13 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import io.realm.Sort class QkRealmMigration : RealmMigration { companion object { const val SCHEMA_VERSION: Long = 8 const val SCHEMA_VERSION: Long = 9 } override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Loading Loading @@ -118,6 +118,18 @@ class QkRealmMigration : RealmMigration { version++ } if (version == 8L) { realm.schema.create("ContactGroup") .addField("id", Long::class.java, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED) .addField("title", String::class.java, FieldAttribute.REQUIRED) .addRealmListField("contacts", realm.schema.get("Contact")) realm.schema.get("Contact") ?.addField("starred", Boolean::class.java, FieldAttribute.REQUIRED) version++ } check(version >= newVersion) { "Migration missing from v$oldVersion to v$newVersion" } } Loading