-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix #156: entitylist_update family changed to entity-management
- Loading branch information
Showing
13 changed files
with
556 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
#' Creates exactly one Entity in the Dataset. | ||
#' | ||
#' `r lifecycle::badge("experimental")` | ||
#' | ||
#' ### Creating a single Entity | ||
#' | ||
#' For creating a single Entity, include | ||
#' | ||
#' - An optional `uuid`. If skipped, Central will create a UUID for the Entity. | ||
#' - The Entity `label` must be non-empty. | ||
#' - A named list `data` representing the Entity's fields. The value type of | ||
#' all properties is string. | ||
#' | ||
#' `uuid = "..."` | ||
#' `label = "John Doe"` | ||
#' `data = list("firstName" = "John", "age" = "22")` | ||
#' | ||
#' This translates to JSON | ||
#' | ||
#' `{ "label": "John Doe", "data": { "firstName": "John", "age": "22" } }` | ||
#' | ||
#' ### Creating multiple Entities | ||
#' | ||
#' For creating multiple Entities in bulk, the request body takes an array | ||
#' entities containing a list of Entity objects as described above. | ||
#' The bulk entity version also takes a source property with a required name | ||
#' field and optional size, for example to capture the file name and size of a | ||
#' bulk upload source (in MB). | ||
#' | ||
#' ``` | ||
#' data=list( | ||
#' "entities" = c( | ||
#' list("label" = "Entity 1", "data" = list("field1" = "value1")), | ||
#' list("label" = "Entity 2", "data" = list("field1" = "value2")) | ||
#' ), | ||
#' "source" = list("name" = "file.csv", "size" = 100) | ||
#' ) | ||
#' ``` | ||
#' | ||
#' This translates to JSON | ||
#' | ||
#' `{ "entities": [...], "source": {"name": "file.csv", "size": 100} }` | ||
#' | ||
#' | ||
#' You can provide `notes` to store the metadata about the request. | ||
#' The metadata is included in the POST request as header `X-Action-Notes` and | ||
#' can retrieved using Entity Audit Log. | ||
#' | ||
#' | ||
#' @template tpl-structure-nested | ||
#' @template tpl-names-cleaned-top-level | ||
#' @template tpl-auth-missing | ||
#' @template tpl-compat-2022-3 | ||
#' @template param-pid | ||
#' @template param-did | ||
#' @param label (character) The Entity label which must be a non-empty string. | ||
#' Default: `""`. | ||
#' @param notes (character) Metadata about the request which can be retrieved | ||
#' using the entity audit log. | ||
#' Default: `""`. | ||
#' @param data (list) A named list of Entity properties to create a single | ||
#' Entity, or a nested list with an array of Entity data to create multiple | ||
#' Entities. See details for the exact format. | ||
#' Default: `list()`. | ||
#' @template param-url | ||
#' @template param-auth | ||
#' @template param-retries | ||
#' @template param-odkcv | ||
#' @template param-orders | ||
#' @template param-tz | ||
#' @return A nested list identical to the return value of `entity_detail`. | ||
#' See <https://docs.getodk.org/central-api-entity-management/#creating-entities> | ||
#' for the full schema. | ||
#' Top level list elements are renamed from ODK's `camelCase` to `snake_case`. | ||
#' Nested list elements have the original `camelCase`. | ||
# nolint start | ||
#' @seealso \url{https://docs.getodk.org/central-api-entity-management/#creating-entities} | ||
# nolint end | ||
#' @family entity-management | ||
#' @export | ||
#' @examples | ||
#' \dontrun{ | ||
#' # See vignette("setup") for setup and authentication options | ||
#' # ruODK::ru_setup(svc = "....svc", un = "[email protected]", pw = "...") | ||
#' | ||
#' el <- entitylist_list() | ||
#' | ||
#' # Entity List name (dataset ID, did) | ||
#' did <- el$name[1] | ||
#' | ||
#' # All Entities of Entity List | ||
#' en <- entity_list(did = did) | ||
#' | ||
#' # Create a single entity | ||
#' ec <- entity_create( | ||
#' did = did, | ||
#' label = "Entity label", | ||
#' notes = "Metadata about the created entity", | ||
#' data = list("field1" = "value1", "field2" = "value1") | ||
#' ) | ||
#' ec | ||
#' | ||
#' # Create multiple entities | ||
#' eb <- entity_create( | ||
#' did = did, | ||
#' notes = "Metadata about the created entities", | ||
#' data = list( | ||
#' "entities" = c( | ||
#' list("label" = "Entity 1", "data" = list("field1" = "value1")), | ||
#' list("label" = "Entity 2", "data" = list("field1" = "value2")) | ||
#' ), | ||
#' "source" = list("name" = "file.csv", "size" = 100) | ||
#' ) | ||
#' ) | ||
#' eb | ||
#' } | ||
entity_create <- function(pid = get_default_pid(), | ||
did = "", | ||
label = "", | ||
uuid = NULL, | ||
notes = "", | ||
data = list(), | ||
url = get_default_url(), | ||
un = get_default_un(), | ||
pw = get_default_pw(), | ||
retries = get_retries(), | ||
odkc_version = get_default_odkc_version(), | ||
orders = c( | ||
"YmdHMS", | ||
"YmdHMSz", | ||
"Ymd HMS", | ||
"Ymd HMSz", | ||
"Ymd", | ||
"ymd" | ||
), | ||
tz = get_default_tz()) { | ||
yell_if_missing(url, un, pw, pid = pid, did = did) | ||
|
||
if (odkc_version |> semver_lt("2022.3")) { | ||
ru_msg_warn("entity_create is supported from v2022.3") | ||
} | ||
|
||
# Triage whether data is single or multiple entity | ||
body <- list() | ||
|
||
if (label == "") { | ||
ru_msg_info("Empty label: creating multiple entities.") | ||
|
||
# Gate check: data must have key "entities" | ||
if (!("entities" %in% names(data))) { | ||
ru_msg_abort("Malformed argument 'data': Must include 'entities'.") | ||
} | ||
|
||
body <- data | ||
} else { | ||
ru_msg_info("Non-empty label: creating single entity.") | ||
# If uuid is not NULL, include in body | ||
if (!is.null(uuid)) { | ||
body <- list("uuid" = uuid, "label" = label, "data" = data) | ||
} else { | ||
body <- list("label" = label, "data" = data) | ||
} | ||
} | ||
|
||
pth <- glue::glue( | ||
"v1/projects/{pid}/datasets/{URLencode(did, reserved = TRUE)}/", | ||
"entities/" | ||
) | ||
|
||
httr::RETRY( | ||
"POST", | ||
httr::modify_url(url, path = pth), | ||
httr::add_headers("Accept" = "application/json", "X-Action-Notes" = notes), | ||
encode = "json", | ||
body = body, | ||
httr::authenticate(un, pw), | ||
times = retries | ||
) |> | ||
yell_if_error(url, un, pw) |> | ||
httr::content(encoding = "utf-8") |> | ||
janitor::clean_names() | ||
} | ||
|
||
# usethis::use_test("entity_create") # nolint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.