Skip to content

Commit

Permalink
Closes #42 Document: howto-update-data-sets
Browse files Browse the repository at this point in the history
  • Loading branch information
vestrel00 committed Nov 28, 2021
1 parent 3160b7b commit 20c8da3
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 10 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/contacts/core/Update.kt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ interface Update {
* them "blanks") to exist. The native Contacts app does not allow insertion of new RawContacts
* without at least one data row. It also deletes blanks on update. Despite seemingly not
* allowing blanks, the native Contacts app shows them.
*
* Note that blank data are always deleted. For example, if all properties of an email are all
* null or blank, then the email is deleted. This behavior cannot be modified.
*/
fun deleteBlanks(deleteBlanks: Boolean): Update

Expand Down
10 changes: 6 additions & 4 deletions core/src/main/java/contacts/core/data/DataUpdate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import contacts.core.util.unsafeLazy
/**
* Updates one or more Profile OR non-Profile (depending on instance) data rows in the data table.
*
* Blank data ([MutableCommonDataEntity.isBlank] will be deleted.
* Blank data ([MutableCommonDataEntity.isBlank]) will be deleted. For example, if all properties
* of an email are all null or blank, then the email is deleted. This is the same behavior as the
* native Contacts app. This behavior cannot be modified.
*
* Note that in cases where blank data are deleted, existing RawContact instances will still have
* references to the deleted data instance. The RawContact instances must be refreshed to get the
* most up-to-date data sets.
* Note that in cases where blank data are deleted, existing RawContact instances (in memory) will
* still have references to the deleted data instance. The RawContact instances (in memory) must be
* refreshed to get the most up-to-date data sets.
*
* Updating data that has already been deleted may return a successful result. However, no update
* actually occurred in the Content Provider Data table because the data row no longer existed.
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/contacts/core/profile/ProfileUpdate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ interface ProfileUpdate {
* them "blanks") to exist. The native Contacts app does not allow insertion of new RawContacts
* without at least one data row. It also deletes blanks on update. Despite seemingly not
* allowing blanks, the native Contacts app shows them.
*
* Note that blank data are always deleted. For example, if all properties of an email are all
* null or blank, then the email is deleted. This is the same behavior as the native Contacts
* app. This is the same behavior as the native Contacts app. This behavior cannot be modified.
*/
fun deleteBlanks(deleteBlanks: Boolean): ProfileUpdate

Expand Down
9 changes: 7 additions & 2 deletions howto/howto-query-data-sets.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# How do I get a list of specific data kinds?

This library provides the `DataQuery` API that allows you to get a list of specific data kinds.
This library provides the `DataQuery` API that allows you to get a list of specific data kinds
directly without having to get them from Contacts/RawContacts.

An instance of the `DataQuery` API is obtained by,

```kotlin
val query = Contacts(context).data().query()
```

> To retrieve all kinds of data via Contacts/RawContacts, read
> [How do I get a list of contacts in the simplest way?](/howto/howto-query-contacts.md)
> and [How do I get a list of contacts in a more advanced way?](/howto/howto-query-contacts-advanced.md)
## Common data queries

The `DataQuery` API provides instances of `CommonDataQuery` for every data kind in the library.
Expand Down Expand Up @@ -201,7 +206,7 @@ You may, of course, use other permission handling libraries or just do it yourse
## Profile data

The `DataQuery` API also supports querying the Profile (device owner) contact data. To get an
instance of this API for Profile queries,
instance of this API for Profile data queries,

