diff --git a/DESCRIPTION b/DESCRIPTION index b2e99b6..a7f69bd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: councilR Title: Functions and Templates for the Metropolitan Council -Version: 0.2.3 -Date: 2023-09-15 +Version: 0.2.4 +Date: 2023-10-05 Authors@R: c( person("Metropolitan Council", role = "cph"), person("Liz", "Roten", , "liz.roten@metc.state.mn.us", role = c("cre", "aut"), @@ -25,20 +25,20 @@ Imports: cli (>= 3.6.1), data.table (>= 1.14.8), DBI (>= 1.1.3), - dplyr (>= 1.1.2), + dplyr (>= 1.1.3), fs (>= 1.6.3), - ggplot2 (>= 3.4.2), - ggspatial (>= 1.1.8), + ggplot2 (>= 3.4.3), + ggspatial (>= 1.1.9), glue (>= 1.6.2), magrittr (>= 2.0.3), odbc (>= 1.3.5), plotly (>= 4.10.2), - purrr (>= 1.0.1), + purrr (>= 1.0.2), rlang (>= 1.1.1), rstudioapi (>= 0.15.0), sf (>= 1.0-14), tictoc (>= 1.2), - tigris (>= 2.0.3), + tigris (>= 2.0.4), utils Suggests: citr (>= 0.3.2), diff --git a/NAMESPACE b/NAMESPACE index 7f37eb8..dc6ed93 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,17 +1,21 @@ # Generated by roxygen2: do not edit by hand export("%>%") +export(FRED_connection) export(council.pal) export(council_layout) export(council_pal2) export(council_theme) +export(emissions_connection) export(fetch_county_geo) export(fetch_ctu_geo) +export(fred_connection) export(import_from_FRED) export(import_from_emissions) export(import_from_fred) export(import_from_gis) export(import_from_gpkg) +export(import_gpkg) export(look) export(map_council_continuous) export(plotly_layout) diff --git a/R/import_from_FRED.R b/R/db_FRED.R similarity index 55% rename from R/import_from_FRED.R rename to R/db_FRED.R index 789dfc1..ad08cd6 100644 --- a/R/import_from_FRED.R +++ b/R/db_FRED.R @@ -1,7 +1,35 @@ -#' @title Import data table from FRED (main CD Research database) data stored +#' @title FRED +#' +#' @description +#' Functions for interacting with FRED, the main CD Research database, stored #' Azure SQL Server #' -#' @param table_name character, which table to pull. +#' @details +#' Both "FRED" and "fred" capitalization are supported. +#' +#' - `fred_connection()` creates an S4 Microsoft SQL Server object for FRED. +#' This function will *not* automatically close the connection, so take +#' care to use [DBI::dbDisconnect()] once you are done. +#' - `import_from_fred()` imports a given table from FRED. The connection will +#' be automatically closed after the table is imported. +#' +#' @note See `vignette("Options")` to review package options. +#' +#' You must be set up with the appropriate database drivers to use these functions. +#' +#' **Windows** users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. +#' +#' **Mac** users need `unixodbc`, `freetds`, and properly configured `odbc.ini`. +#' +#' See instructions in the +#' [onboarding guide](https://furry-adventure-596f3adb.pages.github.io/database-connections.html) +#' and contact package maintainer for assistance. +#' These functions rely on `{rlang}` internal functions. +#' Further examples can be found in `vignette("Databases")`. +#' +#' @rdname fred +#' @family database functions +#' #' @param uid character, your network ID. #' Default is `getOption("councilR.uid")`. #' @param pwd character, your network password. @@ -10,44 +38,45 @@ #' @param prod logical, whether to pull from the test or production db. #' Default is `TRUE`. #' -#' -#' @note See `vignette("Options")` to review package options. -#' You must be set up with the appropriate database drivers to use this function. -#' **Windows** users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. -#' **Mac** users need `unixodbc`, `freetds`, and properly configured `odbc.ini`. -#' See instructions in the -#' [onboarding guide](https://furry-adventure-596f3adb.pages.github.io/database-connections.html) -#' and contact package maintainer for assistance. -#' -#' This function relies on `[{rlang}]` internal functions. -#' -#' @return Requested table +#' @return `fred_connection()` - A S4 Microsoft SQL Server object #' @export #' #' @examples #' \dontrun{ #' library(councilR) +#' library(DBI) #' #' # set options if you haven't already #' options( #' councilR.uid = "mc\\you", #' councilR.pwd = "mypwd" #' ) +#' # create connection +#' conn <- FRED_connection(prod = FALSE) +#' +#' # pull table using SQL +#' DBI::dbGetQuery(conn, "SELECT * FROM GQ_UNIT WHERE UNIT_ZIP = 55104") +#' +#' # disconnect +#' DBI::dbDisconnect(conn) #' +#' # import a specific table, with no additional SQL logic #' import_from_FRED(table_name = "GQ_UNIT", prod = FALSE) #' } +#' #' @importFrom DBI dbCanConnect dbGetQuery dbConnect dbDisconnect #' @importFrom odbc odbc #' @importFrom utils osVersion #' @importFrom purrr map -import_from_FRED <- function(table_name, - uid = getOption("councilR.uid"), - pwd = getOption("councilR.pwd"), - db = "CD_RESEARCH_WEB", - prod = TRUE) { +#' @importFrom cli cli_abort +FRED_connection <- function( + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + db = "CD_RESEARCH_WEB", + prod = TRUE) { # check input types purrr::map( - c(table_name, uid, pwd, db), + c(uid, pwd, db), rlang:::check_string ) purrr::map( @@ -87,7 +116,7 @@ import_from_FRED <- function(table_name, Pwd = pwd ) == FALSE) { - stop("Database failed to connect") + cli::cli_abort("Database failed to connect") } } else if (drv == "SQL Server") { if ( @@ -100,7 +129,7 @@ import_from_FRED <- function(table_name, Server = serv, Trusted_Connection = "yes" ) == FALSE) { - stop("Database failed to connect") + cli::cli_abort("Database failed to connect") } } @@ -126,6 +155,44 @@ import_from_FRED <- function(table_name, ) } + # return connection + return(conn) +} + +#' @rdname fred +#' @export +fred_connection <- FRED_connection + +#' +#' @param table_name character, which table to pull. +#' +#' @return `import_from_FRED()` - Requested table +#' @export +#' +#' @importFrom DBI dbGetQuery dbDisconnect +#' @rdname fred +import_from_FRED <- function(table_name, + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + db = "CD_RESEARCH_WEB", + prod = TRUE) { + # check input types + purrr::map( + c(table_name, uid, pwd, db), + rlang:::check_string + ) + purrr::map( + c(prod), + rlang:::check_bool + ) + + conn <- fred_connection( + uid = uid, + pwd = pwd, + db = db, + prod = prod + ) + db_sp_table <- DBI::dbGetQuery( conn, paste0("SELECT * FROM ", table_name) @@ -138,7 +205,6 @@ import_from_FRED <- function(table_name, -#' @rdname import_from_FRED +#' @rdname fred #' @export import_from_fred <- import_from_FRED - diff --git a/R/import_from_emissions.R b/R/db_emissions.R similarity index 74% rename from R/import_from_emissions.R rename to R/db_emissions.R index 0ac6a21..36c516d 100644 --- a/R/import_from_emissions.R +++ b/R/db_emissions.R @@ -14,19 +14,22 @@ #' To access Azure, your IP address must be approved. Contact Sean Molloy. #' #' @note See `vignette("Options")` to review package options. -#' You must be set up with the appropriate database drivers to use this function. +#' You must be set up with the appropriate database drivers to use these functions. #' **Windows** users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. #' **Mac** users need `unixodbc` and `freetds`. See instructions in the #' [onboarding guide](https://furry-adventure-596f3adb.pages.github.io/database-connections.html) #' -#' This function relies on `[{rlang}]` internal functions. +#' These functions rely on `{rlang}` internal functions. #' #' @return Requested table #' @export +#' @family database functions +#' @rdname emissions +#' +#' @examples \dontrun{ #' -#' @examples -#' \dontrun{ #' library(councilR) +#' library(DBI) #' #' # set options if you haven't already #' options( @@ -34,29 +37,42 @@ #' councilR.pwd = "mypwd" #' ) #' +#' # create connection +#' conn <- emissions_connect() +#' +#' # pull table using SQL +#' DBI::dbGetQuery(conn, "SELECT * FROM metro_energy.vw_electricity_residential_ctu") +#' +#' # disconnect +#' DBI::dbDisconnect(conn) +#' +#' # get specific tables #' t_electricity_residential_ctu <- import_from_emissions( #' table_name = "metro_energy.vw_electricity_residential_ctu" -#' ) +#' ) +#' #' t_eia_energy_consumption_state <- import_from_emissions( #' table_name = "state_energy.eia_energy_consumption_state" -#' ) +#' ) +#' # t_utility_natural_gas_by_ctu <- import_from_emissions( #' table_name = "metro_energy.vw_utility_natural_gas_by_ctu" #' ) #' } -#' @importFrom DBI dbCanConnect dbGetQuery dbConnect dbDisconnect +#' +#' @importFrom DBI dbCanConnect dbConnect #' @importFrom odbc odbc #' @importFrom utils osVersion #' @importFrom purrr map -import_from_emissions <- function(table_name, - uid = getOption("councilR.uid"), - pwd = getOption("councilR.pwd"), - local = TRUE, - db = "CD_Emissions") { - requireNamespace("rlang", quietly = TRUE) +#' @importFrom cli cli_abort +emissions_connection <- function( + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + local = TRUE, + db = "CD_Emissions") { # check input types purrr::map( - c(table_name, uid, pwd, db), + c(uid, pwd, db), rlang:::check_string ) purrr::map( @@ -90,7 +106,7 @@ import_from_emissions <- function(table_name, Pwd = pwd, Server = serv ) == FALSE) { - stop("Database failed to connect") + cli::cli_abort("Database failed to connect") } } else if (drv == "SQL Server") { if ( @@ -103,12 +119,10 @@ import_from_emissions <- function(table_name, Server = serv, Trusted_Connection = "yes" ) == FALSE) { - stop("Database failed to connect") + cli::cli_abort("Database failed to connect") } } - - conn <- if (drv == "FreeTDS") { DBI::dbConnect( @@ -131,6 +145,41 @@ import_from_emissions <- function(table_name, ) } + return(conn) +} + + +#' @param table_name character, which table to pull. +#' +#' @return `import_from_emissions()` - Requested table +#' @export +#' +#' @importFrom DBI dbGetQuery dbDisconnect +#' @importFrom purrr map +#' @rdname emissions +import_from_emissions <- function(table_name, + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + local = TRUE, + db = "CD_Emissions") { + # check input types + purrr::map( + c(table_name, uid, pwd, db), + rlang:::check_string + ) + purrr::map( + c(local), + rlang:::check_bool + ) + + + conn <- emissions_connection( + uid = uid, + pwd = pwd, + local = local, + db = db + ) + db_sp_table <- DBI::dbGetQuery( conn, paste0("SELECT * FROM ", table_name) diff --git a/R/db_gis.R b/R/db_gis.R new file mode 100644 index 0000000..7686ea5 --- /dev/null +++ b/R/db_gis.R @@ -0,0 +1,165 @@ +#' @title GISLibrary +#' +#' @description +#' Functions for interacting with GISLibrary, the primary Met Council +#' ESRI geospatial database. +#' +#' @details +#' +#' - `gis_connection()` creates an S4 Microsoft SQL Server object for GISLibrary. +#' This function will *not* automatically close the connection, so take +#' care to use [DBI::dbDisconnect()] once you are done. +#' - `import_from_gis()` imports a given table from GISLibrary and +#' converts it into a [sf::sf()] object. The connection will +#' be automatically closed after the table is imported. +#' +#' Further examples can be found in `vignette("Databases", package = "councilR")`. +#' +#' @rdname gis +#' @family database functions +#' +#' @param dbname character, database name. Default is `"GISLibrary"`. +#' @param uid character, user ID. Default is `getOption("councilR.uid")` +#' @param pwd character, user password. Default is `getOption("councilR.pwd")`. +#' +#' +#' @examples \dontrun{ +#' library(councilR) +#' library(DBI) +#' library(sf) +#' +#' # set options if you haven't already +#' options( +#' councilR.uid = "mc\\uid", +#' councilR.pwd = "mypwd" +#' ) +#' +#' # create connection +#' gis <- gis_connection() +#' +#' # pull table using SQL and convert to sf +#' DBI::dbGetQuery(gis, "select *, Shape.STAsText() as wkt from GISLibrary.dbo.AIRPORTS where APNAME ='Flying Cloud'") %>% +#' st_as_sf(wkt = "wkt", crs = 26915) +#' +#' # disconnect +#' DBI::dbDisconnect(gis) +#' +#' # import a specific table, with no additional SQL logic +#' import_from_gis(query = "GISLibrary.dbo.AIRPORTS", dbname = "GISLibrary") +#' } +#' +#' @return `gis_connection()` - A S4 Microsoft SQL Server object +#' +#' @family database functions +#' @importFrom DBI dbCanConnect dbConnect +#' @importFrom purrr map +#' @importFrom cli cli_abort +#' @importFrom odbc odbc +gis_connection <- function( + dbname = "GISLibrary", + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd")) { + purrr::map( + c(dbname, uid, pwd), + rlang:::check_string + ) + + serv <- "azdbsqlcl10.mc.local" + + # decide which driver to use based on OS + drv <- if (grepl("mac", osVersion)) { + "FreeTDS" + } else { + "SQL Server" + } + + # check that DB connection works + if (drv == "FreeTDS") { + if ( + DBI::dbCanConnect( + odbc::odbc(), + DSN = dbname, + Uid = uid, + Pwd = pwd + ) + == FALSE) { + cli::cli_abort("Database failed to connect") + } + } else if (drv == "SQL Server") { + if ( + DBI::dbCanConnect( + odbc::odbc(), + Driver = drv, + Database = dbname, + Uid = uid, + Pwd = pwd, + Server = serv, + Trusted_Connection = "yes" + ) == FALSE) { + cli::cli_abort("Database failed to connect") + } + } + + + conn <- + if (drv == "FreeTDS") { + DBI::dbConnect( + odbc::odbc(), + DSN = dbname, + Uid = uid, + Pwd = pwd + ) + } else if (drv == "SQL Server") { + DBI::dbConnect( + odbc::odbc(), + Driver = drv, + Database = dbname, + Uid = uid, + Pwd = pwd, + Server = serv, + Trusted_Connection = "yes" + ) + } +} + +#' @param query character, string with the database connection and feature class +#' @param .quiet logical, whether to print time elapsed message. +#' +#' @rdname gis +#' +#' @return `import_from_gis()` - A [sf::sf()] object +#' @export +#' @importFrom sf st_as_sf +#' @importFrom DBI dbGetQuery dbDisconnect +#' @importFrom tictoc tic toc +import_from_gis <- function(query, + dbname = "GISLibrary", + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + .quiet = FALSE) { + if (.quiet == FALSE) { + tictoc::tic() + } + + conn <- gis_connection( + dbname = dbname, + uid = uid, + pwd = pwd + ) + + que <- DBI::dbGetQuery( + conn, + paste0("SELECT *, Shape.STAsText() as wkt FROM ", query) + ) + + sf_df <- sf::st_as_sf( + que, + wkt = "wkt", crs = 26915 + ) + + DBI::dbDisconnect(conn) + + tictoc::toc() + + return(sf_df) +} diff --git a/R/fetch_county_geo.R b/R/fetch_county_geo.R index 2aa2b50..db2089d 100644 --- a/R/fetch_county_geo.R +++ b/R/fetch_county_geo.R @@ -31,7 +31,7 @@ #' ) #' } #' -#' @note This function relies on `[{rlang}]` internal functions. +#' @note This function relies on `{rlang}` internal functions. #' #' @importFrom tigris counties #' @importFrom cli cli_abort diff --git a/R/import_from_gis.R b/R/import_from_gis.R deleted file mode 100644 index 8221331..0000000 --- a/R/import_from_gis.R +++ /dev/null @@ -1,87 +0,0 @@ -#' Import a dataset from ArcCatalog -#' -#' @param query character, string with the database connection and feature class -#' @param dbname character, database name. Default is `"GISLibrary"`. -#' Must match the database name in `query`. -#' @param uid character, user ID. Default is `getOption("councilR.uid")` -#' @param pwd character, user password. Default is `getOption("councilR.pwd")`. -#' @param .quiet logical, whether to print time elapsed message. -#' -#' @note See `vignette("Options")` to review package options. -#' You must be set up with the appropriate database drivers to use this function. -#' **Windows** users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. -#' **Mac** users need `unixodbc`, `freetds`, and properly configured `odbc.ini`. -#' See instructions in the -#' [onboarding guide](https://furry-adventure-596f3adb.pages.github.io/database-connections.html) -#' and contact package maintainer for assistance. -#' -#' This function relies on `[{rlang}]` internal functions. -#' -#' @return An [`sf`] object -#' @export -#' @examples \dontrun{ -#' library(councilR) -#' -#' options( -#' councilR.uid = "mc\\uid", -#' councilR.pwd = "mypwd" -#' ) -#' -#' # query db name matches -#' import_from_gis(query = "GISLibrary.dbo.AIRPORTS", dbname = "GISLibrary") -#' } -#' @importFrom sf st_as_sf -#' @importFrom odbc odbc -#' @importFrom DBI dbGetQuery dbDisconnect dbCanConnect dbConnect -#' @importFrom tictoc tic toc -#' @importFrom purrr map -import_from_gis <- function(query, - dbname = "GISLibrary", - uid = getOption("councilR.uid"), - pwd = getOption("councilR.pwd"), - .quiet = FALSE) { - requireNamespace("rlang", quietly = TRUE) - - purrr::map( - c(query, dbname, uid, pwd), - rlang:::check_string - ) - - if (.quiet == FALSE) { - tictoc::tic() - } - - if (DBI::dbCanConnect( - odbc::odbc(), - dbname, - timeout = 10, - Uid = uid, - Pwd = pwd - ) != TRUE) { - stop("Database could not connect.") - } - - conn <- DBI::dbConnect( - odbc::odbc(), - dbname, - timeout = 10, - Uid = uid, - Pwd = pwd - ) - - que <- DBI::dbGetQuery( - conn, - paste0("SELECT *, Shape.STAsText() as wkt FROM ", query) - ) - - - sf_df <- sf::st_as_sf( - que, - wkt = "wkt", crs = 26915 - ) - DBI::dbDisconnect(conn) - - tictoc::toc() - - return(sf_df) -} diff --git a/R/import_from_gpkg.R b/R/import_from_gpkg.R index fb814a1..d5b0877 100644 --- a/R/import_from_gpkg.R +++ b/R/import_from_gpkg.R @@ -11,13 +11,14 @@ #' Default is `FALSE`. #' @param .quiet logical, suppress messages. Default is `TRUE`. #' -#' @return an [`sf`] object +#' @return [sf::sf()] object #' @export #' -#' @description Particularly useful for importing data from Minnesota Geospatial Commons -#' when access to the internal GIS database is unavailable. +#' @description This function is particularly useful for importing data from +#' [Minnesota Geospatial Commons](https://gisdata.mn.gov/) +#' when access to GISLibrary is unavailable. #' -#' @note This function relies on `[{rlang}]` internal functions. +#' @note This function relies on `{rlang}` internal functions. #' #' @importFrom sf read_sf st_transform #' @importFrom fs file_delete @@ -77,3 +78,7 @@ import_from_gpkg <- function(link, return(out_sf) } + +#' @rdname import_from_gpkg +#' @export +import_gpkg <- import_from_gpkg diff --git a/R/snippets.R b/R/snippets.R index 05335d0..584638f 100644 --- a/R/snippets.R +++ b/R/snippets.R @@ -108,7 +108,7 @@ snippets_warn_mask <- function(new, old = NULL, warn = FALSE) { } if (!identical(file_new, file_old)) { - stop("Not a good idea to compare different snippets") + cli::cli_abort("Not a good idea to compare different snippets") } snp <- diff --git a/R/theme_council.R b/R/theme_council.R index 09a605e..cfb8454 100644 --- a/R/theme_council.R +++ b/R/theme_council.R @@ -51,7 +51,7 @@ #' a pull request. #' #' -#' @note This function relies on `[{rlang}]` internal functions. +#' @note This function relies on `{rlang}` internal functions. #' Further examples in `vignette("Color")`. #' #' @examples diff --git a/R/utils.R b/R/utils.R index 36379a8..da02dd3 100644 --- a/R/utils.R +++ b/R/utils.R @@ -23,17 +23,17 @@ councilR_file <- function(...) { requires_pkg <- function(pkg) { calling_function <- deparse(sys.calls()[[sys.nframe() - 1]]) if (!requireNamespace(pkg, quietly = TRUE)) { - stop(glue("{calling_function} requires the `{pkg}` package"), call. = FALSE) + cli::cli_abort(glue("{calling_function} requires the `{pkg}` package"), call. = FALSE) } } requires_pkg_version <- function(pkg, version) { calling_function <- deparse(sys.calls()[[sys.nframe() - 1]]) tryCatch(requires_pkg(pkg), error = function(e) { - stop(glue("{calling_function} requires the `{pkg}` package"), call. = FALSE) + cli::cli_abort(glue("{calling_function} requires the `{pkg}` package"), call. = FALSE) }) if (utils::packageVersion(pkg) < package_version(version)) { - stop( + cli::cli_abort( glue("{calling_function} requires `{pkg}` version {version} or later."), call. = FALSE ) @@ -58,11 +58,11 @@ with_rstudio <- function(fn, ..., stopifnot = FALSE) { if (rstudioapi::hasFun(fn)) { rstudio_fun <- get(fn, asNamespace("rstudioapi")) tryCatch(do.call(rstudio_fun, list(...)), error = function(e) { - stop(glue("Error in rstudioapi::{fn}(): {e$message}"), call. = FALSE) + cli::cli_abort(glue("Error in rstudioapi::{fn}(): {e$message}"), call. = FALSE) }) } else { if (stopifnot) { - stop(glue( + cli::cli_abort(glue( "Your version of RStudio does not support this function: {fn}" ), call. = FALSE) } @@ -72,7 +72,7 @@ with_rstudio <- function(fn, ..., stopifnot = FALSE) { has_rstudio <- function(fn, stopifnot = FALSE) { has <- rstudioapi::hasFun(fn) if (!has && stopifnot) { - stop(glue( + cli::cli_abort(glue( "Your version of RStudio does not support this function: {fn}" ), call. = FALSE) } diff --git a/man/import_from_emissions.Rd b/man/emissions.Rd similarity index 70% rename from man/import_from_emissions.Rd rename to man/emissions.Rd index 5b64918..dc8f5fc 100644 --- a/man/import_from_emissions.Rd +++ b/man/emissions.Rd @@ -1,9 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/import_from_emissions.R -\name{import_from_emissions} +% Please edit documentation in R/db_emissions.R +\name{emissions_connection} +\alias{emissions_connection} \alias{import_from_emissions} \title{Import data table from greenhouse gas emissions scenario planning database} \usage{ +emissions_connection( + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + local = TRUE, + db = "CD_Emissions" +) + import_from_emissions( table_name, uid = getOption("councilR.uid"), @@ -13,8 +21,6 @@ import_from_emissions( ) } \arguments{ -\item{table_name}{character, which table to pull.} - \item{uid}{character, your network ID. Default is \code{getOption("councilR.uid")}. If you are accessing Azure, this value should be your full email address.} @@ -26,9 +32,13 @@ Default is \code{getOption("councilR.pwd")}. For example, \code{"my_password"}} Default is \code{TRUE}.} \item{db}{character, database name. Default is \code{"CD_Emissions"}.} + +\item{table_name}{character, which table to pull.} } \value{ Requested table + +\code{import_from_emissions()} - Requested table } \description{ Import data table from greenhouse gas emissions scenario planning database @@ -38,17 +48,19 @@ To access Azure, your IP address must be approved. Contact Sean Molloy. } \note{ See \code{vignette("Options")} to review package options. -You must be set up with the appropriate database drivers to use this function. +You must be set up with the appropriate database drivers to use these functions. \strong{Windows} users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. \strong{Mac} users need \code{unixodbc} and \code{freetds}. See instructions in the \href{https://furry-adventure-596f3adb.pages.github.io/database-connections.html}{onboarding guide} -\if{html}{\out{
}}\preformatted{This function relies on `[\{rlang\}]` internal functions. +\if{html}{\out{
}}\preformatted{These functions rely on `\{rlang\}` internal functions. }\if{html}{\out{
}} } \examples{ \dontrun{ + library(councilR) +library(DBI) # set options if you haven't already options( @@ -56,13 +68,32 @@ options( councilR.pwd = "mypwd" ) +# create connection +conn <- emissions_connect() + +# pull table using SQL +DBI::dbGetQuery(conn, "SELECT * FROM metro_energy.vw_electricity_residential_ctu") + +# disconnect +DBI::dbDisconnect(conn) + +# get specific tables t_electricity_residential_ctu <- import_from_emissions( table_name = "metro_energy.vw_electricity_residential_ctu" -) + ) + t_eia_energy_consumption_state <- import_from_emissions( table_name = "state_energy.eia_energy_consumption_state" -) + ) + table_name = "metro_energy.vw_utility_natural_gas_by_ctu" ) } + +} +\seealso{ +Other database functions: +\code{\link{FRED_connection}()}, +\code{\link{gis_connection}()} } +\concept{database functions} diff --git a/man/fetch_county_geo.Rd b/man/fetch_county_geo.Rd index 2e863e2..f14f94a 100644 --- a/man/fetch_county_geo.Rd +++ b/man/fetch_county_geo.Rd @@ -24,7 +24,7 @@ The default \code{fetch_county_geo()} to return county outlines, plus a suite of To get city, township, and unorganized territory (CTU) boundaries, use \code{fetch_ctu_geo()}. } \note{ -This function relies on \verb{[\{rlang\}]} internal functions. +This function relies on \code{{rlang}} internal functions. } \examples{ \dontrun{ diff --git a/man/import_from_FRED.Rd b/man/fred.Rd similarity index 50% rename from man/import_from_FRED.Rd rename to man/fred.Rd index ae66c55..0c7ffd7 100644 --- a/man/import_from_FRED.Rd +++ b/man/fred.Rd @@ -1,11 +1,26 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/import_from_FRED.R -\name{import_from_FRED} +% Please edit documentation in R/db_FRED.R +\name{FRED_connection} +\alias{FRED_connection} +\alias{fred_connection} \alias{import_from_FRED} \alias{import_from_fred} -\title{Import data table from FRED (main CD Research database) data stored -Azure SQL Server} +\title{FRED} \usage{ +FRED_connection( + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + db = "CD_RESEARCH_WEB", + prod = TRUE +) + +fred_connection( + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + db = "CD_RESEARCH_WEB", + prod = TRUE +) + import_from_FRED( table_name, uid = getOption("councilR.uid"), @@ -23,8 +38,6 @@ import_from_fred( ) } \arguments{ -\item{table_name}{character, which table to pull.} - \item{uid}{character, your network ID. Default is \code{getOption("councilR.uid")}.} @@ -35,36 +48,70 @@ Default is \code{getOption("councilR.pwd")}. For example, \code{"mypwd"}} \item{prod}{logical, whether to pull from the test or production db. Default is \code{TRUE}.} + +\item{table_name}{character, which table to pull.} } \value{ -Requested table +\code{fred_connection()} - A S4 Microsoft SQL Server object + +\code{import_from_FRED()} - Requested table } \description{ -Import data table from FRED (main CD Research database) data stored +Functions for interacting with FRED, the main CD Research database, stored Azure SQL Server } +\details{ +Both "FRED" and "fred" capitalization are supported. +\itemize{ +\item \code{fred_connection()} creates an S4 Microsoft SQL Server object for FRED. +This function will \emph{not} automatically close the connection, so take +care to use \code{\link[DBI:dbDisconnect]{DBI::dbDisconnect()}} once you are done. +\item \code{import_from_fred()} imports a given table from FRED. The connection will +be automatically closed after the table is imported. +} +} \note{ See \code{vignette("Options")} to review package options. -You must be set up with the appropriate database drivers to use this function. + +You must be set up with the appropriate database drivers to use these functions. + \strong{Windows} users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. + \strong{Mac} users need \code{unixodbc}, \code{freetds}, and properly configured \code{odbc.ini}. + See instructions in the \href{https://furry-adventure-596f3adb.pages.github.io/database-connections.html}{onboarding guide} and contact package maintainer for assistance. - -\if{html}{\out{
}}\preformatted{This function relies on `[\{rlang\}]` internal functions. -}\if{html}{\out{
}} +These functions rely on \code{{rlang}} internal functions. +Further examples can be found in \code{vignette("Databases")}. } \examples{ \dontrun{ library(councilR) +library(DBI) # set options if you haven't already options( councilR.uid = "mc\\\\you", councilR.pwd = "mypwd" ) +# create connection +conn <- FRED_connection(prod = FALSE) + +# pull table using SQL +DBI::dbGetQuery(conn, "SELECT * FROM GQ_UNIT WHERE UNIT_ZIP = 55104") +# disconnect +DBI::dbDisconnect(conn) + +# import a specific table, with no additional SQL logic import_from_FRED(table_name = "GQ_UNIT", prod = FALSE) } + +} +\seealso{ +Other database functions: +\code{\link{emissions_connection}()}, +\code{\link{gis_connection}()} } +\concept{database functions} diff --git a/man/gis.Rd b/man/gis.Rd new file mode 100644 index 0000000..f79a8e0 --- /dev/null +++ b/man/gis.Rd @@ -0,0 +1,90 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/db_gis.R +\name{gis_connection} +\alias{gis_connection} +\alias{import_from_gis} +\title{GISLibrary} +\usage{ +gis_connection( + dbname = "GISLibrary", + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd") +) + +import_from_gis( + query, + dbname = "GISLibrary", + uid = getOption("councilR.uid"), + pwd = getOption("councilR.pwd"), + .quiet = FALSE +) +} +\arguments{ +\item{dbname}{character, database name. Default is \code{"GISLibrary"}.} + +\item{uid}{character, user ID. Default is \code{getOption("councilR.uid")}} + +\item{pwd}{character, user password. Default is \code{getOption("councilR.pwd")}.} + +\item{query}{character, string with the database connection and feature class} + +\item{.quiet}{logical, whether to print time elapsed message.} +} +\value{ +\code{gis_connection()} - A S4 Microsoft SQL Server object + +\code{import_from_gis()} - A \code{\link[sf:sf]{sf::sf()}} object +} +\description{ +Functions for interacting with GISLibrary, the primary Met Council +ESRI geospatial database. +} +\details{ +\itemize{ +\item \code{gis_connection()} creates an S4 Microsoft SQL Server object for GISLibrary. +This function will \emph{not} automatically close the connection, so take +care to use \code{\link[DBI:dbDisconnect]{DBI::dbDisconnect()}} once you are done. +\item \code{import_from_gis()} imports a given table from GISLibrary and +converts it into a \code{\link[sf:sf]{sf::sf()}} object. The connection will +be automatically closed after the table is imported. +} + +Further examples can be found in \code{vignette("Databases", package = "councilR")}. +} +\examples{ +\dontrun{ +library(councilR) +library(DBI) +library(sf) + +# set options if you haven't already +options( + councilR.uid = "mc\\\\uid", + councilR.pwd = "mypwd" +) + +# create connection +gis <- gis_connection() + +# pull table using SQL and convert to sf +DBI::dbGetQuery(gis, "select *, Shape.STAsText() as wkt from GISLibrary.dbo.AIRPORTS where APNAME ='Flying Cloud'") \%>\% + st_as_sf(wkt = "wkt", crs = 26915) + +# disconnect +DBI::dbDisconnect(gis) + +# import a specific table, with no additional SQL logic +import_from_gis(query = "GISLibrary.dbo.AIRPORTS", dbname = "GISLibrary") +} + +} +\seealso{ +Other database functions: +\code{\link{FRED_connection}()}, +\code{\link{emissions_connection}()} + +Other database functions: +\code{\link{FRED_connection}()}, +\code{\link{emissions_connection}()} +} +\concept{database functions} diff --git a/man/import_from_gis.Rd b/man/import_from_gis.Rd deleted file mode 100644 index 1920879..0000000 --- a/man/import_from_gis.Rd +++ /dev/null @@ -1,56 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/import_from_gis.R -\name{import_from_gis} -\alias{import_from_gis} -\title{Import a dataset from ArcCatalog} -\usage{ -import_from_gis( - query, - dbname = "GISLibrary", - uid = getOption("councilR.uid"), - pwd = getOption("councilR.pwd"), - .quiet = FALSE -) -} -\arguments{ -\item{query}{character, string with the database connection and feature class} - -\item{dbname}{character, database name. Default is \code{"GISLibrary"}. -Must match the database name in \code{query}.} - -\item{uid}{character, user ID. Default is \code{getOption("councilR.uid")}} - -\item{pwd}{character, user password. Default is \code{getOption("councilR.pwd")}.} - -\item{.quiet}{logical, whether to print time elapsed message.} -} -\value{ -An \code{\link{sf}} object -} -\description{ -Import a dataset from ArcCatalog -} -\note{ -See \code{vignette("Options")} to review package options. -You must be set up with the appropriate database drivers to use this function. -\strong{Windows} users need ODBC with Microsoft SQL. Contact IS support for ODBC installation. -\strong{Mac} users need \code{unixodbc}, \code{freetds}, and properly configured \code{odbc.ini}. -See instructions in the -\href{https://furry-adventure-596f3adb.pages.github.io/database-connections.html}{onboarding guide} -and contact package maintainer for assistance. - -This function relies on \verb{[\{rlang\}]} internal functions. -} -\examples{ -\dontrun{ -library(councilR) - -options( - councilR.uid = "mc\\\\uid", - councilR.pwd = "mypwd" -) - -# query db name matches -import_from_gis(query = "GISLibrary.dbo.AIRPORTS", dbname = "GISLibrary") -} -} diff --git a/man/import_from_gpkg.Rd b/man/import_from_gpkg.Rd index 842e52e..0b68484 100644 --- a/man/import_from_gpkg.Rd +++ b/man/import_from_gpkg.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/import_from_gpkg.R \name{import_from_gpkg} \alias{import_from_gpkg} +\alias{import_gpkg} \title{Import an \code{sf} object using a geopackage URL} \usage{ import_from_gpkg( @@ -12,6 +13,15 @@ import_from_gpkg( keep_temp = FALSE, .quiet = TRUE ) + +import_gpkg( + link, + save_file = FALSE, + save_path = getwd(), + .crs = 4326, + keep_temp = FALSE, + .quiet = TRUE +) } \arguments{ \item{link}{character, URL for the \code{.gpkg} object} @@ -31,14 +41,15 @@ Default is \code{FALSE}.} \item{.quiet}{logical, suppress messages. Default is \code{TRUE}.} } \value{ -an \code{\link{sf}} object +\code{\link[sf:sf]{sf::sf()}} object } \description{ -Particularly useful for importing data from Minnesota Geospatial Commons -when access to the internal GIS database is unavailable. +This function is particularly useful for importing data from +\href{https://gisdata.mn.gov/}{Minnesota Geospatial Commons} +when access to GISLibrary is unavailable. } \note{ -This function relies on \verb{[\{rlang\}]} internal functions. +This function relies on \code{{rlang}} internal functions. } \examples{ diff --git a/man/theme_council.Rd b/man/theme_council.Rd index 53fe084..fd5c33a 100644 --- a/man/theme_council.Rd +++ b/man/theme_council.Rd @@ -48,7 +48,7 @@ Please note that the y-axis text is horizontal, and long axis names will need to For example, consider using this piece of code: \code{labs(y = stringr::str_wrap("Axis labels are now horizontal, but you still need to insert some code to wrap long labels", width = 15))} } \note{ -This function relies on \verb{[\{rlang\}]} internal functions. +This function relies on \code{{rlang}} internal functions. Further examples in \code{vignette("Color")}. } \section{Council fonts}{ diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R index 5ad7f3c..ab94b5a 100644 --- a/tests/testthat/setup.R +++ b/tests/testthat/setup.R @@ -1,5 +1,5 @@ options( tigris_use_cache = TRUE, progress_bar = FALSE, - tigris_refresh = FALSE + tigris_refresh = ifelse(testthat:::on_ci(), TRUE, FALSE) ) diff --git a/tests/testthat/test-db_FRED.R b/tests/testthat/test-db_FRED.R new file mode 100644 index 0000000..b9673b3 --- /dev/null +++ b/tests/testthat/test-db_FRED.R @@ -0,0 +1,85 @@ +# Can import_from_gis() actually import from the GISLibrary database? + +# skip on GH Actions +testthat::skip_on_ci() + +# skip if not connected to VPN +testthat::skip_if( + is.null(curl::nslookup("mc.local")) +) + +testthat::skip_if(httr2::secret_has_key("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins")) + + +testthat::test_that("upercase group quarters table", { + gq <- import_from_FRED( + table_name = "GQ_UNIT", + prod = TRUE, + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY"), + db = "CD_RESEARCH_WEB" + ) + + # test that data is returned from gq unit table, currently 11837 rows + testthat::expect_gte(nrow(gq), 11837) + + # test that object returned is a data.frame + testthat::expect_equal(class(gq)[[1]], "data.frame") +}) + + +testthat::test_that("lowercase group quarters table", { + gq <- import_from_fred( + table_name = "GQ_UNIT", + prod = TRUE, + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY"), + db = "CD_RESEARCH_WEB" + ) + + # test that data is returned from gq unit table, currently 11837 rows + testthat::expect_gte(nrow(gq), 11837) + + # test that object returned is a data.frame + testthat::expect_equal(class(gq)[[1]], "data.frame") +}) + + +testthat::test_that("lowercase park unit via SQL", { + fred <- fred_connection( + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY"), + db = "CD_RESEARCH_WEB" + ) + + testthat::expect_s4_class(fred, "Microsoft SQL Server") + + park_unit <- DBI::dbGetQuery(fred, "SELECT * FROM PARK_UNIT WHERE PARK_UNIT_ID_CURRENT = '094'") + + # test that data is returned from gq unit table, currently 11837 rows + testthat::expect_gte(nrow(park_unit), 1) + + # test that object returned is a data.frame + testthat::expect_equal(class(park_unit)[[1]], "data.frame") +}) + + + +testthat::test_that("uppercase park unit via SQL", { + fred <- FRED_connection( + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY"), + db = "CD_RESEARCH_WEB" + ) + + + testthat::expect_s4_class(fred, "Microsoft SQL Server") + + park_unit <- DBI::dbGetQuery(fred, "SELECT * FROM MANUFACTURED_HOUSING_PARK WHERE PARK_ID_CURRENT = 23") + + # test that data is returned from gq unit table, currently 11837 rows + testthat::expect_gte(nrow(park_unit), 1) + + # test that object returned is a data.frame + testthat::expect_equal(class(park_unit)[[1]], "data.frame") +}) diff --git a/tests/testthat/test-import_from_emissions.R b/tests/testthat/test-db_emissions.R similarity index 57% rename from tests/testthat/test-import_from_emissions.R rename to tests/testthat/test-db_emissions.R index aa0abab..daa92aa 100644 --- a/tests/testthat/test-import_from_emissions.R +++ b/tests/testthat/test-db_emissions.R @@ -1,6 +1,6 @@ # basic testing -test_that("When local == FALSE, return an error message", { +testthat::test_that("When local == FALSE, return an error message", { testthat::expect_error( mod_2 <- import_from_emissions( local = FALSE, @@ -12,7 +12,6 @@ test_that("When local == FALSE, return an error message", { # skip on GH Actions testthat::skip_on_ci() -testthat::skip_on_cran() # skip if not connected to VPN testthat::skip_if( @@ -21,6 +20,26 @@ testthat::skip_if( testthat::skip_if(httr2::secret_has_key("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins")) + + +testthat::test_that("emissions connection returns connection object", { + test_conn <- emissions_connection( + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY") + ) + + testthat::expect_s4_class(test_conn, "Microsoft SQL Server") + + ctu_test <- DBI::dbGetQuery(test_conn, "SELECT * FROM metro_energy.vw_electricity_residential_ctu") + + testthat::expect_equal(nrow(ctu_test), 186) + + DBI::dbDisconnect(test_conn) +}) + + + + testthat::test_that("Residential electricity data is returned", { electric_residential <- import_from_emissions( uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), diff --git a/tests/testthat/test-import_from_gis.R b/tests/testthat/test-db_gis.R similarity index 62% rename from tests/testthat/test-import_from_gis.R rename to tests/testthat/test-db_gis.R index ea0b14c..c481009 100644 --- a/tests/testthat/test-import_from_gis.R +++ b/tests/testthat/test-db_gis.R @@ -10,8 +10,25 @@ testthat::skip_if( testthat::skip_if(httr2::secret_has_key("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins")) -# test return object attributes +testthat::test_that("GIS connection returns connection object", { + test_conn <- gis_connection( + uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), + pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY") + ) + + testthat::expect_s4_class(test_conn, "Microsoft SQL Server") + + airp_test <- DBI::dbGetQuery(test_conn, "SELECT * FROM AIRPORTS WHERE APNAME = 'Flying Cloud'") + + testthat::expect_equal(nrow(airp_test), 4) + DBI::dbDisconnect(test_conn) +}) + + + + +# test return object attributes testthat::test_that("airports spatial dataset", { airport <- import_from_gis( uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), diff --git a/tests/testthat/test-import_from_FRED.R b/tests/testthat/test-import_from_FRED.R deleted file mode 100644 index 8e2fabb..0000000 --- a/tests/testthat/test-import_from_FRED.R +++ /dev/null @@ -1,28 +0,0 @@ -# Can import_from_gis() actually import from the GISLibrary database? - -# skip on GH Actions -testthat::skip_on_ci() - -# skip if not connected to VPN -testthat::skip_if( - is.null(curl::nslookup("mc.local")) -) - -testthat::skip_if(httr2::secret_has_key("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins")) - - -testthat::test_that("group quarters dataset", { - gq <- import_from_FRED( - table_name = "GQ_UNIT", - prod = FALSE, - uid = httr2::secret_decrypt("QUHBRb_yoy2RRj59qno8NVXA7mW402xkins", "COUNCILR_KEY"), - pwd = httr2::secret_decrypt("rQHk4S39pjfJ6yoKWUUNpQUDk2i9XA3d", "COUNCILR_KEY"), - db = "CD_RESEARCH_WEB" - ) - - # test that data is returned from gq unit table, currently 11837 rows - testthat::expect_gte(nrow(gq), 11837) - - # test that object returned is a data.frame - testthat::expect_equal(class(gq)[[1]], "data.frame") -}) diff --git a/tests/testthat/test-import_from_gpkg.R b/tests/testthat/test-import_from_gpkg.R index e083f23..dd0a3d9 100644 --- a/tests/testthat/test-import_from_gpkg.R +++ b/tests/testthat/test-import_from_gpkg.R @@ -1,7 +1,19 @@ testthat::skip_if_offline() +testthat::test_that("metc districts with import from", { + districts <- import_from_gpkg("https://resources.gisdata.mn.gov/pub/gdrs/data/pub/us_mn_state_metc/bdry_mcdistricts_2013/gpkg_bdry_mcdistricts_2013.zip") -testthat::expect_true(class(import_from_gpkg("https://resources.gisdata.mn.gov/pub/gdrs/data/pub/us_mn_state_metc/bdry_mcdistricts_2013/gpkg_bdry_mcdistricts_2013.zip"))[[1]] == "sf") + testthat::expect_s3_class(districts, "sf") + testthat::expect_equal(nrow(districts), 16) +}) -# testthat::expect_true(class(import_from_gpkg("https://resources.gisdata.mn.gov/pub/gdrs/data/pub/us_mn_state_metc/plan_parks_regional/gpkg_plan_parks_regional.zip"))[[1]] == "sf") + + +testthat::test_that("metc districts with import_gpkg", { + districts <- import_gpkg("https://resources.gisdata.mn.gov/pub/gdrs/data/pub/us_mn_state_metc/bdry_mcdistricts_2013/gpkg_bdry_mcdistricts_2013.zip") + + testthat::expect_s3_class(districts, "sf") + + testthat::expect_equal(nrow(districts), 16) +}) diff --git a/vignettes/Databases.Rmd b/vignettes/Databases.Rmd new file mode 100644 index 0000000..3ced82a --- /dev/null +++ b/vignettes/Databases.Rmd @@ -0,0 +1,122 @@ +--- +title: "Databases" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Databases} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + eval = FALSE +) +``` + +```{r setup} +library(councilR) +``` + +Database connections are a critical part of the work we do at the Metropolitan Council. + +See `vignette("Options", package = "councilR")` to review package options that make these functions run more smoothly. All `uid` and `pwd` parameters are `getOption("councilR.uid")` and `getOption("councilR.pwd")`. + +## FRED + +FRED contains most of CD Research's data tables, including tables for regional parks use estimates, population estimates, group quarters, and much more. Once you have the connection, you can use SQL queries to fetch only the data you need. + +```{r fred-sql, eval=FALSE} +library(DBI) +fred <- fred_connection() + +DBI::dbListTables(fred, )[1:20] + +head(DBI::dbGetQuery(fred, "SELECT * FROM GQ_UNIT WHERE UNIT_ZIP = 55104")) + +DBI::dbDisconnect(fred) +``` + + +The database connection is also useful if you want to pull multiple tables from a single connection with `{purrr}`. + +```{r fred-purrr, eval=FALSE} +library(purrr) +library(dplyr) + +fred <- fred_connection() + +park_tables <- purrr::map( + # park table names + list( + "PARK_UNIT", + "PARK_TYPE", + "PARK_IMPL_AGENCY" + ), + function(x) { + # for each table name, locate and collect data + dplyr::tbl(fred, x) %>% + dplyr::collect() + } +) + +park_tables + +DBI::dbDisconnect(fred) +``` + + +If you know the name of the table you need, you can pull it directly with `import_from_fred()`. This uses SQL `SELECT * FROM ___`. + + +```{r fred-table, eval=FALSE} +head(import_from_FRED(table_name = "GQ_UNIT", prod = FALSE)) +``` + + +## GISLibrary + +GISLibrary is an ESRI SQL database that contains essential geospatial datasets. + +Generally, if the Council has published a dataset on [Minnesota Geospatial Commons](https://gisdata.mn.gov/), it is available in GISLibrary. + +```{r gis-sql, eval=FALSE} +# create connection +gis <- gis_connection() + +# fetch with SQL +DBI::dbGetQuery(gis, "select *, Shape.STAsText() as wkt from GISLibrary.dbo.AIRPORTS where APNAME ='Flying Cloud'") + +# remember to disconnect! +DBI::dbDisconnect(gis) +``` + +```{r gis-table, eval=FALSE} +# import a specific table as an sf object, with no additional SQL +airport <- import_from_gis( + query = "GISLibrary.dbo.AIRPORTS", + .quiet = TRUE +) +``` + +## Emissions + +The emissions database is used for GHG inventory and scenario planning projects. + +```{r emissions-sql, eval=FALSE} +# create connection +emissions <- emissions_connection() + +# fetch with SQL +DBI::dbGetQuery(emissions, "SELECT * FROM metro_energy.vw_electricity_residential_ctu") + +# remember to disconnect! +DBI::dbDisconnect(emissions) +``` + +```{r emissions-table, eval=FALSE} +# import a specific table with no additional SWL +import_from_emissions("metro_energy.vw_electricity_residential_ctu") +``` +