-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- new files for db stuff, separate files for redshift, rds and wait fxns - add rds functions - modify wait functions to use common plumbing with generator for each of redshift, rds - now importing RMariaDB
Showing
19 changed files
with
462 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ Suggests: | |
roxyglobals, | ||
DBI, | ||
RPostgres, | ||
RMariaDB, | ||
testthat (>= 3.0.0), | ||
vcr (>= 0.6.0), | ||
withr | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#' Get a database connection to Amazon RDS | ||
#' | ||
#' JUST MariaDB FOR NOW!!!! | ||
#' | ||
#' @export | ||
#' @inheritParams aws_db_redshift_con | ||
#' @note RDS supports: Aurora (both PostgreSQL and MySQL compatible), | ||
#' PostgreSQL, MariaDB, MySQL, Orace, MS SQL Server | ||
#' @examples \dontrun{ | ||
#' library(DBI) | ||
#' library(RMariaDB) | ||
#' | ||
#' con_rds <- aws_db_rds_con("<define all params here>") | ||
#' con_rds | ||
#' | ||
#' library(RMariaDB) | ||
#' dbListTables(con_rds) | ||
#' dbWriteTable(con_rds, "mtcars", mtcars) | ||
#' dbListTables(con_rds) | ||
#' dbReadTable(con_rds, "mtcars") | ||
#' | ||
#' library(dplyr) | ||
#' tbl(con_rds, "mtcars") | ||
#' } | ||
aws_db_rds_con <- function(user, pwd, id = NULL, host = NULL, port = NULL, | ||
dbname = NULL, ...) { | ||
check_for_pkg("DBI") | ||
check_for_pkg("RMariaDB") | ||
|
||
stopifnot("user is required" = !missing(user)) | ||
stopifnot("pwd is required" = !missing(pwd)) | ||
|
||
if (!is.null(id)) { | ||
con_info <- instance_con_info(id) | ||
host <- con_info$host | ||
port <- con_info$port | ||
dbname <- con_info$dbname | ||
} | ||
if (any(vapply(list(host, port, dbname), is.null, logical(1)))) { | ||
stop("`host`, `port`, and `dbname` can not be NULL", call. = FALSE) | ||
} | ||
|
||
DBI::dbConnect( | ||
RMariaDB::MariaDB(), | ||
host = host, | ||
port = port, | ||
dbname = dbname, | ||
user = user, | ||
password = pwd, | ||
... | ||
) | ||
} | ||
|
||
#' Create an RDS cluster | ||
#' | ||
#' @export | ||
#' @importFrom paws rds | ||
#' @param id (character) required. instance identifier. The identifier for | ||
#' this DB instance. This parameter is stored as a lowercase string. | ||
#' Constraints: must contain from 1 to 63 letters, numbers, or hyphens; first | ||
#' character must be a letter; cn't end with a hyphen or contain two | ||
#' consecutive hyphens. required. | ||
#' @param class (character) required. The compute and memory capacity of the | ||
#' DB instance, for example `db.m5.large`. | ||
#' @param user (character) User name associated with the admin user account for | ||
#' the cluster that is being created. | ||
#' @param pwd (character) Password associated with the admin user account for | ||
#' the cluster that is being created. | ||
#' @param dbname (character) The name of the first database to be created when | ||
#' the cluster is created. default: "dev". additional databases can be created | ||
#' within the cluster | ||
#' @param engine (character) The engine to use. default: "mariadb". required. | ||
#' @param storage (character) The amount of storage in gibibytes (GiB) to | ||
#' allocate for the DB instance. default: 20 | ||
#' @param storage_encrypted (logical) Whether the DB instance is encrypted. | ||
#' default: `TRUE` | ||
#' @param security_group_ids (character) VPC security group identifiers; one | ||
#' or more. If none are supplied, you should go into your AWS Redshift | ||
#' dashboard and add the appropriate VPC security group. | ||
#' @param wait (logical) wait for cluster to initialize? default: `TRUE`. If | ||
#' you don't wait (`FALSE`) then there's many operations you can not do | ||
#' until the cluster is available. If `wait=FALSE` use | ||
#' `aws_db_instance_status()` to check on the cluster status. | ||
#' @param ... named parameters passed on to | ||
#' [create_db_instance](https://www.paws-r-sdk.com/docs/rds_create_db_instance/) | ||
#' @note See above link to `create_cluster` docs for details on requirements | ||
#' for each parameter | ||
#' @return a list with methods for interfacing with RDS; | ||
#' see <https://www.paws-r-sdk.com/docs/rds/> | ||
aws_db_rds_create <- | ||
function(id, class, user, pwd, dbname = "dev", | ||
engine = "mariadb", storage = 20, | ||
storage_encrypted = TRUE, security_group_ids = NULL, | ||
wait = TRUE, ...) { | ||
aws_db_rds_client() | ||
env64$rds$create_db_instance( | ||
DBName = dbname, DBInstanceIdentifier = id, | ||
Engine = engine, DBInstanceClass = class, | ||
AllocatedStorage = storage, | ||
MasterUsername = user, MasterUserPassword = pwd, | ||
VpcSecurityGroupIds = security_group_ids, | ||
StorageEncrypted = storage_encrypted, | ||
... | ||
) | ||
if (wait) { | ||
wait_for_instance(id) | ||
} | ||
return(env64$rds) | ||
} | ||
|
||
#' Get the `paws` RDS client | ||
#' @export | ||
#' @note returns existing client if found; a new client otherwise | ||
#' @return a list with methods for interfacing with RDS; | ||
#' see <https://www.paws-r-sdk.com/docs/rds/> | ||
aws_db_rds_client <- function() { | ||
if (is.null(env64$rds)) env64$rds <- paws::rds() | ||
return(env64$rds) | ||
} | ||
|
||
#' Get information for all RDS instances | ||
#' @return a list of instance details | ||
#' @keywords internal | ||
instance_details <- function() { | ||
instances <- env64$rds$describe_db_instances() | ||
return(instances) | ||
} | ||
|
||
#' Get connection information for all instances | ||
#' @inheritParams aws_db_redshift_create | ||
#' @return a list of cluster details | ||
#' @keywords internal | ||
instance_con_info <- function(id) { | ||
deets <- instance_details()$DBInstances | ||
z <- Filter(function(x) x$DBInstanceIdentifier == id, deets)[[1]] | ||
list(host = z$Endpoint$Address, port = z$Endpoint$Port, dbname = z$DBName) | ||
} | ||
|
||
#' Get instance status | ||
#' @export | ||
#' @inheritParams aws_db_rds_create | ||
#' @return (character) the status of the instance, e.g., "creating", | ||
#' "available", "not found" | ||
#' @examples \dontrun{ | ||
#' aws_db_instance_status(id = "thedbinstance") | ||
#' } | ||
aws_db_instance_status <- function(id) { | ||
deets <- instance_details()$DBInstances | ||
instance <- Filter(function(x) x$DBInstanceIdentifier == id, deets) | ||
if (!length(instance)) { | ||
warning(glue::glue("instance id '{id}' not found")) | ||
return("not found") | ||
} | ||
instance[[1]]$DBInstanceStatus | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# wait fxn generator | ||
wait_until <- function(fun, message) { | ||
function(id, sleep = 2, status_target = "available") { | ||
options(cli.spinner = "simpleDots") | ||
on.exit(options(cli.spinner = NULL), add = TRUE) | ||
cli::cli_progress_bar(format = "{cli::pb_spin} {message}") # nolint | ||
is_not_available <- TRUE | ||
while (is_not_available) { | ||
status <- fun(id) | ||
if (status == "not found") break | ||
cli::cli_progress_update() | ||
Sys.sleep(sleep) | ||
if (status == status_target) { | ||
is_not_available <- FALSE | ||
} | ||
} | ||
} | ||
} | ||
|
||
#' Wait for a Redshift cluster to have a certain status | ||
#' | ||
#' @importFrom cli cli_progress_bar cli_progress_update pb_spin | ||
#' @inheritParams aws_db_redshift_create | ||
#' @param fun (function) a function to check status of something; | ||
#' must return a single boolean, e.g., `aws_db_cluster_status` or | ||
#' `aws_db_instance_status` | ||
#' @param sleep (integer/numeric) number of seconds to wait between | ||
#' checks of the cluster status (i.e., http requests) | ||
#' @param status_target (character) status to wait for. default: "available" | ||
#' @return nothing, exits if there's an error, or if the while | ||
#' loop completes | ||
#' @keywords internal | ||
#' @examples \dontrun{ | ||
#' wait_for_cluster(id = "scotts-test-cluster-456") | ||
#' } | ||
wait_for_cluster <- wait_until( | ||
aws_db_cluster_status, | ||
"Redshift cluster initializing" | ||
) | ||
|
||
#' Wait for an RDS instance to have a certain status | ||
#' | ||
#' @inheritParams wait_for_cluster | ||
#' @return nothing, exits if there's an error, or if the while | ||
#' loop completes | ||
#' @keywords internal | ||
#' @examples \dontrun{ | ||
#' wait_for_instance(id = "scotts-test-cluster-456") | ||
#' } | ||
wait_for_instance <- wait_until( | ||
aws_db_instance_status, | ||
"RDS instance initializing" | ||
) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
18 changes: 10 additions & 8 deletions
18
man/wait_until_cluster_available.Rd → man/wait_for_instance.Rd
Oops, something went wrong.