tests/testthat/test-prepare_sql.R

# Check names of lists are properly transferred
test_that("names are preserved", {
  connect(config_filename = testthat::test_path("testfiles",
                                                "sqlhelper_db_conf.yml"),
          exclusive=TRUE)

  sql <- prepare_sql(c(one="SELECT 1", two="SELECT2"))
  expect_equal(sql$qname, c("one", "two"))
})

# Check errors are raised for improperly formed inputs (wrong cols, wrong rows)
test_that("inputs are validated", {
  expect_error(prepare_sql(tibble::tibble(a=c(1,2),b=c(3,4))), "must have these columns")
  expect_error(prepare_sql(list(one="SELECT 1", two="SELECT2")), "must be a character vector or a tibble")
  expect_error(prepare_sql(c(one=1, two=2)), "must be a character vector or a tibble")

  expect_error(
    prepare_sql(
      tibble::tibble(qname=NA,
                     quotesql=NA,
                     interpolate=NA,
                     execmethod=NA,
                     geometry=NA,
                     conn_name=NA,
                     sql=c(NA,"foo"),
                     filename=NA)
    ),
    "sql argument contains NAs"
  )

  expect_error(
    prepare_sql(
      tibble::tibble(qname=NA,
                     quotesql=NA,
                     interpolate=NA,
                     execmethod=NA,
                     geometry=NA,
                     conn_name=NA,
                     sql=NA,
                     filename=NA)
    ),
    "sql argument contains NAs"
  )

  expect_identical(
    prepare_sql(
      tibble::tibble(qname=NA,
                     quotesql=NA,
                     interpolate=NA,
                     execmethod=NA,
                     geometry=NA,
                     conn_name=NA,
                     sql=c("SELECT 'foo'"),
                     filename=NA)
    ),
    tibble::tibble(qname=as.character(NA),
                   quotesql="yes",
                   interpolate="yes",
                   execmethod="get",
                   geometry=as.character(NA),
                   conn_name="default",
                   sql=c("SELECT 'foo'"),
                   filename=as.character(NA),
                   prepared_sql=list(DBI::SQL("SELECT 'foo'")))
  )

  expect_error(prepare_sql("select 1", default.conn = "foo"),
               "is not a valid connection")

  bust <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
  DBI::dbDisconnect(bust)
  expect_error(prepare_sql("select 1", default.conn = bust),
               "is not a valid connection")

  foo <- "bar"
  expect_equal(prepare_sql("select {`foo`}")$prepared_sql[[1]],
               DBI::SQL("select `bar`"))
  DBI::dbDisconnect(live_connection("single_mem"))
  expect_error(prepare_sql("select {`foo`}"),
               "is not a valid connection")
  expect_error(prepare_sql("select {`foo`}",default.conn = "single_mem"),
               "is not a valid connection")

  connect(config_filename = testthat::test_path("testfiles",
                                                "sqlhelper_db_conf.yml"),
          exclusive=TRUE)
})

# Check that only NAs are replaced with defaults (and that they are properly replaced)
test_that("NAs are replaced by defaults", {
  n <- 5
  foo <- "bar"
  sql <- read_sql( testthat::test_path( "testfiles", "test_prepare.SQL")) |>
    prepare_sql()
  expect_equal(sql$conn_name, c('default', 'default', 'default', 'default', 'pool_mem'))
  expect_equal(sql$quotesql, c("yes", "yes", "yes", "no", "no"))
  expect_equal(sql$execmethod, c("get", "get", "get", "execute", "spatial"))
  expect_equal(sql$geometry, c(NA, NA, NA, NA, "geom"))
  expect_equal(sql$prepared_sql,
               list(
                 DBI::SQL("SELECT 5"),
                 DBI::SQL("SELECT `bar`"),
                 DBI::SQL("SELECT {`foo`}"),
                 DBI::SQL("SELECT bar"),
                 DBI::SQL("select 'foo'")
                 )
               )


  sql <- read_sql( testthat::test_path( "testfiles", "test_prepare.SQL")) |>
    prepare_sql(default.conn = "pool_mem", quotesql = "no", execmethod = "sendq", geometry="g")
  expect_equal(sql$conn_name, c('default', 'default', 'default', 'default', 'pool_mem'))
  expect_equal(sql$quotesql, c("no", "no","no", "no", "no"))
  expect_equal(sql$execmethod, c("sendq", "sendq","sendq", "execute", "spatial"))
  expect_equal(sql$geometry, c("g", "g", "g", "g", "geom"))

})

