diff --git a/R/bq-perform.R b/R/bq-perform.R index b478b1f4..b9eaa8ca 100644 --- a/R/bq-perform.R +++ b/R/bq-perform.R @@ -72,6 +72,8 @@ bq_perform_extract <- function( check_bool(print_header) check_string(billing) + labels <- check_labels(getOption("bigrquery.labels")) + url <- bq_path(billing, jobs = "") body <- list( configuration = list( @@ -81,7 +83,8 @@ bq_perform_extract <- function( destinationFormat = unbox(destination_format), compression = unbox(compression), printHeader = unbox(print_header) - ) + ), + labels = labels ) ) @@ -140,6 +143,8 @@ bq_perform_upload <- function( check_string(billing) json_digits <- check_digits(json_digits) + labels <- check_labels(getOption("bigrquery.labels")) + load <- list( sourceFormat = unbox(source_format), destinationTable = tableReference(x), @@ -154,11 +159,16 @@ bq_perform_upload <- function( load$autodetect <- unbox(TRUE) } - metadata <- list(configuration = list(load = load)) + metadata <- list( + configuration = list( + load = load, + labels = labels + ) + ) metadata <- bq_body(metadata, ...) metadata <- list( "type" = "application/json; charset=UTF-8", - "content" = jsonlite::toJSON(metadata, pretty = TRUE, digits = json_digits) + "content" = jsonlite::toJSON(metadata, auto_unbox = TRUE, pretty = TRUE, digits = json_digits) ) if (source_format == "NEWLINE_DELIMITED_JSON") { @@ -261,6 +271,8 @@ bq_perform_load <- function( check_string(create_disposition) check_string(write_disposition) + labels <- check_labels(getOption("bigrquery.labels")) + load <- list( sourceUris = as.list(source_uris), sourceFormat = unbox(source_format), @@ -280,7 +292,12 @@ bq_perform_load <- function( load$autodetect <- TRUE } - body <- list(configuration = list(load = load)) + body <- list( + configuration = list( + load = load, + labels = labels + ) + ) url <- bq_path(billing, jobs = "") res <- bq_post( @@ -332,6 +349,8 @@ bq_perform_query <- function( check_bool(use_legacy_sql) check_string(priority) + labels <- check_labels(getOption("bigrquery.labels")) + query <- list( query = unbox(query), useLegacySql = unbox(use_legacy_sql), @@ -357,7 +376,12 @@ bq_perform_query <- function( } url <- bq_path(billing, jobs = "") - body <- list(configuration = list(query = query)) + body <- list( + configuration = list( + query = query, + labels = labels + ) + ) res <- bq_post( url, @@ -383,9 +407,16 @@ bq_perform_query_dry_run <- function( parameters = parameters, use_legacy_sql = use_legacy_sql ) + labels <- check_labels(getOption("bigrquery.labels")) url <- bq_path(billing, jobs = "") - body <- list(configuration = list(query = query, dryRun = unbox(TRUE))) + body <- list( + configuration = list( + query = query, + labels = labels, + dryRun = unbox(TRUE) + ) + ) res <- bq_post( url, @@ -412,8 +443,16 @@ bq_perform_query_schema <- function( use_legacy_sql = FALSE ) + labels <- check_labels(getOption("bigrquery.labels")) + url <- bq_path(billing, jobs = "") - body <- list(configuration = list(query = query, dryRun = unbox(TRUE))) + body <- list( + configuration = list( + query = query, + labels = labels, + dryRun = unbox(TRUE) + ) + ) res <- bq_post( url, @@ -463,6 +502,7 @@ bq_perform_copy <- function( ) { billing <- billing %||% dest$project url <- bq_path(billing, jobs = "") + labels <- check_labels(getOption("bigrquery.labels")) body <- list( configuration = list( @@ -471,7 +511,8 @@ bq_perform_copy <- function( destinationTable = tableReference(dest), createDisposition = unbox(create_disposition), writeDisposition = unbox(write_disposition) - ) + ), + labels = labels ) ) diff --git a/R/utils.R b/R/utils.R index d0b1b14b..5876e4a8 100644 --- a/R/utils.R +++ b/R/utils.R @@ -85,3 +85,15 @@ as_query <- function(x, error_arg = caller_arg(x), error_call = caller_env()) { has_bigrquerystorage <- function() { is_installed("bigrquerystorage") } + +check_labels <- function(labels) { + if (is.null(labels) || length(labels) == 0) { + return(NULL) + } + + if (!is.list(labels) || any(names2(labels) == "")) { + cli::cli_abort("Labels must be a named list.") + } + + labels +} diff --git a/R/zzz.R b/R/zzz.R index e3b1c8e2..043e5675 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -23,7 +23,8 @@ op <- options() defaults <- list( bigrquery.quiet = NA, - bigrquery.page.size = 1e4 + bigrquery.page.size = 1e4, + bigrquery.labels = NULL ) toset <- !(names(defaults) %in% names(op)) if (any(toset)) { diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index c9a644ba..fe73cbcb 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -5,3 +5,17 @@ test_that("bq_check_namespace() works", { error = TRUE ) }) + +test_that("check_labels() accepts valid labels and NULL-like inputs", { + expect_null(check_labels(NULL)) + expect_null(check_labels(list())) + + expect_equal(check_labels(list(env = "prod")), list(env = "prod")) + expect_equal(check_labels(list(env = "prod", team = "data")), list(env = "prod", team = "data")) + expect_equal(check_labels(list(env = "")), list(env = "")) +}) + +test_that("check_labels() errors on invalid inputs", { + expect_error(check_labels(c(env = "prod")), "named list") + expect_error(check_labels(list("no-name")), "named list") +})