239 lines
7.5 KiB
R
239 lines
7.5 KiB
R
|
|
# Connection management --------------------------------------------------------
|
|
|
|
#' MODB Connection References
|
|
#'
|
|
#' \code{modb_conn_ref} checks for and/or validates parameters that may be a
|
|
#' connection reference. Connections in MODB may be named on creation or must
|
|
#' be referenced by the unique ID that is returned by the
|
|
#' \link{\code{modb_connect}} method.
|
|
#'
|
|
#' @param conn_id Integer. The ID of the connection returned by modb_connect
|
|
#' @param conn_name String. The name provided when creating a connection.
|
|
#' @param conn_ref Expected to be either a conn_id or a conn_name
|
|
#' @param args list(...) Arguments passed to a calling function in the va scope.
|
|
#' @seealso \link{\code{modb_connect}}
|
|
#' @export
|
|
modb_conn_ref <- function(conn_id, conn_name, conn_ref, args = NULL) {
|
|
if (length(args) != 0) {
|
|
if ("conn_ref" %in% ls(args)) {
|
|
conn_ref <- args$conn_ref
|
|
}
|
|
if ("conn_id" %in% ls(args)) {
|
|
conn_id <- args$conn_id
|
|
}
|
|
if ("conn_name" %in% ls(args)) {
|
|
conn_name <- args$conn_name
|
|
}
|
|
}
|
|
|
|
if (!missing(conn_ref)) {
|
|
if (checkmate::test_string(conn_ref)) {
|
|
return(conn_ref)
|
|
} else if (checkmate::test_int(conn_ref)) {
|
|
return(as.integer(conn_ref))
|
|
} else {
|
|
stop("invalid connection ref provided (must be string(name) or int(id))")
|
|
}
|
|
} else if (!missing(conn_id)) {
|
|
if (!checkmate::test_null(conn_id)) {
|
|
checkmate::assert_int(conn_id)
|
|
return(as.integer(conn_id))
|
|
}
|
|
} else if (!missing(conn_name)) {
|
|
if (!checkmate::test_null(conn_name)) {
|
|
checkmate::assert_string(conn_name)
|
|
return(conn_name)
|
|
}
|
|
}
|
|
|
|
stop("one of the arguments \"conn_ref\", \"conn_id\" or \"conn_name\" must be provided")
|
|
}
|
|
|
|
|
|
#' MODB Connections
|
|
#'
|
|
#' \code{modb_connect} creates a new database connection and attmepts to open a
|
|
#' connection to a database with the details provided.
|
|
#'
|
|
#' @param username String. Username to use when connecting to the database.
|
|
#' @param password String. Password to use when connecting to the database.
|
|
#' @param database String. The database to use.
|
|
#' @param host String. The hostname or IP address to connect to.
|
|
#' Either host & port or socket may be used
|
|
#' @param port Integer. The port number to connect on.
|
|
#' @param socket String. The socket path to connect to,
|
|
#' e.g. /var/run/mysqld/mysqld.sock
|
|
#' @param name String. A name for the connection which can be used to identify
|
|
#' the connection later on. Alternatively the id returned
|
|
#' can be used.
|
|
#' @return The id of the connection
|
|
#' @export
|
|
modb_connect <- function(username, password, database,
|
|
host = "localhost", port = 3306,
|
|
socket = NULL, conn_name = NULL) {
|
|
checkmate::assert_string(username)
|
|
checkmate::assert_string(password)
|
|
checkmate::assert_string(database)
|
|
|
|
if (checkmate::test_null(socket)) {
|
|
checkmate::assert_string(host)
|
|
checkmate::assert_int(port, lower = 1, upper = 65535)
|
|
res <- .Call(
|
|
c_rmodb_connectToHost,
|
|
conn_name,
|
|
host,
|
|
as.integer(port),
|
|
username,
|
|
password,
|
|
database
|
|
)
|
|
} else {
|
|
res <- .Call(
|
|
c_rmodb_connectToSocket, conn_name, socket, username, password, database
|
|
)
|
|
}
|
|
|
|
if (res < 0) {
|
|
stop("failed to create connection")
|
|
}
|
|
|
|
return(res)
|
|
}
|
|
|
|
#' MODB Connections
|
|
#'
|
|
#' modb_disconnect closes a database connection and cleans up the instance
|
|
#'
|
|
#' @param ... conn_id, conn_name or conn_ref required. See \link{modb_conn_ref}
|
|
#' @export
|
|
modb_disconnect <- function(...) {
|
|
res <- .Call(c_rmodb_disconnect, modb_conn_ref(args = list(...)))
|
|
return(invisible(res))
|
|
}
|
|
|
|
#' MODB Connections
|
|
#'
|
|
#' Fetches information on a connection such as the last query, insert id and
|
|
#' number of queries run
|
|
#'
|
|
#' @param ... conn_id, conn_name or conn_ref required. See \link{modb_conn_ref}
|
|
#' @return The details of the connection as a list.
|
|
#' @export
|
|
modb_connectionInfo <- function(stop_on_error = TRUE, ...) {
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
utils::str(conn_ref)
|
|
res <- .Call(c_rmodb_connectionInfo, conn_ref)
|
|
|
|
if (length(res) == sum(is.na(res))) {
|
|
if (stop_on_error) {
|
|
stop("invalid connection reference")
|
|
} else {
|
|
warning("invalid connection reference")
|
|
return(NA)
|
|
}
|
|
}
|
|
|
|
return(res)
|
|
}
|
|
|
|
#' @describeIn modb_connectionInfo Determines if a connection with the name or
|
|
#' id provided exists
|
|
#' @param ... conn_id, conn_name or conn_ref required. See \link{modb_conn_ref}
|
|
#' @return TRUE if the connection exists, FALSE if not.
|
|
#' @export
|
|
modb_connectionExists <- function(...) {
|
|
res <- .Call(c_rmodb_connectionInfo, modb_conn_ref(args = list(...)))
|
|
return(!(length(res) == sum(is.na(res))))
|
|
}
|
|
|
|
#' @describeIn modb_connectionInfo Finds a connection id via the name
|
|
#' @param conn_name String. The name provided when creating a connection.
|
|
#' @return The ID of the connection.
|
|
#' @export
|
|
modb_connectionId <- function(conn_name, stop_on_error = TRUE) {
|
|
info <- modb_connectionInfo(stop_on_error, conn_ref = conn_name)
|
|
if (length(info) == sum(is.na(info))) {
|
|
return(NA)
|
|
}
|
|
return(info$id)
|
|
}
|
|
#' @describeIn modb_connectionInfo Finds a connection name via the id
|
|
#' @param conn_id Integer. The id of the connection, returned by modb_connect.
|
|
#' @return The name of the connection.
|
|
#' @export
|
|
modb_connectionName <- function(conn_id, stop_on_error = TRUE) {
|
|
info <- modb_connectionInfo(stop_on_error, conn_ref = conn_id)
|
|
if (length(info) == sum(is.na(info))) {
|
|
return(NA)
|
|
}
|
|
return(info$name)
|
|
}
|
|
|
|
|
|
# Database management ----------------------------------------------------------
|
|
|
|
#' @export
|
|
modb_exists <- function(modb_name, ...) {
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
res <- .Call(c_rmodb_exists, conn_ref, modb_name)
|
|
return(res)
|
|
}
|
|
#' @export
|
|
modb_create <- function(modb_name, extended_meta = NULL, ...) {
|
|
checkmate::assert_string(modb_name)
|
|
|
|
# If a dataframe: data.frame(name = c(1, 2, 3), type = c('a', 'b', 'c'), nullable = c(1,0,1), stringsAsFactors=F)
|
|
# extended_meta %>% rowwise() %>% transmute(r = list(c("A" = A, "B" = B, "C" = C))) %>% first()
|
|
if (!checkmate::test_null(extended_meta)) {
|
|
for (idx in 1:length(extended_meta)) {
|
|
meta_col <- extended_meta[[idx]]
|
|
|
|
if (!("name" %in% names(meta_col))) {
|
|
stop("missing name in extended_meta definition")
|
|
} else {
|
|
checkmate::assert_string(meta_col$name)
|
|
}
|
|
|
|
if (!("type" %in% names(meta_col))) {
|
|
stop("missing type in extended_meta definition")
|
|
} else {
|
|
type <- meta_col$type
|
|
checkmate::assert_int(type, lower = 0, upper = TYPE_TIMESTAMP)
|
|
checkmate::assert_true(type == 1 || type %% 2 == 0)
|
|
meta_col$type <- as.integer(type)
|
|
}
|
|
|
|
if (!("nullable" %in% names(meta_col))) {
|
|
meta_col$nullable = FALSE
|
|
} else {
|
|
checkmate::assert_logical(meta_col$nullable)
|
|
}
|
|
|
|
extended_meta[[idx]] <- meta_col
|
|
}
|
|
}
|
|
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
res <- .Call(c_rmodb_create, conn_ref, modb_name, extended_meta)
|
|
return(res)
|
|
}
|
|
#' @export
|
|
modb_destroy <- function(modb_name, ...) {
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
res <- .Call(c_rmodb_destroy, conn_ref, modb_name)
|
|
return(res)
|
|
}
|
|
|
|
#' @export
|
|
modb_use <- function(modb_name, override = FALSE, ...) {
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
res <- .Call(c_rmodb_use, conn_ref, modb_name, as.logical(override))
|
|
return(res)
|
|
}
|
|
|
|
modb_get_last_query <- function(...) {
|
|
conn_ref <- modb_conn_ref(args = list(...))
|
|
res <- .Call(c_rmodb_getLastQuery, conn_ref)
|
|
return(res)
|
|
} |