---
title: "Working with Bulk API"
author: "Steven M. Mortimer"
date: "2018-03-12"
output:
  rmarkdown::html_vignette:
    toc: true
    toc_depth: 4
    keep_md: true
vignette: >
  %\VignetteIndexEntry{Working with Bulk API}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, echo = FALSE}
NOT_CRAN <- identical(tolower(Sys.getenv("NOT_CRAN")), "true")
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  purl = NOT_CRAN,
  eval = NOT_CRAN
)
```

### Using the Bulk API

First, load the `salesforcer` package and login. 

```{r auth, include = FALSE}
suppressWarnings(suppressMessages(library(dplyr)))
suppressWarnings(suppressMessages(library(here)))
library(salesforcer)
token_path <- here::here("tests", "testthat", "salesforcer_token.rds")
suppressMessages(sf_auth(token = token_path, verbose = FALSE))
```

```{r load-package, eval=FALSE}
suppressWarnings(suppressMessages(library(dplyr)))
library(salesforcer)
sf_auth()
```

For really large inserts, updates, deletes, upserts, queries you can just add 
"api_type" = "Bulk" to most functions to get the benefits of using the Bulk API 
instead of the SOAP or REST APIs. Here is the difference in using the REST API vs. 
the Bulk API to do an insert:

```{r}
n <- 2
new_contacts <- tibble(FirstName = rep("Test", n),
                       LastName = paste0("Contact-Create-", 1:n))
# REST
rest_created_records <- sf_create(new_contacts, object_name="Contact", api_type="REST")
rest_created_records
# Bulk
bulk_created_records <- sf_create(new_contacts, object_name="Contact", api_type="Bulk 1.0")
bulk_created_records
```

There are some differences in the way each API returns response information; however, 
the end result is exactly the same for these two calls. Also, note that this 
package utilizes the Bulk 2.0 API for most bulk calls except for bulk queries 
since Salesforce has not yet implemented it in 2.0. 

Here is a simple workflow of adding, querying, and deleting records using the Bulk 1.0 API.

```{r}
# just add api_type="Bulk 1.0" or api_type="Bulk 2.0" to most calls!
# create bulk
object <- "Contact"
n <- 2
new_contacts <- tibble(FirstName = rep("Test", n),
                       LastName = paste0("Contact-Create-", 1:n))
created_records <- sf_create(new_contacts, object_name=object, api_type="Bulk 1.0")
created_records

# query bulk
my_soql <- sprintf("SELECT Id,
                           FirstName, 
                           LastName
                    FROM Contact 
                    WHERE Id in ('%s')", 
                   paste0(created_records$Id , collapse="','"))

queried_records <- sf_query(my_soql, object_name=object, api_type="Bulk 1.0")
queried_records

# delete bulk
deleted_records <- sf_delete(queried_records$Id, object_name=object, api_type="Bulk 1.0")
deleted_records
```
