diff --git a/R/spec-meta-bind-.R b/R/spec-meta-bind-.R index ee2ce2225..e44ab6fc5 100644 --- a/R/spec-meta-bind-.R +++ b/R/spec-meta-bind-.R @@ -15,6 +15,15 @@ test_select_bind_expr <- function( force(arrow) force(bind) + caller <- sys.function(-1) + caller_src <- utils::getSrcref(caller) + caller_ref <- paste0("") + + roxygen_bits <- grep("#' .*$", as.character(caller_src), value = TRUE) + docstring <- gsub("^ +#' *", "", roxygen_bits) + + header <- c(caller_ref, docstring) + cast_fun <- enquo(cast_fun) has_cast_fun <- !quo_is_null(cast_fun) cast_fun_expr <- if (has_cast_fun) expr({ @@ -49,6 +58,8 @@ test_select_bind_expr <- function( }) expr({ + !!!header + !!skip_dbitest_expr !!skip_expr placeholder_funs <- !!placeholder_funs_expr diff --git a/R/spec-meta-bind-arrow-stream.R b/R/spec-meta-bind-arrow-stream.R index 03ee90110..e60f01439 100644 --- a/R/spec-meta-bind-arrow-stream.R +++ b/R/spec-meta-bind-arrow-stream.R @@ -5,6 +5,11 @@ spec_meta_arrow_stream_bind <- list( arrow_stream_bind_return_value = function(ctx, con) { + # + # @return + # `dbBind()` returns the result set, + # invisibly, + # for queries issued by [dbSendQuery()] or [dbSendQueryArrow()] and placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -33,6 +38,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_too_many = function(ctx, con) { + # + # @section Failure modes: + # Binding too many placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -56,6 +64,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_not_enough = function(ctx, con) { + # + # or not enough values, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -76,6 +86,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_wrong_name = function(ctx, con) { + # + # or parameters with wrong names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -95,6 +107,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_named_param_unnamed_placeholders = function(ctx, con) { + # + # If the placeholders in the query are named, + # all parameter values must have names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -114,6 +129,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_named_param_empty_placeholders = function(ctx, con) { + # + # (which must not be empty placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -137,6 +154,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_unnamed_param_named_placeholders = function(ctx, con) { + # + # and vice versa, + # otherwise an error is raised. placeholder_funs <- get_placeholder_funs(ctx, requires_names = FALSE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -156,6 +176,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_premature_clear = function(ctx, con) { + # + # Calling `dbBind()` on a result set already cleared by [dbClearResult()] + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -172,6 +195,10 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_multi_row = function(ctx, con) { + # + # @section Specification: + # The elements of the `params` argument do not need to be scalars, + # vectors of arbitrary length placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -194,6 +221,12 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_multi_row_zero_length = function(ctx, con) { + # + # (including length 0) + # are supported. + # For queries, calling `dbFetch()` binding such parameters returns + # concatenated results, equivalent to binding and fetching for each set + # of values and connecting via [rbind()]. skip_if_not_dbitest(ctx, "1.7.99.12") placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -216,6 +249,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_repeated = function(ctx, con) { + # + # `dbBind()` also accepts repeated calls on the same result set + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -243,6 +279,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_repeated_untouched = function(ctx, con) { + # + # even if no results are fetched between calls to `dbBind()`, + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -266,6 +305,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_named_param_shuffle = function(ctx, con) { + # + # If the placeholders in the query are named, + # their order in the `params` argument is not important. placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -289,6 +331,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_integer = function(ctx, con) { + # + # At least the following data types are accepted on input (including [NA]): + # - [integer] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -315,6 +360,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_numeric = function(ctx, con) { + # + # - [numeric] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -341,6 +388,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_logical = function(ctx, con) { + # + # - [logical] for Boolean values placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -366,6 +415,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_character = function(ctx, con) { + # + # - [character] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -397,6 +448,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_character_escape = function(ctx, con) { + # + # (also with special characters such as spaces, newlines, quotes, and backslashes) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -432,6 +485,9 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_factor = function(ctx, con) { + # + # - [factor] (bound as character, + # with warning) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -463,6 +519,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_date = function(ctx, con) { + # + # - [Date] skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -493,6 +551,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_date_integer = function(ctx, con) { + # + # (also when stored internally as integer) skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -523,6 +583,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_timestamp = function(ctx, con) { + # + # - [POSIXct] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -553,6 +615,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_timestamp_lt = function(ctx, con) { + # + # - [POSIXlt] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -583,6 +647,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_time_seconds = function(ctx, con) { + # + # - [difftime] values skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -613,6 +679,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_time_hours = function(ctx, con) { + # + # (also with units other than seconds skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -643,6 +711,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_time_minutes_integer = function(ctx, con) { + # + # and with the value stored as integer) skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -673,6 +743,8 @@ spec_meta_arrow_stream_bind <- list( } }, arrow_stream_bind_blob = function(ctx, con) { + # + # - objects of type [blob::blob] skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check diff --git a/R/spec-meta-bind-arrow.R b/R/spec-meta-bind-arrow.R index f47372a8e..44c1b0d60 100644 --- a/R/spec-meta-bind-arrow.R +++ b/R/spec-meta-bind-arrow.R @@ -5,6 +5,11 @@ spec_meta_arrow_bind <- list( arrow_bind_return_value = function(ctx, con) { + # + # @return + # `dbBind()` returns the result set, + # invisibly, + # for queries issued by [dbSendQuery()] or [dbSendQueryArrow()] and placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -33,6 +38,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_too_many = function(ctx, con) { + # + # @section Failure modes: + # Binding too many placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -56,6 +64,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_not_enough = function(ctx, con) { + # + # or not enough values, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -76,6 +86,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_wrong_name = function(ctx, con) { + # + # or parameters with wrong names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -95,6 +107,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_multi_row_unequal_length = function(ctx, con) { + # + # or unequal length, + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -120,6 +135,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_named_param_unnamed_placeholders = function(ctx, con) { + # + # If the placeholders in the query are named, + # all parameter values must have names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -139,6 +157,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_named_param_empty_placeholders = function(ctx, con) { + # + # (which must not be empty placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -162,6 +182,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_unnamed_param_named_placeholders = function(ctx, con) { + # + # and vice versa, + # otherwise an error is raised. placeholder_funs <- get_placeholder_funs(ctx, requires_names = FALSE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -181,6 +204,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_premature_clear = function(ctx, con) { + # + # Calling `dbBind()` on a result set already cleared by [dbClearResult()] + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -197,6 +223,10 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_multi_row = function(ctx, con) { + # + # @section Specification: + # The elements of the `params` argument do not need to be scalars, + # vectors of arbitrary length placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -219,6 +249,12 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_multi_row_zero_length = function(ctx, con) { + # + # (including length 0) + # are supported. + # For queries, calling `dbFetch()` binding such parameters returns + # concatenated results, equivalent to binding and fetching for each set + # of values and connecting via [rbind()]. skip_if_not_dbitest(ctx, "1.7.99.12") placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -241,6 +277,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_repeated = function(ctx, con) { + # + # `dbBind()` also accepts repeated calls on the same result set + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -268,6 +307,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_repeated_untouched = function(ctx, con) { + # + # even if no results are fetched between calls to `dbBind()`, + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -291,6 +333,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_named_param_shuffle = function(ctx, con) { + # + # If the placeholders in the query are named, + # their order in the `params` argument is not important. placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -314,6 +359,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_integer = function(ctx, con) { + # + # At least the following data types are accepted on input (including [NA]): + # - [integer] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -340,6 +388,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_numeric = function(ctx, con) { + # + # - [numeric] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -366,6 +416,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_logical = function(ctx, con) { + # + # - [logical] for Boolean values placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -391,6 +443,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_character = function(ctx, con) { + # + # - [character] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -419,6 +473,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_character_escape = function(ctx, con) { + # + # (also with special characters such as spaces, newlines, quotes, and backslashes) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -451,6 +507,9 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_factor = function(ctx, con) { + # + # - [factor] (bound as character, + # with warning) skip_if_not_dbitest(ctx, "1.7.99.13") placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -480,6 +539,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_date = function(ctx, con) { + # + # - [Date] skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -507,6 +568,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_date_integer = function(ctx, con) { + # + # (also when stored internally as integer) skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -534,6 +597,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_timestamp = function(ctx, con) { + # + # - [POSIXct] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -561,6 +626,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_timestamp_lt = function(ctx, con) { + # + # - [POSIXlt] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -588,6 +655,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_time_seconds = function(ctx, con) { + # + # - [difftime] values skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -615,6 +684,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_time_hours = function(ctx, con) { + # + # (also with units other than seconds skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -642,6 +713,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_time_minutes_integer = function(ctx, con) { + # + # and with the value stored as integer) skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -669,6 +742,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_raw = function(ctx, con) { + # + # - lists of [raw] for blobs (with `NULL` entries for SQL NULL values) skip_if_not_dbitest(ctx, "1.7.99.14") skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) @@ -697,6 +772,8 @@ spec_meta_arrow_bind <- list( } }, arrow_bind_blob = function(ctx, con) { + # + # - objects of type [blob::blob] skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check diff --git a/R/spec-meta-bind-stream.R b/R/spec-meta-bind-stream.R index f698b1228..e1572b0da 100644 --- a/R/spec-meta-bind-stream.R +++ b/R/spec-meta-bind-stream.R @@ -5,6 +5,11 @@ spec_meta_stream_bind <- list( stream_bind_return_value = function(ctx, con) { + # + # @return + # `dbBind()` returns the result set, + # invisibly, + # for queries issued by [dbSendQuery()] or [dbSendQueryArrow()] and placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -33,6 +38,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_return_value_statement = function(ctx, con) { + # + # also for data manipulation statements issued by + # [dbSendStatement()]. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -62,6 +70,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_too_many = function(ctx, con) { + # + # @section Failure modes: + # Binding too many placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -85,6 +96,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_not_enough = function(ctx, con) { + # + # or not enough values, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -105,6 +118,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_wrong_name = function(ctx, con) { + # + # or parameters with wrong names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -124,6 +139,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_named_param_unnamed_placeholders = function(ctx, con) { + # + # If the placeholders in the query are named, + # all parameter values must have names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -143,6 +161,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_named_param_empty_placeholders = function(ctx, con) { + # + # (which must not be empty placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -166,6 +186,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_named_param_na_placeholders = function(ctx, con) { + # + # or `NA`), placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -189,6 +211,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_unnamed_param_named_placeholders = function(ctx, con) { + # + # and vice versa, + # otherwise an error is raised. placeholder_funs <- get_placeholder_funs(ctx, requires_names = FALSE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -208,6 +233,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_premature_clear = function(ctx, con) { + # + # Calling `dbBind()` on a result set already cleared by [dbClearResult()] + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -224,6 +252,10 @@ spec_meta_stream_bind <- list( } }, stream_bind_multi_row = function(ctx, con) { + # + # @section Specification: + # The elements of the `params` argument do not need to be scalars, + # vectors of arbitrary length placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -246,6 +278,12 @@ spec_meta_stream_bind <- list( } }, stream_bind_multi_row_zero_length = function(ctx, con) { + # + # (including length 0) + # are supported. + # For queries, calling `dbFetch()` binding such parameters returns + # concatenated results, equivalent to binding and fetching for each set + # of values and connecting via [rbind()]. skip_if_not_dbitest(ctx, "1.7.99.12") placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -268,6 +306,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_multi_row_statement = function(ctx, con) { + # + # For data manipulation statements, `dbGetRowsAffected()` returns the + # total number of rows affected if binding non-scalar parameters. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -292,6 +333,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_repeated = function(ctx, con) { + # + # `dbBind()` also accepts repeated calls on the same result set + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -319,6 +363,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_repeated_statement = function(ctx, con) { + # + # and data manipulation statements, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -348,6 +394,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_repeated_untouched = function(ctx, con) { + # + # even if no results are fetched between calls to `dbBind()`, + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -371,6 +420,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_repeated_untouched_statement = function(ctx, con) { + # + # and data manipulation statements. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -396,6 +447,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_named_param_shuffle = function(ctx, con) { + # + # If the placeholders in the query are named, + # their order in the `params` argument is not important. placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -419,6 +473,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_integer = function(ctx, con) { + # + # At least the following data types are accepted on input (including [NA]): + # - [integer] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -445,6 +502,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_numeric = function(ctx, con) { + # + # - [numeric] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -471,6 +530,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_logical = function(ctx, con) { + # + # - [logical] for Boolean values placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -496,6 +557,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_character = function(ctx, con) { + # + # - [character] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -527,6 +590,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_character_escape = function(ctx, con) { + # + # (also with special characters such as spaces, newlines, quotes, and backslashes) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -562,6 +627,9 @@ spec_meta_stream_bind <- list( } }, stream_bind_factor = function(ctx, con) { + # + # - [factor] (bound as character, + # with warning) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -593,6 +661,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_date = function(ctx, con) { + # + # - [Date] skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -623,6 +693,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_date_integer = function(ctx, con) { + # + # (also when stored internally as integer) skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -653,6 +725,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_timestamp = function(ctx, con) { + # + # - [POSIXct] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -683,6 +757,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_timestamp_lt = function(ctx, con) { + # + # - [POSIXlt] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -713,6 +789,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_time_seconds = function(ctx, con) { + # + # - [difftime] values skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -743,6 +821,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_time_hours = function(ctx, con) { + # + # (also with units other than seconds skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -773,6 +853,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_time_minutes_integer = function(ctx, con) { + # + # and with the value stored as integer) skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -803,6 +885,8 @@ spec_meta_stream_bind <- list( } }, stream_bind_blob = function(ctx, con) { + # + # - objects of type [blob::blob] skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check diff --git a/R/spec-meta-bind.R b/R/spec-meta-bind.R index 81973be60..ce0b4a266 100644 --- a/R/spec-meta-bind.R +++ b/R/spec-meta-bind.R @@ -5,6 +5,11 @@ spec_meta_bind <- list( bind_return_value = function(ctx, con) { + # + # @return + # `dbBind()` returns the result set, + # invisibly, + # for queries issued by [dbSendQuery()] or [dbSendQueryArrow()] and placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -33,6 +38,9 @@ spec_meta_bind <- list( } }, bind_return_value_statement = function(ctx, con) { + # + # also for data manipulation statements issued by + # [dbSendStatement()]. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -62,6 +70,9 @@ spec_meta_bind <- list( } }, bind_too_many = function(ctx, con) { + # + # @section Failure modes: + # Binding too many placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -85,6 +96,8 @@ spec_meta_bind <- list( } }, bind_not_enough = function(ctx, con) { + # + # or not enough values, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -105,6 +118,8 @@ spec_meta_bind <- list( } }, bind_wrong_name = function(ctx, con) { + # + # or parameters with wrong names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -124,6 +139,9 @@ spec_meta_bind <- list( } }, bind_multi_row_unequal_length = function(ctx, con) { + # + # or unequal length, + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -149,6 +167,9 @@ spec_meta_bind <- list( } }, bind_named_param_unnamed_placeholders = function(ctx, con) { + # + # If the placeholders in the query are named, + # all parameter values must have names placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -168,6 +189,8 @@ spec_meta_bind <- list( } }, bind_named_param_empty_placeholders = function(ctx, con) { + # + # (which must not be empty placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -191,6 +214,8 @@ spec_meta_bind <- list( } }, bind_named_param_na_placeholders = function(ctx, con) { + # + # or `NA`), placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -214,6 +239,9 @@ spec_meta_bind <- list( } }, bind_unnamed_param_named_placeholders = function(ctx, con) { + # + # and vice versa, + # otherwise an error is raised. placeholder_funs <- get_placeholder_funs(ctx, requires_names = FALSE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -233,6 +261,9 @@ spec_meta_bind <- list( } }, bind_premature_clear = function(ctx, con) { + # + # Calling `dbBind()` on a result set already cleared by [dbClearResult()] + # also raises an error. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -249,6 +280,10 @@ spec_meta_bind <- list( } }, bind_multi_row = function(ctx, con) { + # + # @section Specification: + # The elements of the `params` argument do not need to be scalars, + # vectors of arbitrary length placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -271,6 +306,12 @@ spec_meta_bind <- list( } }, bind_multi_row_zero_length = function(ctx, con) { + # + # (including length 0) + # are supported. + # For queries, calling `dbFetch()` binding such parameters returns + # concatenated results, equivalent to binding and fetching for each set + # of values and connecting via [rbind()]. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -292,6 +333,9 @@ spec_meta_bind <- list( } }, bind_multi_row_statement = function(ctx, con) { + # + # For data manipulation statements, `dbGetRowsAffected()` returns the + # total number of rows affected if binding non-scalar parameters. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -316,6 +360,9 @@ spec_meta_bind <- list( } }, bind_repeated = function(ctx, con) { + # + # `dbBind()` also accepts repeated calls on the same result set + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -343,6 +390,8 @@ spec_meta_bind <- list( } }, bind_repeated_statement = function(ctx, con) { + # + # and data manipulation statements, placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -372,6 +421,9 @@ spec_meta_bind <- list( } }, bind_repeated_untouched = function(ctx, con) { + # + # even if no results are fetched between calls to `dbBind()`, + # for both queries placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -395,6 +447,8 @@ spec_meta_bind <- list( } }, bind_repeated_untouched_statement = function(ctx, con) { + # + # and data manipulation statements. placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected @@ -420,6 +474,9 @@ spec_meta_bind <- list( } }, bind_named_param_shuffle = function(ctx, con) { + # + # If the placeholders in the query are named, + # their order in the `params` argument is not important. placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -443,6 +500,9 @@ spec_meta_bind <- list( } }, bind_integer = function(ctx, con) { + # + # At least the following data types are accepted on input (including [NA]): + # - [integer] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -469,6 +529,8 @@ spec_meta_bind <- list( } }, bind_numeric = function(ctx, con) { + # + # - [numeric] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -495,6 +557,8 @@ spec_meta_bind <- list( } }, bind_logical = function(ctx, con) { + # + # - [logical] for Boolean values placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -520,6 +584,8 @@ spec_meta_bind <- list( } }, bind_character = function(ctx, con) { + # + # - [character] placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -548,6 +614,8 @@ spec_meta_bind <- list( } }, bind_character_escape = function(ctx, con) { + # + # (also with special characters such as spaces, newlines, quotes, and backslashes) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -580,6 +648,9 @@ spec_meta_bind <- list( } }, bind_factor = function(ctx, con) { + # + # - [factor] (bound as character, + # with warning) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check for (placeholder_fun in placeholder_funs) { @@ -608,6 +679,8 @@ spec_meta_bind <- list( } }, bind_date = function(ctx, con) { + # + # - [Date] skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -635,6 +708,8 @@ spec_meta_bind <- list( } }, bind_date_integer = function(ctx, con) { + # + # (also when stored internally as integer) skip_if(!isTRUE(ctx$tweaks$date_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -662,6 +737,8 @@ spec_meta_bind <- list( } }, bind_timestamp = function(ctx, con) { + # + # - [POSIXct] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -689,6 +766,8 @@ spec_meta_bind <- list( } }, bind_timestamp_lt = function(ctx, con) { + # + # - [POSIXlt] timestamps skip_if(!isTRUE(ctx$tweaks$timestamp_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -716,6 +795,8 @@ spec_meta_bind <- list( } }, bind_time_seconds = function(ctx, con) { + # + # - [difftime] values skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -743,6 +824,8 @@ spec_meta_bind <- list( } }, bind_time_hours = function(ctx, con) { + # + # (also with units other than seconds skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -770,6 +853,8 @@ spec_meta_bind <- list( } }, bind_time_minutes_integer = function(ctx, con) { + # + # and with the value stored as integer) skip_if(!isTRUE(ctx$tweaks$time_typed)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -797,6 +882,8 @@ spec_meta_bind <- list( } }, bind_raw = function(ctx, con) { + # + # - lists of [raw] for blobs (with `NULL` entries for SQL NULL values) skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check @@ -824,6 +911,8 @@ spec_meta_bind <- list( } }, bind_blob = function(ctx, con) { + # + # - objects of type [blob::blob] skip_if(isTRUE(ctx$tweaks$omit_blob_tests)) placeholder_funs <- get_placeholder_funs(ctx) is_null_check <- ctx$tweaks$is_null_check diff --git a/tests/testthat/helper-dev.R b/tests/testthat/helper-dev.R index 8e46c0827..1b05d0d52 100644 --- a/tests/testthat/helper-dev.R +++ b/tests/testthat/helper-dev.R @@ -65,6 +65,7 @@ inline_meta_tests <- function(arrow, bind, path) { text[[1]] <- paste0("spec_meta_", infix, "bind <- ", text[[1]]) # FIXME: Why does constructive not handle this? text <- gsub('r"[\\]"', '"\\\\"', text, fixed = TRUE) + text <- gsub('^( *)"(.*)"$', "\\1# \\2", text) text <- c( "# Generated by helper-dev.R, do not edit by hand", "# Sources: R/spec-meta-bind-.R, R/spec-meta-bind-expr.R, R/spec-meta-bind-runner.R",