diff --git a/R/addIndex.R b/R/addIndex.R index 75d7d24..311d3e7 100644 --- a/R/addIndex.R +++ b/R/addIndex.R @@ -2,7 +2,8 @@ #' #' @description #' Adds an index on subject_id and cohort_start_date to a cohort table. Note, -#' currently only indexes will be added if the table is in a postgres database. +#' currently only indexes will be added if the table is in a postgres or sql +#' server database. #' #' @inheritParams cohortDoc #' @@ -67,6 +68,56 @@ addIndex <- function(cdm, name, cols) { ");" ) suppressMessages(DBI::dbExecute(con, query)) + } else if (dbType == c("sql server")) { + con <- attr(cdm, "dbcon") + schema <- attr(cdm, "write_schema") + if(length(schema) > 2){ + prefix <- attr(cdm, "write_schema")["prefix"] + schema1 <- attr(cdm, "write_schema")["schema1"] + schema2 <- attr(cdm, "write_schema")["schema2"] + } else { + schema1 <- attr(cdm, "write_schema")["schema1"] + schema2 <- attr(cdm, "write_schema")["schema2"] + prefix <- NULL + } + + existingIndex <- DBI::dbGetQuery(con, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + DB_NAME() AS database_name + FROM sys.indexes i + JOIN sys.objects o ON o.object_id = o.object_id + WHERE o.name = '", paste0(prefix, name) ,"' + AND i.name IS NOT NULL + + UNION ALL + + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = '", paste0(prefix, name) ,"' + AND i.name IS NOT NULL +")) + + + if(nrow(existingIndex) > 0){ + cli::cli_inform("Index already existing so no new index added.") + return(invisible(NULL)) + } else { + cli::cli_inform("Adding indexes to table") + } + + cols <- paste0(cols, collapse = ",") + + query <- paste0( + "CREATE INDEX IX_", name, "_", gsub(",", "_", cols), + " ON ", schema1, ".", schema2, ".", prefix, name, + " (", cols, ");" + ) + suppressMessages(DBI::dbExecute(con, query)) } return(invisible(NULL)) diff --git a/man/addCohortTableIndex.Rd b/man/addCohortTableIndex.Rd index c652c03..d7238bd 100644 --- a/man/addCohortTableIndex.Rd +++ b/man/addCohortTableIndex.Rd @@ -14,5 +14,6 @@ The cohort table } \description{ Adds an index on subject_id and cohort_start_date to a cohort table. Note, -currently only indexes will be added if the table is in a postgres database. +currently only indexes will be added if the table is in a postgres or sql +server database. } diff --git a/tests/testthat/test-addIndex.R b/tests/testthat/test-addIndex.R index 7a653c9..6868afd 100644 --- a/tests/testthat/test-addIndex.R +++ b/tests/testthat/test-addIndex.R @@ -68,3 +68,172 @@ test_that("postgres test - adds indexes", { CDMConnector::cdm_disconnect(cdm = cdm) }) + +test_that("sql server test - adds indexes", { + skip_on_cran() + skip_if(Sys.getenv("CDM5_SQL_SERVER_SERVER") == "") + + db <- DBI::dbConnect(odbc::odbc(), + Driver = Sys.getenv("SQL_SERVER_DRIVER"), + Server = Sys.getenv("CDM5_SQL_SERVER_SERVER"), + Database = Sys.getenv("CDM5_SQL_SERVER_CDM_DATABASE"), + UID = Sys.getenv("CDM5_SQL_SERVER_USER"), + PWD = Sys.getenv("CDM5_SQL_SERVER_PASSWORD"), + TrustServerCertificate="yes", + Port = Sys.getenv("CDM5_SQL_SERVER_PORT")) + + cdm <- CDMConnector::cdm_from_con( + con = db, + cdm_schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_CDM_SCHEMA"), "\\.")[[1]], + write_schema = c(schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_SCRATCH_SCHEMA"), "\\.")[[1]], + prefix = "cc_") + ) + + cdm <- omopgenerics::insertTable(cdm = cdm, + name = "my_cohort", + table = data.frame(cohort_definition_id = 1L, + subject_id = 1L, + cohort_start_date = as.Date("2009-01-01"), + cohort_end_date = as.Date("2009-01-02"))) + cdm$my_cohort <- omopgenerics::newCohortTable(cdm$my_cohort) + + indexes_start <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'cc_my_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_start) == 0) + + cdm$my_cohort <- cdm$my_cohort |> addCohortTableIndex() + + indexes_end <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'cc_my_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_end) == 1) + + # no error if we add another index - it will just be skipped + cdm$my_cohort <- cdm$my_cohort |> addCohortTableIndex() + indexes_end_2 <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'cc_my_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_end_2) == 1) + + # should still all work as before + cdm$my_cohort <- omopgenerics::newCohortTable(cdm$my_cohort) + omopgenerics::dropTable(cdm = cdm, name = "my_cohort") + + + # no cdm prefix + cdm <- CDMConnector::cdm_from_con( + con = db, + cdm_schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_CDM_SCHEMA"), "\\.")[[1]], + write_schema = c(schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_SCRATCH_SCHEMA"), "\\.")[[1]]) + ) + cdm <- omopgenerics::insertTable(cdm = cdm, + name = "my_new_cohort", + table = data.frame(cohort_definition_id = 1L, + subject_id = 1L, + cohort_start_date = as.Date("2009-01-01"), + cohort_end_date = as.Date("2009-01-02"))) + cdm$my_new_cohort <- omopgenerics::newCohortTable(cdm$my_new_cohort) + cdm$my_new_cohort <- cdm$my_new_cohort |> addCohortTableIndex() + + omopgenerics::dropTable(cdm = cdm, name = "my_new_cohort") + + CDMConnector::cdm_disconnect(cdm = cdm) + +}) + +test_that("sql server no prefix test - adds indexes", { + skip_on_cran() + skip_if(Sys.getenv("CDM5_SQL_SERVER_SERVER") == "") + + db <- DBI::dbConnect(odbc::odbc(), + Driver = Sys.getenv("SQL_SERVER_DRIVER"), + Server = Sys.getenv("CDM5_SQL_SERVER_SERVER"), + Database = Sys.getenv("CDM5_SQL_SERVER_CDM_DATABASE"), + UID = Sys.getenv("CDM5_SQL_SERVER_USER"), + PWD = Sys.getenv("CDM5_SQL_SERVER_PASSWORD"), + TrustServerCertificate="yes", + Port = Sys.getenv("CDM5_SQL_SERVER_PORT")) + + + # no cdm prefix + cdm <- CDMConnector::cdm_from_con( + con = db, + cdm_schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_CDM_SCHEMA"), "\\.")[[1]], + write_schema = c(schema = strsplit(Sys.getenv("CDM5_SQL_SERVER_SCRATCH_SCHEMA"), "\\.")[[1]]) + ) + cdm <- omopgenerics::insertTable(cdm = cdm, + name = "my_new_cohort", + table = data.frame(cohort_definition_id = 1L, + subject_id = 1L, + cohort_start_date = as.Date("2009-01-01"), + cohort_end_date = as.Date("2009-01-02"))) + cdm$my_new_cohort <- omopgenerics::newCohortTable(cdm$my_new_cohort) + + indexes_start <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'my_new_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_start) == 0) + + cdm$my_new_cohort <- cdm$my_new_cohort |> addCohortTableIndex() + + indexes_end <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'my_new_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_end) == 1) + + # skip creation now index exists + cdm$my_new_cohort <- cdm$my_new_cohort |> addCohortTableIndex() + + indexes_end_2 <- DBI::dbGetQuery(db, + paste0(" + SELECT i.name AS index_name, + o.name AS table_name, + 'tempdb' AS database_name + FROM tempdb.sys.indexes i + JOIN tempdb.sys.objects o ON i.object_id = o.object_id + WHERE o.name = 'my_new_cohort' + AND i.name IS NOT NULL +")) + expect_true(nrow(indexes_end_2) == 1) + + omopgenerics::dropTable(cdm = cdm, name = "my_new_cohort") + + CDMConnector::cdm_disconnect(cdm = cdm) + +})