# Check interpolations
test_that("defaults are properly set", {
  connect(config_filename = testthat::test_path("testfiles",
                                                "sqlhelper_db_conf.yml"),
          exclusive=TRUE)

  # test default defaults
  sql <- prepare_sql(c(one="select 1"))

  expect_equal(sql$qname, "one")
  expect_equal(sql$quotesql, "yes")
  expect_equal(sql$interpolate, "yes")
  expect_equal(sql$execmethod, "get")
  expect_true(is.na(sql$geometry))
  expect_equal(sql$conn_name, "default")
  expect_equal(sql$sql, "select 1")
  expect_true(is.na(sql$filename))
  expect_equal(sql$prepared_sql[[1]], DBI::SQL("select 1"))

  # change defaults
  sql <- prepare_sql(c(one="select 1"),
                     quotesql = "no",
                     values = "no",
                     execmethod = "sendq",
                     default.conn = "pool_mem"
                     )

  expect_equal(sql$quotesql, "no")
  expect_equal(sql$interpolate, "no")
  expect_equal(sql$execmethod, "sendq")
  #expect_equal(sql$conn_name, "pool_mem")

  expect_error(prepare_sql("SELECT {`foo`}"))
  expect_error(prepare_sql("SELECT {`foo`}", quotesql = "no"))
})

test_that("correct connections are used for interpolation",{
  skip("Requires local SQL Server instance") # comment if local
  foo <- "noo"
  bar <- "baz"
  sql <- "select {`bar`} from {`foo`}"
  expect_equal(
    sqlhelper:::interpolate_sql(
      interpolate = "yes",
      quotesql = "yes",
      conn_name = "default",
      sql = sql,
      values = environment(),
      default.conn = default_conn()),

    DBI::SQL("select `baz` from `noo`")
  )

  # Local sqlserver install
  con <- DBI::dbConnect(odbc::odbc(),
                        Driver = "{ODBC Driver 17 for SQL Server}",
                        Server = "Dap-sql01\\cds",
                        Trusted_Connection = "yes")

  expect_equal(
    sqlhelper:::interpolate_sql(
      interpolate = "yes",
      quotesql = "yes",
      conn_name = "default",
      sql = sql,
      values = environment(),
      default.conn = con),

    DBI::SQL("select \"baz\" from \"noo\"")
  )
})

# interpolation is correct
test_that("interpolation is correct", {

  # connection specified in comment is bad
  expect_error(
    read_sql(
      testthat::test_path( "testfiles", "test_prepare_badconn.SQL")
    ) |>
      prepare_sql()
  )

  # value not available
  expect_error(prepare_sql(c(one="select {x}")))

  # interpolate settings are obeyed: interpolate
  sql <- prepare_sql(c(one="select {x}"), values = NULL)
  expect_equal(sql$interpolate, "no")
  expect_false(sql$prepared_sql[[1]] == "select 3")

  x = 3
  sql <- prepare_sql(c(one="select {x}"))
  expect_true(sql$prepared_sql[[1]] == "select 3")

  # parent.env vs alt env
  n <- 5
  foo <- "fye"
  env <- new.env()
  env$n <- 2
  env$foo <- "bar"
  sql <- prepare_sql(c(one="select {n}", two="select {foo}"), values = env)
  expect_equal(sql$prepared_sql,list(DBI::SQL("select 2"),DBI::SQL("select 'bar'")))

  # settings are obeyed: quotesql
  sql <- prepare_sql(c(one="select {foo}"), values = env, quotesql = "no")
  expect_equal(sql$prepared_sql,list(DBI::SQL("select bar")))

})

Try the sqlhelper package in your browser

Any scripts or data that you put into this service are public.

sqlhelper documentation built on May 29, 2024, 4:29 a.m.