From 0712f29ebe769fe92c79c86f0b36a70cc7a4f4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Wed, 15 Sep 2021 09:32:35 +0200 Subject: [PATCH] Single dispatch for dbQuoteLiteral() --- DESCRIPTION | 2 +- R/quote.R | 129 ++++++++++++++++++--------------------------------- man/quote.Rd | 31 +------------ 3 files changed, 48 insertions(+), 114 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a53b17c9..812b7610 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -35,7 +35,7 @@ Imports: bit64, blob (>= 1.2.0), DBI (>= 1.1.0), - hms (>= 0.5.0), + hms (>= 1.0.0), lubridate, methods, Rcpp (>= 1.0.7), diff --git a/R/quote.R b/R/quote.R index 5253dc1e..28d32a55 100644 --- a/R/quote.R +++ b/R/quote.R @@ -111,91 +111,52 @@ as_table <- function(catalog, schema, table) { } #' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "logical"), function(conn, x, ...) { - ret <- as.character(x) - ret[is.na(ret)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "integer"), function(conn, x, ...) { - ret <- paste0(as.character(x), "::int4") - ret[is.na(x)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "numeric"), function(conn, x, ...) { - ret <- paste0(as.character(x), "::float8") - ret[is.na(x)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "factor"), function(conn, x, ...) { - dbQuoteLiteral(conn, as.character(x)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "Date"), function(conn, x, ...) { - ret <- paste0("'", as.character(x), "'::date") - ret[is.na(x)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "POSIXt"), function(conn, x, ...) { - ret <- paste0("'", as.character(lubridate::with_tz(x, conn@timezone)), "'::timestamp") - ret[is.na(x)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "difftime"), function(conn, x, ...) { - # https://github.com/tidyverse/hms/issues/84 - mode(x) <- "double" - - ret <- paste0("'", as.character(hms::as_hms(x)), "'::interval") - ret[is.na(x)] <- "NULL" - SQL(ret, names = names(ret)) -}) - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "list"), function(conn, x, ...) { - quote_blob(x) -}) - -#' @export -#' @rdname quote #' @importFrom blob blob -setMethod("dbQuoteLiteral", c("PqConnection", "blob"), function(conn, x, ...) { - quote_blob(x) -}) +#' @rdname quote +setMethod("dbQuoteLiteral", "PqConnection", function(conn, x, ...) { + if (is.factor(x)) { + x <- as.character(x) + } -quote_blob <- function(x) { - blob_data <- vcapply( - x, - function(x) { - if (is.null(x)) "NULL" - else if (is.raw(x)) paste0("E'\\\\x", paste(format(x), collapse = ""), "'") - else { - stop("Lists must contain raw vectors or NULL", call. = FALSE) + if (inherits(x, "Date")) { + ret <- paste0("'", as.character(x), "'::date") + ret[is.na(x)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (inherits(x, "POSIXt")) { + ret <- paste0("'", as.character(lubridate::with_tz(x, conn@timezone)), "'::timestamp") + ret[is.na(x)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (inherits(x, "difftime")) { + ret <- paste0("'", as.character(hms::as_hms(x)), "'::interval") + ret[is.na(x)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (is.logical(x)) { + ret <- as.character(x) + ret[is.na(ret)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (is.integer(x)) { + ret <- paste0(as.character(x), "::int4") + ret[is.na(x)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (is.numeric(x)) { + ret <- paste0(as.character(x), "::float8") + ret[is.na(x)] <- "NULL" + SQL(ret, names = names(ret)) + } else if (is.list(x) || inherits(x, "blob")) { + blob_data <- vcapply( + x, + function(x) { + if (is.null(x)) "NULL" + else if (is.raw(x)) paste0("E'\\\\x", paste(format(x), collapse = ""), "'") + else { + stopc("Lists must contain raw vectors or NULL") + } } - } - ) - SQL(blob_data, names = names(x)) -} - -#' @export -#' @rdname quote -setMethod("dbQuoteLiteral", c("PqConnection", "character"), function(conn, x, ...) { - dbQuoteString(conn, x) + ) + SQL(blob_data, names = names(x)) + } else if (is.character(x)) { + dbQuoteString(conn, x) + } else { + stopc("Can't convert value of class ", class(x)[[1]], " to SQL.", call. = FALSE) + } }) diff --git a/man/quote.Rd b/man/quote.Rd index c931e01b..eb8a070b 100644 --- a/man/quote.Rd +++ b/man/quote.Rd @@ -8,16 +8,7 @@ \alias{dbQuoteIdentifier,PqConnection,SQL-method} \alias{dbQuoteIdentifier,PqConnection,Id-method} \alias{dbUnquoteIdentifier,PqConnection,SQL-method} -\alias{dbQuoteLiteral,PqConnection,logical-method} -\alias{dbQuoteLiteral,PqConnection,integer-method} -\alias{dbQuoteLiteral,PqConnection,numeric-method} -\alias{dbQuoteLiteral,PqConnection,factor-method} -\alias{dbQuoteLiteral,PqConnection,Date-method} -\alias{dbQuoteLiteral,PqConnection,POSIXt-method} -\alias{dbQuoteLiteral,PqConnection,difftime-method} -\alias{dbQuoteLiteral,PqConnection,list-method} -\alias{dbQuoteLiteral,PqConnection,blob-method} -\alias{dbQuoteLiteral,PqConnection,character-method} +\alias{dbQuoteLiteral,PqConnection-method} \title{Quote postgres strings, identifiers, and literals} \usage{ \S4method{dbQuoteString}{PqConnection,character}(conn, x, ...) @@ -32,25 +23,7 @@ \S4method{dbUnquoteIdentifier}{PqConnection,SQL}(conn, x, ...) -\S4method{dbQuoteLiteral}{PqConnection,logical}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,integer}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,numeric}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,factor}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,Date}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,POSIXt}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,difftime}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,list}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,blob}(conn, x, ...) - -\S4method{dbQuoteLiteral}{PqConnection,character}(conn, x, ...) +\S4method{dbQuoteLiteral}{PqConnection}(conn, x, ...) } \arguments{ \item{conn}{A \linkS4class{PqConnection} created by \code{dbConnect()}}