Skip to content

Commit

Permalink
feat: add support for Redshift connections
Browse files Browse the repository at this point in the history
  • Loading branch information
owenjonesuob committed May 3, 2024
1 parent e52ba91 commit 1dd6b91
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 27 deletions.
2 changes: 1 addition & 1 deletion R/build_copy_queries.R
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ build_copy_queries <- function(dest, dm, set_key_constraints = TRUE, temporary =
pk_col <- pk_col[[1]]

# Postgres:
if (is_postgres(dest)) {
if (is_postgres(dest) || is_redshift(dest)) {
types[pk_col] <- "SERIAL"
}

Expand Down
19 changes: 17 additions & 2 deletions R/db-helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ is_postgres <- function(dest) {
))
}

is_redshift <- function(dest) {
inherits_any(dest, c(
"src_RedshiftConnection", "RedshiftConnection"
))
}

is_mariadb <- function(dest) {
inherits_any(
dest,
Expand Down Expand Up @@ -122,8 +128,8 @@ find_name_clashes <- function(old, new) {

#' @autoglobal
get_src_tbl_names <- function(src, schema = NULL, dbname = NULL, names = NULL) {
if (!is_mssql(src) && !is_postgres(src) && !is_mariadb(src)) {
warn_if_arg_not(schema, only_on = c("MSSQL", "Postgres", "MariaDB"))
if (!is_mssql(src) && !is_postgres(src) && !is_redshift(src) && !is_mariadb(src)) {
warn_if_arg_not(schema, only_on = c("MSSQL", "Postgres", "Redshift", "MariaDB"))
warn_if_arg_not(dbname, only_on = "MSSQL")
tables <- src_tbls(src)
out <- purrr::map(tables, ~ DBI::Id(table = .x))
Expand All @@ -148,6 +154,11 @@ get_src_tbl_names <- function(src, schema = NULL, dbname = NULL, names = NULL) {
schema <- schema_postgres(con, schema)
dbname <- warn_if_arg_not(dbname, only_on = "MSSQL")
names_table <- get_names_table_postgres(con)
} else if (is_redshift(src)) {
# Redshift
schema <- schema_redshift(con, schema)
dbname <- warn_if_arg_not(dbname, only_on = "MSSQL")
names_table <- get_names_table_redshift(con)
} else if (is_mariadb(src)) {
# MariaDB
schema <- schema_mariadb(con, schema)
Expand Down Expand Up @@ -224,6 +235,8 @@ schema_postgres <- function(con, schema) {
schema
}

schema_redshift <- schema_postgres

schema_mariadb <- function(con, schema) {
if (is_null(schema)) {
schema <- sql("database()")
Expand Down Expand Up @@ -262,4 +275,6 @@ get_names_table_postgres <- function(con) {
)
}

get_names_table_redshift <- get_names_table_postgres

get_names_table_mariadb <- get_names_table_postgres
4 changes: 2 additions & 2 deletions R/db-interface.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#' The latter is copied to the former.
#' The default is to create temporary tables, set `temporary = FALSE` to create permanent tables.
#' Unless `set_key_constraints` is `FALSE`, primary key constraints are set on all databases,
#' and in addition foreign key constraints are set on MSSQL and Postgres databases.
#' and in addition foreign key constraints are set on MSSQL and Postgres/Redshift databases.
#'
#' @inheritParams dm_examine_constraints
#'
Expand Down Expand Up @@ -280,7 +280,7 @@ db_append_table <- function(con, remote_table, table, progress, top_level_fun =
}
DBI::dbExecute(con, sql, immediate = TRUE)
}))
} else if (is_postgres(con)) {
} else if (is_postgres(con) || is_redshift(con)) {
# https://github.com/r-dbi/RPostgres/issues/384
table <- as.data.frame(table)
# https://github.com/r-dbi/RPostgres/issues/382
Expand Down
10 changes: 5 additions & 5 deletions R/dm_from_con.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @description
#' `dm_from_con()` creates a [dm] from some or all tables in a [src]
#' (a database or an environment) or which are accessible via a DBI-Connection.
#' For Postgres and SQL Server databases, primary and foreign keys
#' For Postgres/Redshift and SQL Server databases, primary and foreign keys
#' are imported from the database.
#'
#' @param con A [`DBI::DBIConnection-class`] or a `Pool` object.
Expand All @@ -14,13 +14,13 @@
#'
#' Set to `TRUE` to query the definition of primary and
#' foreign keys from the database.
#' Currently works only for Postgres and SQL Server databases.
#' Currently works only for Postgres/Redshift and SQL Server databases.
#' The default attempts to query and issues an informative message.
#' @param .names
#' `r lifecycle::badge("experimental")`
#'
#' A glue specification that describes how to name the tables
#' within the output, currently only for MSSQL, Postgres and MySQL/MariaDB.
#' within the output, currently only for MSSQL, Postgres/Redshift and MySQL/MariaDB.
#' This can use `{.table}` to stand for the table name, and
#' `{.schema}` to stand for the name of the schema which the table lives
#' within. The default (`NULL`) is equivalent to `"{.table}"` when a single
Expand All @@ -30,11 +30,11 @@
#'
#' Additional parameters for the schema learning query.
#'
#' - `schema`: supported for MSSQL (default: `"dbo"`), Postgres (default: `"public"`), and MariaDB/MySQL
#' - `schema`: supported for MSSQL (default: `"dbo"`), Postgres/Redshift (default: `"public"`), and MariaDB/MySQL
#' (default: current database). Learn the tables in a specific schema (or database for MariaDB/MySQL).
#' - `dbname`: supported for MSSQL. Access different databases on the connected MSSQL-server;
#' default: active database.
#' - `table_type`: supported for Postgres (default: `"BASE TABLE"`). Specify the table type. Options are:
#' - `table_type`: supported for Postgres/Redshift (default: `"BASE TABLE"`). Specify the table type. Options are:
#' 1. `"BASE TABLE"` for a persistent table (normal table type)
#' 2. `"VIEW"` for a view
#' 3. `"FOREIGN TABLE"` for a foreign table
Expand Down
4 changes: 2 additions & 2 deletions R/dm_sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ ddl_get_col_defs <- function(tables, con, table_names, pks) {
# extract column name representing primary key
pk_col_name <- pk_col$pk_col[[1]]

# Postgres:
if (is_postgres(con)) {
# Postgres/Redshift:
if (is_postgres(con) || is_redshift(con)) {
types[pk_col_name] <- "SERIAL"
}

Expand Down
2 changes: 1 addition & 1 deletion R/learn.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @description If there are any permament tables on a DB, a new [`dm`] object can be created that contains those tables,
#' along with their primary and foreign key constraints.
#'
#' Currently this only works with MSSQL and Postgres databases.
#' Currently this only works with MSSQL and Postgres/Redshift databases.
#'
#' The default database schema will be used; it is currently not possible to parametrize the funcion with a specific database schema.
#'
Expand Down
11 changes: 10 additions & 1 deletion R/meta.R
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ dm_meta_raw <- function(con, catalog) {
if (is_mssql(src)) {
columns <- columns %>%
mutate(is_autoincrement = sql("CAST(COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity') AS BIT)"))
} else if (is_postgres(src)) {
} else if (is_postgres(src) || is_redshift(src)) {
columns <- columns %>%
mutate(is_autoincrement = sql("CASE WHEN column_default IS NULL THEN FALSE ELSE column_default SIMILAR TO '%nextval%' END"))
} else if (is_mariadb(src)) {
Expand Down Expand Up @@ -134,6 +134,15 @@ dm_meta_raw <- function(con, catalog) {
"constraint_catalog", "constraint_schema", "constraint_name",
"ordinal_position"
))
} else if (is_redshift(src)) {
constraint_column_usage <-
tbl_lc(src, "information_schema.key_column_usage", vars = c(
"table_catalog",
"table_schema", "table_name", "column_name",
"constraint_catalog", "constraint_schema", "constraint_name",
"ordinal_position"
)) %>%
filter(!is.na(table_name))
} else if (is_mssql(src)) {
constraint_column_usage <- mssql_constraint_column_usage(src, table_constraints, catalog)
} else {
Expand Down
4 changes: 2 additions & 2 deletions R/schema.R
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ sql_schema_table_list_postgres <- function(con, schema = NULL) {
#'
#' @inheritParams db_schema_create
#' @param force Boolean, default `FALSE`. Set to `TRUE` to drop a schema and
#' all objects it contains at once. Currently only supported for Postgres.
#' all objects it contains at once. Currently only supported for Postgres/Redshift.
#'
#' @details Methods are not available for all DBMS.
#'
Expand Down Expand Up @@ -357,7 +357,7 @@ db_schema_drop.PqConnection <- function(con, schema, force = FALSE, ...) {
`db_schema_drop.Microsoft SQL Server` <- function(con, schema, force = FALSE, dbname = NULL, ...) {
warn_if_arg_not(
force,
only_on = "Postgres",
only_on = c("Postgres", "Redshift"),
correct = FALSE,
additional_msg = "Please remove potential objects from the schema manually."
)
Expand Down
2 changes: 1 addition & 1 deletion man/copy_dm_to.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/db_schema_drop.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions man/dm_from_con.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions man/dm_from_src.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scratch/info.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ info_local <-
collect()

quote_fq_schema <- function(con, catalog, schema) {
if (is_postgres(con) || is_mssql(con)) {
if (is_postgres(con) || is_redshift(con) || is_mssql(con)) {
catalog <- dbQuoteIdentifier(con, catalog)
schema <- dbQuoteIdentifier(con, schema)
paste0(catalog, ".", schema)
Expand Down

0 comments on commit 1dd6b91

Please sign in to comment.