Changeset: f29f04694445 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f29f04694445 Added Files: clients/R/MonetDB.R/R/dbi.R clients/R/MonetDB.R/R/dplyr.R clients/R/MonetDB.R/R/mapi.R Removed Files: clients/R/MonetDB.R/R/monetdb.R Modified Files: clients/R/MonetDB.R/DESCRIPTION clients/R/MonetDB.R/NAMESPACE clients/R/MonetDB.R/NEWS clients/R/Tests/dplyr.R Branch: Oct2014 Log Message:
R Connector: dplyr II part I Unterschiede (gekürzt von 2297 auf 300 Zeilen): diff --git a/clients/R/MonetDB.R/DESCRIPTION b/clients/R/MonetDB.R/DESCRIPTION --- a/clients/R/MonetDB.R/DESCRIPTION +++ b/clients/R/MonetDB.R/DESCRIPTION @@ -5,6 +5,7 @@ Authors@R: c(person("Hannes Muehleisen", person("Thomas Lumley", role = "ctb"), person("Anthony Damico", role = "ctb")) Depends: DBI (>= 0.3), digest (>= 0.6.4), bitops (>= 1.0), methods +Suggests: dplyr(>= 0.2.0.9000) Description: Allows to pull data from MonetDB into R License: MPL (== 1.1) URL: http://monetr.r-forge.r-project.org diff --git a/clients/R/MonetDB.R/NAMESPACE b/clients/R/MonetDB.R/NAMESPACE --- a/clients/R/MonetDB.R/NAMESPACE +++ b/clients/R/MonetDB.R/NAMESPACE @@ -5,15 +5,8 @@ export(MonetDB,MonetR,MonetDBR,MonetDB.R export(monet.read.csv,monetdb.read.csv) # this one is not in the DBI exportMethods(dbSendUpdate,dbSendUpdateAsync,dbTransaction,dbIsValid) -export(monetdbGetTransferredBytes) -export(monetdbRtype) -export(monetdb_queryinfo) - -# shorthand for db connections -export(mc) - -# shorthand for db queries -export(mq) +# shorthands +export(mc,mq) # control.R export(monetdb.server.setup) @@ -22,3 +15,17 @@ export(monetdb.server.stop) export(monetdbd.liststatus) export(monetdb.liststatus) useDynLib(MonetDB.R) + +# dplyr.R +export(src_monetdb) +export(translate_env.src_monetdb) +export(brief_desc.src_monetdb) +export(tbl.src_monetdb) +export(db_query_fields.MonetDBConnection) +export(db_query_rows.MonetDBConnection) +export(db_save_query.MonetDBConnection) +export(db_insert_into.MonetDBConnection) +export(db_create_index.MonetDBConnection) +export(db_analyze.MonetDBConnection) +export(db_begin.MonetDBConnection) +export(sql_subquery.MonetDBConnection) diff --git a/clients/R/MonetDB.R/NEWS b/clients/R/MonetDB.R/NEWS --- a/clients/R/MonetDB.R/NEWS +++ b/clients/R/MonetDB.R/NEWS @@ -5,6 +5,8 @@ 0.9.5 - DBI 0.3 compatibility (isValid etc.) - deprecated dbTransaction() (DBI has standardized dbBegin()) - Back to R socket code for peace of mind +- Code cleanup +- dplyr integration moved to MonetDB.R 0.9.4 - dbWriteTable overhaul (thanks, Anthony) diff --git a/clients/R/MonetDB.R/R/dbi.R b/clients/R/MonetDB.R/R/dbi.R new file mode 100644 --- /dev/null +++ b/clients/R/MonetDB.R/R/dbi.R @@ -0,0 +1,657 @@ +C_LIBRARY <- "MonetDB.R" + +.onLoad <- function(lib, pkg) { + if (getOption("monetdb.clib", FALSE)) { + library.dynam( C_LIBRARY, pkg, lib ) + .Call("mapiInit", PACKAGE=C_LIBRARY) + } +} + +# Make S4 aware of S3 classes +setOldClass(c("sockconn", "connection", "monetdb_mapi_conn")) + +### MonetDBDriver +setClass("MonetDBDriver", representation("DBIDriver")) + +# allow instantiation of this driver with MonetDB to allow existing programs to work +MonetR <- MonetDB <- MonetDBR <- MonetDB.R <- function() { + new("MonetDBDriver") +} + +# dbIsValid is missing from the DBI 0.3, so redefine +setGeneric("dbIsValid", + def = function(dbObj, ...) standardGeneric("dbIsValid"), + valueClass = "logical") + +setMethod("dbIsValid", "MonetDBDriver", def=function(dbObj, ...) { + return(TRUE) # driver object cannot be invalid +}) + +setMethod("dbUnloadDriver", "MonetDBDriver", def=function(drv, ...) { + return(TRUE) # there is nothing to really unload here... +}) + +setMethod("dbGetInfo", "MonetDBDriver", def=function(dbObj, ...) + list(name="MonetDBDriver", + driver.version=packageVersion("MonetDB.R"), + DBI.version=packageVersion("DBI"), + client.version="NA", + max.connections=125) # R can only handle 128 connections, three of which are pre-allocated +) + +# shorthand for connecting to the DB, very handy, e.g. dbListTables(mc("acs")) +mc <- function(dbname="demo", user="monetdb", password="monetdb", host="localhost", port=50000L, + timeout=86400L, wait=FALSE, language="sql", ...) { + + dbConnect(MonetDB.R(), dbname, user, password, host, port, timeout, wait, language, ...) +} + +mq <- function(dbname, query, ...) { + conn <- mc(dbname, ...) + res <- dbGetQuery(conn, query) + dbDisconnect(conn) + return(res) +} + +setMethod("dbConnect", "MonetDBDriver", def=function(drv, dbname="demo", user="monetdb", + password="monetdb", host="localhost", port=50000L, timeout=86400L, wait=FALSE, language="sql", + ..., url="") { + + if (substring(url, 1, 10) == "monetdb://") { + dbname <- url + } + timeout <- as.integer(timeout) + + if (substring(dbname, 1, 10) == "monetdb://") { + rest <- substring(dbname, 11, nchar(dbname)) + # split at /, so we get the dbname + slashsplit <- strsplit(rest, "/", fixed=TRUE) + hostport <- slashsplit[[1]][1] + dbname <- slashsplit[[1]][2] + + # count the number of : in the string + ndc <- nchar(hostport) - nchar(gsub(":","",hostport,fixed=T)) + if (ndc == 0) { + host <- hostport + } + if (ndc == 1) { # ipv4 case, any ipv6 address has more than one : + hostportsplit <- strsplit(hostport, ":", fixed=TRUE) + host <- hostportsplit[[1]][1] + port <- hostportsplit[[1]][2] + } + if (ndc > 1) { # ipv6 case, now we only need to check for ]: + if (length(grep("]:", hostport, fixed=TRUE)) == 1) { # ipv6 with port number + hostportsplit <- strsplit(hostport, "]:", fixed=TRUE) + host <- substring(hostportsplit[[1]][1],2) + port <- hostportsplit[[1]][2] + } + else { + host <- hostport + } + } + } + # this is important, otherwise we'll trip an assertion + port <- as.integer(port) + + # validate port number + if (length(port) != 1 || port < 1 || port > 65535) { + stop("Illegal port number ",port) + } + + if (getOption("monetdb.debug.mapi", F)) message("II: Connecting to MonetDB on host ", host, " at " + ,"port ", port, " to DB ", dbname, " with user ", user, " and a non-printed password, timeout is " + , timeout, " seconds.") + socket <- FALSE + if (wait) { + repeat { + continue <- FALSE + tryCatch ({ + # open socket with 5-sec timeout so we can check whether everything works + socket <- socket <<- .mapiConnect(host, port, 5) + # authenticate + .mapiAuthenticate(socket, dbname, user, password, language=language) + .mapiDisconnect(socket) + break + }, error = function(e) { + if ("connection" %in% class(socket)) { + close(socket) + } + message("Server not ready(", e$message, "), retrying (ESC or CTRL+C to abort)") + Sys.sleep(1) + continue <<- TRUE + }) + } + } + + # make new socket with user-specified timeout + socket <- .mapiConnect(host, port, 5) + .mapiAuthenticate(socket, dbname, user, password, language=language) + connenv <- new.env(parent=emptyenv()) + connenv$lock <- 0 + connenv$deferred <- list() + connenv$exception <- list() + + conn <- new("MonetDBConnection", socket=socket, connenv=connenv, Id=-1L) + if (getOption("monetdb.sequential", F)) { + message("MonetDB: Switching to single-threaded query execution.") + dbSendQuery(conn, "set optimizer='sequential_pipe'") + } + + return(conn) + +}, +valueClass="MonetDBConnection") + + +### MonetDBConnection +setClass("MonetDBConnection", representation("DBIConnection", socket="ANY", + connenv="environment", fetchSize="integer", Id="integer")) + +setMethod("dbGetInfo", "MonetDBConnection", def=function(dbObj, ...) { + envdata <- dbGetQuery(dbObj, "SELECT name, value from sys.env()") + ll <- as.list(envdata$value) + names(ll) <- envdata$name + ll$name <- "MonetDBConnection" + return(ll) +}) + +setMethod("dbIsValid", "MonetDBConnection", def=function(dbObj, ...) { + return(!is.na(tryCatch(dbGetInfo(dbObj), error=function(e){NA}))) +}) + +setMethod("dbDisconnect", "MonetDBConnection", def=function(conn, ...) { + .mapiDisconnect(conn@socket) + return(invisible(TRUE)) +}) + +setMethod("dbListTables", "MonetDBConnection", def=function(conn, ..., sys_tables=F, schema_names=F, quote=F) { + q <- "select schemas.name as sn, tables.name as tn from sys.tables join sys.schemas on tables.schema_id=schemas.id" + if (!sys_tables) q <- paste0(q, " where tables.system=false") + df <- dbGetQuery(conn, q) + if (quote) { + df$tn <- paste0("\"", df$tn, "\"") + } + res <- df$tn + if (schema_names) { + if (quote) { + df$sn <- paste0("\"", df$sn, "\"") + } + res <- paste0(df$sn, ".", df$tn) + } + return(as.character(res)) +}) + +if (is.null(getGeneric("dbTransaction"))) setGeneric("dbTransaction", function(conn, ...) + standardGeneric("dbTransaction")) + +setMethod("dbTransaction", signature(conn="MonetDBConnection"), def=function(conn, ...) { + dbBegin(conn) + warning("dbTransaction() is deprecated, use dbBegin() from now.") + invisible(TRUE) +}) + +setMethod("dbBegin", "MonetDBConnection", def=function(conn, ...) { + dbSendQuery(conn, "START TRANSACTION") + invisible(TRUE) +}) + +setMethod("dbCommit", "MonetDBConnection", def=function(conn, ...) { + dbSendQuery(conn, "COMMIT") + invisible(TRUE) +}) + +setMethod("dbRollback", "MonetDBConnection", def=function(conn, ...) { + dbSendQuery(conn, "ROLLBACK") + invisible(TRUE) +}) + +setMethod("dbListFields", "MonetDBConnection", def=function(conn, name, ...) { + if (!dbExistsTable(conn, name)) + stop(paste0("Unknown table: ", name)); + df <- dbGetQuery(conn, paste0("select columns.name as name from sys.columns join sys.tables on \ + columns.table_id=tables.id where tables.name='", name, "';")) + df$name +}) + +setMethod("dbExistsTable", "MonetDBConnection", def=function(conn, name, ...) { + #TODO: make this work with more cases + tolower(name) %in% tolower(dbListTables(conn,sys_tables=T)) +}) + +setMethod("dbGetException", "MonetDBConnection", def=function(conn, ...) { + conn@connenv$exception +}) + +setMethod("dbReadTable", "MonetDBConnection", def=function(conn, name, ...) { + if (!dbExistsTable(conn, name)) + stop(paste0("Unknown table: ", name)); + dbGetQuery(conn, paste0("SELECT * FROM ", name)) +}) + +# This one does all the work in this class +setMethod("dbSendQuery", signature(conn="MonetDBConnection", statement="character"), + def=function(conn, statement, ..., list=NULL, async=FALSE) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list