Skip to content

Commit

Permalink
Make ContactLookup take a single contactId instead of a collection
Browse files Browse the repository at this point in the history
  • Loading branch information
alexstyl committed Feb 19, 2022
1 parent 3c50475 commit ca57d81
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,18 @@ public class TestContactStore(
}


@Suppress("DEPRECATION") // using deprecated to warn any consumers of the library. To be removed in 1.0.0
private fun matchesContact(
predicate: ContactPredicate.ContactLookup,
contact: StoredContact
): Boolean {
val isInIds = predicate.inContactIds.orEmpty().contains(contact.contactId)
val isFavorite = predicate.isFavorite?.let { contact.isStarred == it } ?: true
return isInIds && isFavorite
if (predicate.inContactIds.orEmpty().isNotEmpty()) {
System.err.println("ContactLookup.inContactIds does nothing. Use ContactLookup.contactId instead")
}
if (predicate.isFavorite != null) {
System.err.println("ContactLookup.isFavorite does nothing")
}
return predicate.contactId == contact.contactId
}

private fun matchesPhone(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.provider.ContactsContract
import android.util.Log
import androidx.test.core.app.ApplicationProvider
import androidx.test.rule.GrantPermissionRule
import com.alexstyl.contactstore.ContactPredicate.ContactLookup
import com.alexstyl.contactstore.test.samePropertiesAs
import kotlinx.coroutines.flow.first
import org.hamcrest.CoreMatchers.equalTo
Expand All @@ -24,7 +25,7 @@ internal abstract class ContactStoreTestBase {
suspend fun assertContactUpdated(editedContact: MutableContact) {
store.execute { update(editedContact) }
val actual = store.fetchContacts(
predicate = ContactPredicate.ContactLookup(inContactIds = listOf(editedContact.contactId)),
predicate = ContactLookup(editedContact.contactId),
columnsToFetch = editedContact.columns
).first().first()

Expand All @@ -34,7 +35,7 @@ internal abstract class ContactStoreTestBase {
suspend fun assertContactUpdatedNoId(expected: MutableContact) {
store.execute { update(expected) }
val actual = store.fetchContacts(
predicate = ContactPredicate.ContactLookup(inContactIds = listOf(expected.contactId)),
predicate = ContactLookup(expected.contactId),
columnsToFetch = expected.columns
).first().first()

Expand Down
22 changes: 11 additions & 11 deletions library/src/main/java/com/alexstyl/contactstore/ContactEquality.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@ internal fun Contact.contactHashCode(): Int {
result = 31 * result + hashIfContains(Note) { note?.hashCode() }
result = 31 * result + hashIfContains(GroupMemberships) { groups.hashCode() }
result = 31 * result + hashIfContains(Relations) { relations.hashCode() }
result = 31 * result + hashIfContains(Organization) { organization?.hashCode() }
result = 31 * result + hashIfContains(Organization) { jobTitle?.hashCode() }
result = 31 * result + hashIfContains(Names) { firstName?.hashCode() }
result = 31 * result + hashIfContains(Names) { lastName?.hashCode() }
result = 31 * result + hashIfContains(Names) { middleName?.hashCode() }
result = 31 * result + hashIfContains(Names) { prefix?.hashCode() }
result = 31 * result + hashIfContains(Names) { suffix?.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticLastName?.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticFirstName?.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticMiddleName?.hashCode() }
result = 31 * result + hashIfContains(Organization) { organization.hashCode() }
result = 31 * result + hashIfContains(Organization) { jobTitle.hashCode() }
result = 31 * result + hashIfContains(Names) { firstName.hashCode() }
result = 31 * result + hashIfContains(Names) { lastName.hashCode() }
result = 31 * result + hashIfContains(Names) { middleName.hashCode() }
result = 31 * result + hashIfContains(Names) { prefix.hashCode() }
result = 31 * result + hashIfContains(Names) { suffix.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticLastName.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticFirstName.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticMiddleName.hashCode() }
result = 31 * result + hashIfContains(Names) { fullNameStyle.hashCode() }
result = 31 * result + hashIfContains(Names) { phoneticNameStyle.hashCode() }
result = 31 * result + hashIfContains(Names) { nickname?.hashCode() }
result = 31 * result + hashIfContains(Names) { nickname.hashCode() }
result = 31 * result + displayName.hashCode()

return result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@ public sealed class ContactPredicate {
* Performs a contact lookup by trying to match the given string against various parts of the contact name.
*/
public data class NameLookup(val partOfName: String) : ContactPredicate()

/**
* Performs a contact lookup by trying to find a contact with the given contact id.
*/
public data class ContactLookup(
val contactId: Long,
@Deprecated(
"This property does nothing and will go away in 1.0.0. Perform multiple contactFetches using ContactStore#fetchContacts() using FlowKt.combine()",
ReplaceWith("contactId")
)
val inContactIds: List<Long>? = null,
@Deprecated("This property is not used. It will go away in 1.0.0")
val isFavorite: Boolean? = null,
) : ContactPredicate()
}
44 changes: 14 additions & 30 deletions library/src/main/java/com/alexstyl/contactstore/ContactQueries.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import com.alexstyl.contactstore.ContactPredicate.PhoneLookup
import com.alexstyl.contactstore.utils.DateParser
import com.alexstyl.contactstore.utils.mapEachRow
import com.alexstyl.contactstore.utils.runQueryFlow
import com.alexstyl.contactstore.utils.valueIn
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.io.InputStream
Expand Down Expand Up @@ -87,7 +86,7 @@ internal class ContactQueries(
): Flow<List<PartialContact>> {
return when (predicate) {
null -> queryAllContacts(displayNameStyle)
is ContactLookup -> lookupFromPredicate(predicate, displayNameStyle)
is ContactLookup -> lookupContact(predicate.contactId, displayNameStyle)
is MailLookup -> lookupFromMail(predicate.mailAddress, displayNameStyle)
is PhoneLookup -> lookupFromPhone(predicate.phoneNumber, displayNameStyle)
is NameLookup -> lookupFromName(predicate.partOfName, displayNameStyle)
Expand Down Expand Up @@ -117,14 +116,13 @@ internal class ContactQueries(
}
}

private fun lookupFromPredicate(
predicate: ContactLookup,
private fun lookupContact(
contactId: Long,
displayNameStyle: DisplayNameStyle
): Flow<List<PartialContact>> {
return contentResolver.runQueryFlow(
contentUri = Contacts.CONTENT_URI,
contentUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
projection = ContactsQuery.projection(displayNameStyle),
selection = buildColumnsToFetchSelection(predicate),
sortOrder = ContactsQuery.sortOrder(displayNameStyle)
).map { cursor ->
cursor.mapEachRow {
Expand Down Expand Up @@ -162,20 +160,6 @@ internal class ContactQueries(
}
}

private fun buildColumnsToFetchSelection(predicate: ContactLookup): String {
return buildString {
predicate.inContactIds?.let { contactIds ->
append("${Contacts._ID} IN ${valueIn(contactIds)}")
}
predicate.isFavorite?.let { isTrue ->
if (isNotEmpty()) {
append(" AND")
}
append(" ${Contacts.STARRED} = ${isTrue.toBoolInt()}")
}
}
}

private fun lookupFromPhone(
phoneNumber: PhoneNumber,
displayNameStyle: DisplayNameStyle
Expand Down Expand Up @@ -241,16 +225,16 @@ internal class ContactQueries(
val rawContacts = rawContactQueries.fetchRawContacts(contact)

val contactId = contact.contactId
var firstName= ""
var middleName= ""
var lastName= ""
var prefix= ""
var suffix= ""
var firstName = ""
var middleName = ""
var lastName = ""
var prefix = ""
var suffix = ""
var fullNameStyle: Int = FullNameStyle.UNDEFINED
var nickname= ""
var nickname = ""
var phoneticFirstName = ""
var phoneticMiddleName= ""
var phoneticLastName= ""
var phoneticMiddleName = ""
var phoneticLastName = ""
var phoneticNameStyle: Int = PhoneticNameStyle.UNDEFINED
var imageData: ImageData? = null
val phones = mutableSetOf<LabeledValue<PhoneNumber>>()
Expand All @@ -261,8 +245,8 @@ internal class ContactQueries(
val imAddresses = mutableSetOf<LabeledValue<ImAddress>>()
val relations = mutableSetOf<LabeledValue<Relation>>()
val postalAddresses = mutableSetOf<LabeledValue<PostalAddress>>()
var organization= ""
var jobTitle= ""
var organization = ""
var jobTitle = ""
var note: Note? = null
val groupIds = mutableListOf<GroupMembership>()
val customDataItems = mutableListOf<CustomDataItem>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal class ExistingContactOperationsFactory(
) {
suspend fun updateOperation(contact: MutableContact): List<ContentProviderOperation> {
val existingContact = contactQueries.queryContacts(
predicate = ContactPredicate.ContactLookup(inContactIds = listOf(contact.contactId)),
predicate = ContactPredicate.ContactLookup(contact.contactId),
columnsToFetch = contact.columns,
displayNameStyle = DisplayNameStyle.Primary
).first().firstOrNull() ?: return emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class ContactDetailsActivity : ComponentActivity() {

val contact = runBlocking {
contactStore.fetchContacts(
predicate = ContactLookup(listOf(contactId)),
predicate = ContactLookup(contactId),
columnsToFetch = allContactColumns()
).first().firstOrNull()
}
Expand Down

0 comments on commit ca57d81

Please sign in to comment.