```kotlin
val profileDataQuery = Contacts(context).profile().data().query()
Expand Down
4 changes: 4 additions & 0 deletions howto/howto-update-contacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ The API allows you to specify if you want the update operation to delete blank c

For more info, read [How do I learn more about "blank" contacts?](/howto/howto-learn-more-about-blank-contacts.md)

**Note** that blank data are always deleted. For example, if all properties of an email are all null
or blank, then the email is deleted. This is the same behavior as the native Contacts app. This
behavior cannot be modified.

## Including only specific data

To include only the given set of fields (data) in each of the update operation,
Expand Down
163 changes: 159 additions & 4 deletions howto/howto-update-data-sets.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,162 @@
# How do I update existing sets of data?

TODO
This library provides the `DataUpdate` API that allows you to update a list of any data kinds
directly without having to update them via Contacts/RawContacts.

Note for people looking at this file, the code and documentation within the code is already complete.
I'm in the process of writing these howto pages to provide examples and more explanations on how
to use the APIs provided in this library.
An instance of the `DataUpdate` API is obtained by,

```kotlin
val update = Contacts(context).data().update()
```

> To update all kinds of data via Contacts/RawContacts, read [How do I update contacts?](/howto/howto-update-contacts.md)
## A basic update

To update a set of `MutableCommonDataEntity`,

```kotlin
val updateResult = Contacts(context)
.data()
.update()
.data(dataSet)
.commit()
```

## Blank data are deleted

Blank data are always deleted. For example, if all properties of an email are all null or blank,
then the email is deleted. This is the same behavior as the native Contacts app. This behavior
cannot be modified.

## Including only specific data

To include only the given set of fields (data) in each of the update operation,

```kotlin
.include(fields)
```

For example, to only include email fields,

```kotlin
.include(Fields.Email.all)
```

For more info, read [How do I include only the data that I want?](/howto/howto-include-only-desired-data.md)

## Executing the update

To execute the update,

```kotlin
.commit()
```

### Handling the update result

The `commit` function returns a `Result`,

```kotlin
val contactsApi = Contacts(context)
val mutableEmail = email.toMutableEmail().apply { ... }
val mutablePhone = phone.toMutablePhone().apply { ... }

val updateResult = contactsApi
.date()
.update()
.data(mutableEmail, mutablePhone)
.commit()
```

To check if all updates succeeded,

```kotlin
val allUpdatesSuccessful = updateResult.isSuccessful
```

To check if a particular update succeeded,

```kotlin
val emailUpdateSuccessful = updateResult.isSuccessful(mutableEmail)
```

Once you have performed the updates, you can retrieve the updated data references via the `DataQuery` API,

```kotlin
val updatedEmail = contactsApi
.data()
.query()
.emails()
.where(Fields.Email.Id equalTo emailId)
.find()
```

> For more info, read [How do I get a list of specific data kinds?](/howto/howto-query-data-sets.md)
Alternatively, you may use the extensions provided in `DataRefresh`.

To get the updated phone,

```kotlin
val updatedPhone = phone.refresh(contactsApi)
```

## Cancelling the update

To cancel an update amid execution,

```kotlin
.commit { returnTrueIfUpdateShouldBeCancelled() }
```

The `commit` function optionally takes in a function that, if it returns true, will cancel update
processing as soon as possible. The function is called numerous times during update processing to
check if processing should stop or continue. This gives you the option to cancel the update.

For example, to automatically cancel the update inside a Kotlin coroutine when the coroutine is cancelled,

```kotlin
launch {
withContext(coroutineContext) {
val updateResult = update.commit { !isActive }
}
}
```

## Performing the update and result processing asynchronously

Updates are executed when the `commit` function is invoked. The work is done in the same thread as
the call-site. This may result in a choppy UI.

To perform the work in a different thread, use the Kotlin coroutine extensions provided in the `async` module.
For more info, read [How do I use the async module to simplify executing work outside of the UI thread using coroutines?](/howto/howto-use-api-with-async-execution.md)

You may, of course, use other multi-threading libraries or just do it yourself =)

> Extensions for Kotlin Flow and RxJava are also in the v1 roadmap.
## Performing the update with permission

Updates require the `android.permission.WRITE_CONTACTS` permissions. If not granted, the update
will do nothing and return a failed result.

To perform the update with permission, use the extensions provided in the `permissions` module.
For more info, read [How do I use the permissions module to simplify permission handling using coroutines?](/howto/howto-use-api-with-permissions-handling.md)

You may, of course, use other permission handling libraries or just do it yourself =)

## Profile data

The `DataUpdate` API also supports updating the Profile (device owner) contact data. To get an
instance of this API for Profile data updates,

```kotlin
val profileDataUpdate = Contacts(context).profile().data().update()
```

All queries will be limited to the Profile, whether it exists or not.

## Custom data support

The `DataUpdate` API supports custom data. For more info, read [How do I use update APIs to update custom data?](/howto/howto-update-custom-data.md)
4 changes: 4 additions & 0 deletions howto/howto-update-profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ The API allows you to specify if you want the update operation to delete blank R

For more info, read [How do I learn more about "blank" contacts?](/howto/howto-learn-more-about-blank-contacts.md)

**Note** that blank data are always deleted. For example, if all properties of an email are all null
or blank, then the email is deleted. This is the same behavior as the native Contacts app. This
behavior cannot be modified.

## Including only specific data

To include only the given set of fields (data) in each of the update operation,
Expand Down

0 comments on commit 20c8da3

Please sign in to comment.