# Not generic enough for DBItest test_that("throws error if constraint violated", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) x <- data.frame(col1 = 1:10, col2 = letters[1:10]) dbWriteTable(con, "t1", x) dbExecute(con, "CREATE UNIQUE INDEX t1_c1_c2_idx ON t1(col1, col2)") expect_error( dbWriteTable(con, "t1", x, append = TRUE), "UNIQUE constraint failed" ) }) # In memory -------------------------------------------------------------------- test_that("can't override existing table with default options", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) x <- data.frame(col1 = 1:10, col2 = letters[1:10]) dbWriteTable(con, "t1", x) expect_error(dbWriteTable(con, "t1", x), "exists in database") }) test_that("throws error if constrainted violated", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) x <- data.frame(col1 = 1:10, col2 = letters[1:10]) dbWriteTable(con, "t1", x) dbExecute(con, "CREATE UNIQUE INDEX t1_c1_c2_idx ON t1(col1, col2)") expect_error( dbWriteTable(con, "t1", x, append = TRUE), "UNIQUE constraint failed" ) }) test_that("can't add table when result set open", { # This needs to fail because cloning a temporary file or in memory # database creates new database con <- dbConnect(SQLite(), tempfile()) on.exit(dbDisconnect(con)) x <- data.frame(col1 = 1:10, col2 = letters[1:10]) dbWriteTable(con, "t1", x) res <- dbSendQuery(con, "SELECT * FROM t1") expect_warning(dbWriteTable(con, "t2", x), "pending rows") expect_warning(dbClearResult(res), "Expired") }) test_that("rownames not preserved by default", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) df <- data.frame(x = 1:10) row.names(df) <- paste(letters[1:10], 1:10, sep = "") dbWriteTable(con, "t1", df) t1 <- dbReadTable(con, "t1") expect_identical(.row_names_info(t1), -10L) }) test_that("rownames preserved with row.names = TRUE", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) df <- data.frame(x = 1:10) row.names(df) <- paste(letters[1:10], 1:10, sep = "") dbWriteTable(con, "t1", df, row.names = TRUE) t1 <- dbReadTable(con, "t1", row.names = TRUE) expect_equal(rownames(t1), rownames(df)) }) test_that("commas in fields are preserved", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) df <- data.frame( x = c("ABC, Inc.", "DEF Holdings"), stringsAsFactors = FALSE ) dbWriteTable(con, "t1", df, row.names = FALSE) expect_equal(dbReadTable(con, "t1"), df) }) test_that("NAs preserved in factors", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) df <- data.frame(x = 1:10, y = factor(LETTERS[1:10])) df$y[4] <- NA dbWriteTable(con, "bad_table", df) bad_table <- dbReadTable(con, "bad_table") expect_equal(bad_table$x, df$x) expect_equal(bad_table$y, as.character(df$y)) }) test_that("logical converted to int", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) local <- data.frame(x = 1:3, y = c(NA, TRUE, FALSE)) dbWriteTable(con, "t1", local) remote <- dbReadTable(con, "t1") expect_equal(remote$y, as.integer(local$y)) }) test_that("can roundtrip special field names", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) local <- data.frame(x = 1:3, select = 1:3, ` ` = 1:3, check.names = FALSE) dbWriteTable(con, "torture", local) remote <- dbReadTable(con, "torture", check.names = FALSE) expect_equal(local, remote) }) # From file ------------------------------------------------------------------- test_that("comments are preserved", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) tmp_file <- tempfile() cat("A,B,C\n11,2#2,33\n", file = tmp_file) on.exit(file.remove(tmp_file), add = TRUE) dbWriteTable(con, "t1", tmp_file, header = TRUE, sep = ",") remote <- dbReadTable(con, "t1") expect_equal(remote$B, "2#2") }) test_that("colclasses overridden by argument", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) tmp_file <- tempfile() cat("A,B,C\n1,2,3\n4,5,6\na,7,8\n", file = tmp_file) on.exit(file.remove(tmp_file), add = TRUE) dbWriteTable(con, "t1", tmp_file, header = TRUE, sep = ",", colClasses = c("character", "integer", "double") ) remote <- dbReadTable(con, "t1") expect_equal( sapply(remote, class), c(A = "character", B = "integer", C = "numeric") ) }) test_that("options work", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) expected <- data.frame( a = c(1:3, NA), b = c("x", "y", "z", "E"), stringsAsFactors = FALSE ) dbWriteTable(con, "dat", "dat-rn.txt", sep = "|", eol = "\r\n", overwrite = TRUE) expect_equal(dbReadTable(con, "dat"), expected) # No idea why this fails in GHA on Windows skip_on_os("windows") dbWriteTable(con, "dat", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE) expect_equal(dbReadTable(con, "dat"), expected) }) test_that("temporary works", { db_file <- tempfile(fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "prm", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE) dbWriteTable(con, "tmp", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE, temporary = TRUE) expect_true(dbExistsTable(con, "prm")) expect_true(dbExistsTable(con, "tmp")) con2 <- dbConnect(SQLite(), db_file) on.exit(dbDisconnect(con2), add = TRUE) expect_true(dbExistsTable(con2, "prm")) expect_false(dbExistsTable(con2, "tmp")) }) test_that("works within transaction", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) df <- data.frame( a = c(1:3, NA), b = c("x", "y", "z", "E"), stringsAsFactors = FALSE ) csv_file <- tempfile(fileext = ".csv") write.csv(df, file = csv_file, row.names = FALSE, eol = "\n") dbWithTransaction(con, { dbWriteTable(con, "tbl", csv_file, eol = "\n", overwrite = TRUE) expect_true(dbExistsTable(con, "tbl")) dbBreak() }) expect_false(dbExistsTable(con, "tbl")) }) # Append ------------------------------------------------------------------ test_that("appending to table ignores column order and column names", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "a", data.frame(a = 1, b = 2)) expect_error( dbWriteTable(con, "a", data.frame(b = 1, a = 2), append = TRUE), NA ) expect_error( dbWriteTable(con, "a", data.frame(c = 1, d = 2), append = TRUE), "not found" ) }) test_that("appending to table gives error if fewer columns", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "a", data.frame(a = 1, b = 2)) dbWriteTable(con, "a", data.frame(b = 1), append = TRUE) expect_error(dbWriteTable(con, "a", data.frame(c = 1), append = TRUE)) a <- dbReadTable(con, "a") expect_identical(a, data.frame(a = c(1, NA), b = c(2, 1))) }) test_that("appending to table gives error if more columns", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "a", data.frame(a = 1, b = 2)) expect_error(dbWriteTable(con, "a", data.frame(a = 1, b = 2, c = 3), append = TRUE)) expect_error(dbWriteTable(con, "a", data.frame(d = 1, e = 2, f = 3), append = TRUE)) a <- dbReadTable(con, "a") expect_identical(a, data.frame(a = 1, b = 2)) }) # Row names --------------------------------------------------------------- test_that("dbWriteTable(row.names = 0)", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) expect_warning(dbWriteTable(con, "mtcars", mtcars, row.names = 0)) res <- dbReadTable(con, "mtcars") expect_equal(rownames(res), as.character(seq_len(nrow(mtcars)))) rownames(res) <- rownames(mtcars) expect_identical(res, mtcars) }) test_that("dbWriteTable(row.names = 1)", { memoise::forget(warning_once) con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) expect_warning(dbWriteTable(con, "mtcars", mtcars, row.names = 1)) res <- dbReadTable(con, "mtcars", row.names = TRUE) expect_identical(res, mtcars) }) test_that("dbWriteTable(row.names = FALSE)", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "mtcars", mtcars, row.names = FALSE) res <- dbReadTable(con, "mtcars") expect_equal(rownames(res), as.character(seq_len(nrow(mtcars)))) rownames(res) <- rownames(mtcars) expect_identical(res, mtcars) }) test_that("dbWriteTable(row.names = TRUE)", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "mtcars", mtcars, row.names = TRUE) res <- dbReadTable(con, "mtcars", row.names = TRUE) expect_identical(res, mtcars) }) test_that("dbWriteTable(iris, row.names = NA)", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "iris", iris, row.names = NA) res <- dbReadTable(con, "iris", row.names = NA) expect_equal(rownames(res), as.character(seq_len(nrow(iris)))) res$Species <- factor(res$Species) expect_identical(res, iris) }) test_that("dbWriteTable(mtcars, row.names = NA)", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "mtcars", mtcars, row.names = NA) res <- dbReadTable(con, "mtcars", row.names = NA) expect_identical(res, mtcars) }) test_that("dbWriteTable(iris, row.names = 'rn')", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "iris", iris, row.names = "rn") res <- dbReadTable(con, "iris", row.names = "rn") expect_equal(rownames(res), as.character(seq_len(nrow(iris)))) res$Species <- factor(res$Species) # Original row names are numeric, RSQLite returns them as character # for simplicity attr(res, "row.names") <- attr(iris, "row.names") expect_identical(res, iris) }) test_that("dbWriteTable(mtcars, row.names = 'rn')", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) dbWriteTable(con, "mtcars", mtcars, row.names = "rn") res <- dbReadTable(con, "mtcars", row.names = "rn") expect_identical(res, mtcars) }) # AsIs -------------------------------------------------------------------- test_that("dbWriteTable with AsIs character fields", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) dbWriteTable(con, "a", data.frame(a = I(letters))) res <- dbReadTable(con, "a") expect_identical(res, data.frame(a = letters, stringsAsFactors = FALSE)) }) test_that("dbWriteTable with AsIs numeric fields", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) dbWriteTable(con, "a", data.frame(a = I(1:3))) res <- dbReadTable(con, "a") expect_identical(res, data.frame(a = 1:3)) }) test_that("dbWriteTable with AsIs list fields", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) dbWriteTable(con, "a", data.frame(a = I(list(as.raw(1:3), as.raw(4:5))))) res <- dbReadTable(con, "a") expected <- data.frame(a = 1:2) expected$a <- blob::blob(as.raw(1:3), as.raw(4:5)) expect_identical(res, expected) }) test_that("dbWriteTable with AsIs raw fields", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) expect_warning( dbWriteTable(con, "a", data.frame(a = I(as.raw(1:3)))), " raw " ) res <- dbReadTable(con, "a") expected <- data.frame(a = 1:3) expected$a <- as.character(as.raw(1:3)) expect_identical(res, expected) })