diff --git a/DESCRIPTION b/DESCRIPTION index f6a12e2..70d803f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,7 +13,10 @@ License: MIT + file LICENSE VignetteBuilder: knitr Depends: R (>= 3.3) -Imports: +Imports: + assertthat, + DBI (>= 0.3.0), + methods, utils, httr (>= 1.3), jsonlite, @@ -23,9 +26,11 @@ Imports: rappdirs, dbplyr, dplyr, + purrr, tidyselect (>= 0.2.4) Suggests: knitr, + DBItest, testthat Roxygen: list(markdown=TRUE) RoxygenNote: 6.1.0.9000 diff --git a/R/#AzureDataExplorer.R# b/R/#AzureDataExplorer.R# deleted file mode 100644 index 140bc4e..0000000 --- a/R/#AzureDataExplorer.R# +++ /dev/null @@ -1,16 +0,0 @@ -.onLoad <- function(libname, pkgname) -{ - config_dir <- config_dir() - if(!dir.exists(config_dir)) - dir.create(config_dir, recursive=TRUE) - - add_methods() - invisible(NULL) -} - - -config_dir <- function() -{ - rappdirs::user_config_dir(appname="AzureDataExplorer", appauthor="AzureR", roaming=FALSE) -} -c \ No newline at end of file diff --git a/R/#az_kusto.R# b/R/#az_kusto.R# deleted file mode 100644 index 7b373dc..0000000 --- a/R/#az_kusto.R# +++ /dev/null @@ -1,12 +0,0 @@ -#' @export -az_data_explorer <- R6::R6Class("az_data_explorer", inherit=AzureRMR::az_resource, - public=list( - get_ade_cluster=function(tenant=NULL) - { - clus_name <- sub(".kusto.windows.net$", "", httr::parse_url(self$properties$queryUri)$host) - if(is.null(tenant)) - tenant <- self$properties$trustedExternalTenants[[1]]$value - ade_cluster(clus_name, tenant=tenant) - } -)) - diff --git a/R/.#az_kusto.R b/R/.#az_kusto.R deleted file mode 120000 index 35b7bd6..0000000 --- a/R/.#az_kusto.R +++ /dev/null @@ -1 +0,0 @@ -alex@alex-XPS-13-9343.5633:1506128837 \ No newline at end of file diff --git a/R/dbi.R b/R/dbi.R new file mode 100644 index 0000000..532f619 --- /dev/null +++ b/R/dbi.R @@ -0,0 +1,88 @@ +#' Driver for Azure Data Explorer +#' +#' @keywords internal +#' @export +#' @import DBI +#' @import methods +setClass("AzureDataExplorerDriver", contains = "DBIDriver") + +#' @export +#' @rdname AzureDataExplorer-class +setMethod("dbUnloadDriver", "AzureDataExplorerDriver", function(drv, ...) +{ + TRUE +}) + +setMethod("show", "AzureDataExplorerDriver", function(object){ + cat("\n") +}) + +AzureDataExplorer <- function() +{ + new("AzureDataExplorerDriver") +} + +#' AzureDataExplorer connection class. +#' +#' @export +#' @keywords internal +setClass("AzureDataExplorerConnection", + contains = "DBIConnection", + slots = list( + host = "character", + ptr = "externalptr" + )) + +#' @param drv An object created by AzureDataExplorer +#' @rdname AzureDataExplorer +#' @export +#' @examples +#' \dontrun{ +#' db <- dbConnect(AzureDataExplorer::AzureDataExplorer()) +#' dbWriteTable(db, "mtcars", mtcars) +#' dbGetQuery(db, "mtcars | where cyl == 4") +#' } +setMethod("dbConnect", "AzureDataExplorerDriver", function(drv, ...) +{ + new("AzureDataExplorerConnection", host=host, ...) +}) + +#' AzureDataExplorer results class +#' +#' @keywords internal +#' @export +setClass("AzureDataExplorerResult", + contains="DBIResult", + slots = list(ptr = "externalptr") + ) + +#' Send a query to AzureDataExplorer. +#' +#' @export +#' @examples +#' +setMethod("dbSendQuery", "AzureDataExplorerConnection", function(conn, statement, ...) +{ + # TODO + new("AzureDataExplorerResult", ...) +}) + +#' @export +setMethod("dbClearResult", "AzureDataExplorerResult", function(res, ...) +{ + # TODO: free resources + TRUE +}) + +#' Retrieve records from query +#' @export +setMethod("dbFetch", "AzureDataExplorerResult", function(res, n = -1, ...) +{ + #TODO +}) + +#' @export +setMethod("dbHasCompleted", "AzureDataExplorerResult", function(res, ...) +{ + #TODO +}) diff --git a/R/ops.R b/R/ops.R new file mode 100644 index 0000000..e69de29 diff --git a/R/tbl.R b/R/tbl.R index 5acc0c2..577f92b 100644 --- a/R/tbl.R +++ b/R/tbl.R @@ -4,90 +4,32 @@ tbl <- function(object, ...) UseMethod("tbl") } -new_tbl <- function(data) { - structure(data, class = "tbl") -} - - -#' @export -tbl.ade_database <- function(object, table, ...) +tbl_ade <- function(object, table, ...) { - out <- list(tbl=table, db=object) - class(out) <- "tbl" - out + ops <- list(x = table, vars = names(table)) + dplyr::make_tbl("ade", db = object, ops = ops) } - - -#' @export -select.tbl <- function(.data, ...) +#' Create a dummy tbl from a data frame. +#' Useful for testing KQL generation without a remote connection. +tbl.tbl_df <- function(table, object=simulate_ade()) { - dots <- quos(...) - add_op_single("select", .data, dots = dots) - ## grps <- group_vars(.data) - ## vars <- unique(c(grps, select_vars(names(.data), ...))) - ## if(length(vars) == 0) - ## stop("No variables selected", call.=FALSE) - - ## arglst <- list(.data, varsToKeep=vars) - ## arglst <- doExtraArgs(arglst, .data, enexpr(.rxArgs), .outFile) - - ## on.exit(deleteIfTbl(.data)) - ## # need to use rxImport on non-Xdf data sources because of bugs in rxDataStep (?) - ## output <- callRx("rxDataStep", arglst) - ## simpleRegroup(output, grps) -} - - -#' @export -add_op_single <- function(name, .data, dots = list(), args = list()) { - .data$ops <- op_single(name, x = .data$ops, dots = dots, args = args) - .data + tbl_ade(object, table) } #' @export -op_single <- function(name, x, dots = list(), args = list()) { +tbl.ade_database_endpoint <- function(object, table, ...) +{ + tbl_ade(object, table) +} + +simulate_ade <- function() +{ structure( - list( - name = name, - x = x, - dots = dots, - args = args - ), - class = c(paste0("op_", name), "op_single", "op") + list( + db = "local_df", + cluster = "local_df" + ), + class = "ade_database_endpoint" ) } - -#' @export -show_query.tbl <- function(x, ...){ - qry <- kql_build(x, con=x$src, ...) - kql_render(qry, con = x$src, ...) -} - -#' @export -kql_render <- function(query, con = NULL, ...) -{ - UseMethod("kql_render") -} - -#' @export -kql_render.tbl <- function(query, con = query$con, ...) -{ - q <- kql_build(query$ops, con = con, ...) -} - -#' @export -kql_build <- function(op, con = NULL, ...) { - UseMethod("kql_build") -} - -#' @export -kql_build.tbl <- function(op, con = NULL, ...){ - q <- kql_build(op$ops, con = con, ...) -} - -#' @export -sql_build.op_select <- function(op, con, ...) { - vars <- tidyselect::vars_select(op_vars(op$x), !!! op$dots, .include = op_grps(op$x)) - select_query(sql_build(op$x, con), ident(vars)) -}