Changeset: 21143fb53227 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=21143fb53227
Modified Files:
        clients/R/MonetDB.R/DESCRIPTION
        clients/R/MonetDB.R/NEWS
        clients/R/MonetDB.R/R/dbi.R
        clients/R/MonetDB.R/R/mapi.R
        clients/R/MonetDB.R/src/mapisplit.c
        clients/R/Tests/dbi.R
Branch: default
Log Message:

R Connector: Progress bar, MAPI parser overhaul


diffs (truncated from 487 to 300 lines):

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
@@ -1,5 +1,5 @@
 Package: MonetDB.R
-Version: 0.9.6
+Version: 0.9.7
 Title: Connect MonetDB to R
 Authors@R: c(person("Hannes Muehleisen", role = c("aut", "cre"),email = 
"han...@cwi.nl"),
        person("Thomas Lumley", role = "ctb"),
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
@@ -1,3 +1,9 @@
+0.9.7
+- monetdb.read.csv TODO (thanks, Duncan)
+- dbWriteTable encoding checks  TODO (thanks, Anthony)
+- deprecated nrows parameter to monetdb.read.csv, not neccessary any more 
because of upgrades to MonetDB
+- added query progress bar (counting MAL statements) for MonetDB releases 
following Oct2014, enable with options(monetdb.profile=T)
+
 0.9.6
 - Fixed non-ASCII character handling (thanks, Roman!)
 - Fully removed C-based socket code
diff --git a/clients/R/MonetDB.R/R/dbi.R b/clients/R/MonetDB.R/R/dbi.R
--- a/clients/R/MonetDB.R/R/dbi.R
+++ b/clients/R/MonetDB.R/R/dbi.R
@@ -125,6 +125,15 @@ setMethod("dbConnect", "MonetDBDriver", 
     message("MonetDB: Switching to single-threaded query execution.")
     dbSendQuery(conn, "set optimizer='sequential_pipe'")
   }
+
+  # enable profiler, we use a MAL connection for this
+  if (getOption("monetdb.profile", F)) {
+    msocket <- .mapiConnect(host, port, timeout) 
+    .mapiAuthenticate(msocket, dbname, user, password, language="mal")
+    .profiler_enable(msocket)
+    .mapiDisconnect(msocket);
+    message("Enabled profiler")
+  }
   
   return(conn)
 
@@ -222,64 +231,64 @@ setMethod("dbReadTable", "MonetDBConnect
 setMethod("dbSendQuery", signature(conn="MonetDBConnection", 
statement="character"),  
           def=function(conn, statement, ..., list=NULL, async=FALSE) {
             
-            if(!is.null(list) || length(list(...))){
-              if (length(list(...))) statement <- .bindParameters(statement, 
list(...))
-              if (!is.null(list)) statement <- .bindParameters(statement, list)
-            }  
-            conn@connenv$exception <- list()
-            env <- NULL
-            # Auto-convert? 
-            # statement <- enc2utf8(statement)
-            if (getOption("monetdb.debug.query", F))  message("QQ: '", 
statement, "'")
-            resp <- .mapiParseResponse(.mapiRequest(conn, paste0("s", 
statement, "\n;"), async=async))
-            
-            env <- new.env(parent=emptyenv())
-            
-            if (resp$type == Q_TABLE) {
-              # we have to pass this as an environment to make conn object 
available to result for fetching
-              env$success = TRUE
-              env$conn <- conn
-              env$data <- resp$tuples
-              resp$tuples <- NULL # clean up
-              env$info <- resp
-              env$delivered <- 0
-              env$query <- statement
-              env$open <- TRUE
-            }
-            if (resp$type == Q_UPDATE || resp$type == Q_CREATE || resp$type == 
MSG_ASYNC_REPLY) {
-              env$success = TRUE
-              env$conn <- conn
-              env$query <- statement
-              env$info <- resp
+  if(!is.null(list) || length(list(...))){
+    if (length(list(...))) statement <- .bindParameters(statement, list(...))
+    if (!is.null(list)) statement <- .bindParameters(statement, list)
+  }    
+  conn@connenv$exception <- list()
+  env <- NULL
+  if (getOption("monetdb.debug.query", F))  message("QQ: '", statement, "'")
+  # the actual request
+  mresp <- .mapiRequest(conn, paste0("s", statement, "\n;"), async=async)
+  resp <- .mapiParseResponse(mresp)
 
-            }
-            if (resp$type == MSG_MESSAGE) {
-              env$success = FALSE
-              env$conn <- conn
-              env$query <- statement
-              env$info <- resp
-              env$message <- resp$message
-            }
-            
-            if (!env$success) {
-              sp <- strsplit(env$message, "!", fixed=T)[[1]]
-              # truncate statement to not hide actual error message
-              if (nchar(statement) > 100) { statement <- 
paste0(substring(statement, 1, 100), "...") }
-              if (length(sp) == 3) {
-                errno <- sp[[2]]
-                errmsg <- sp[[3]]
-                conn@connenv$exception <- list(errNum=errno, errMsg=errmsg)
-                stop("Unable to execute statement '", statement, "'.\nServer 
says '", errmsg, "' [#", 
-                     errno, "].")
-              }
-              else {
-                conn@connenv$exception <- list(errNum=NA, errMsg=env$message)
-                stop("Unable to execute statement '", statement, "'.\nServer 
says '", env$message, "'.")
-              }
-            }
-            
-            return(new("MonetDBResult", env=env))
-          })
+  env <- new.env(parent=emptyenv())
+
+  if (resp$type == Q_TABLE) {
+    # we have to pass this as an environment to make conn object available to 
result for fetching
+    env$success = TRUE
+    env$conn <- conn
+    env$data <- resp$tuples
+    resp$tuples <- NULL # clean up
+    env$info <- resp
+    env$delivered <- 0
+    env$query <- statement
+    env$open <- TRUE
+  }
+  if (resp$type == Q_UPDATE || resp$type == Q_CREATE || resp$type == 
MSG_ASYNC_REPLY) {
+    env$success = TRUE
+    env$conn <- conn
+    env$query <- statement
+    env$info <- resp
+
+  }
+  if (resp$type == MSG_MESSAGE) {
+    env$success = FALSE
+    env$conn <- conn
+    env$query <- statement
+    env$info <- resp
+    env$message <- resp$message
+  }
+
+  if (!env$success) {
+    sp <- strsplit(env$message, "!", fixed=T)[[1]]
+    # truncate statement to not hide actual error message
+    if (nchar(statement) > 100) { statement <- paste0(substring(statement, 1, 
100), "...") }
+    if (length(sp) == 3) {
+      errno <- sp[[2]]
+      errmsg <- sp[[3]]
+      conn@connenv$exception <- list(errNum=errno, errMsg=errmsg)
+      stop("Unable to execute statement '", statement, "'.\nServer says '", 
errmsg, "' [#", 
+           errno, "].")
+    }
+    else {
+      conn@connenv$exception <- list(errNum=NA, errMsg=env$message)
+      stop("Unable to execute statement '", statement, "'.\nServer says '", 
env$message, "'.")
+    }
+  }
+
+  return(new("MonetDBResult", env=env))
+  })
 
 
 
@@ -323,7 +332,7 @@ setMethod("dbWriteTable", "MonetDBConnec
   if (length(value[[1]])) {
     if (csvdump) {
       tmp <- tempfile(fileext = ".csv")
-      write.table(value, tmp, sep = ",", quote = TRUE,row.names = FALSE, 
col.names = FALSE,na="")
+      write.table(value, tmp, sep = ",", quote = TRUE, row.names = FALSE, 
col.names = FALSE,na="")
       dbSendQuery(conn, paste0("COPY ",format(nrow(value), scientific=FALSE)," 
RECORDS INTO ", qname,
       " FROM '", tmp, "' USING DELIMITERS ',','\\n','\"' NULL AS ''"))
       file.remove(tmp) 
@@ -528,7 +537,7 @@ setMethod("dbFetch", signature(res="Mone
   
   # convert tuple string vector into matrix so we can access a single column 
efficiently
   # call to a faster C implementation for the annoying task of splitting 
everyting into fields
-  parts <- .Call("mapiSplit", res@env$data[1:n], as.integer(info$cols), 
PACKAGE=C_LIBRARY)
+  parts <- .Call("mapi_split", res@env$data[1:n], as.integer(info$cols), 
PACKAGE=C_LIBRARY)
   
   # convert values column by column
   for (j in seq.int(info$cols)) {      
@@ -610,13 +619,17 @@ setMethod("dbGetInfo", "MonetDBResult", 
               has.completed=dbHasCompleted(dbObj), is.select=TRUE))    
 }, valueClass="list")
 
-# copied from RMonetDB, no java-specific things in here...
-monet.read.csv <- monetdb.read.csv <- function(conn, files, tablename, nrows, 
header=TRUE, 
+# adapted from RMonetDB, no java-specific things in here...
+monet.read.csv <- monetdb.read.csv <- function(conn, files, tablename, 
nrows=NA, header=TRUE, 
                                                locked=FALSE, na.strings="", 
nrow.check=500, delim=",", newline="\\n", quote="\"", ...){
   
   if (length(na.strings)>1) stop("na.strings must be of length 1")
   headers <- lapply(files, read.csv, sep=delim, na.strings=na.strings, 
quote=quote, nrows=nrow.check, 
                     ...)
+
+  if (!missing(nrows)) {
+    warning("monetdb.read.csv(): nrows parameter is not neccessary any more 
and deprecated.")
+  }
   
   if (length(files)>1){
     nn <- sapply(headers, ncol)
@@ -631,19 +644,18 @@ monet.read.csv <- monetdb.read.csv <- fu
   
   delimspec <- paste0("USING DELIMITERS '", delim, "','", newline, "','", 
quote, "'")
   
-  if(header || !missing(nrows)){
-    if (length(nrows)==1) nrows <- rep(nrows, length(files))
+  if(header){
     for(i in seq_along(files)) {
       thefile <- normalizePath(files[i])
-      dbSendUpdate(conn, paste("COPY", format(nrows[i], scientific=FALSE), 
"OFFSET 2 RECORDS INTO", 
-                               tablename, "FROM", paste("'", thefile, "'", 
sep=""), delimspec, "NULL as", paste("'", 
-                                                                               
                                 na.strings[1], "'", sep=""), if(locked) 
"LOCKED"))
+      dbSendUpdate(conn, paste("COPY OFFSET 2 INTO", 
+        tablename, "FROM", paste("'", thefile, "'", sep=""), delimspec, "NULL 
as", paste("'", 
+        na.strings[1], "'", sep=""), if(locked) "LOCKED"))
     }
   } else {
     for(i in seq_along(files)) {
       thefile <- normalizePath(files[i])
       dbSendUpdate(conn, paste0("COPY INTO ", tablename, " FROM ", paste("'", 
thefile, "'", sep=""), 
-                                delimspec, "NULL as ", paste("'", 
na.strings[1], "'", sep=""), if(locked) " LOCKED "))
+        delimspec, "NULL as ", paste("'", na.strings[1], "'", sep=""), 
if(locked) " LOCKED "))
     }
   }
   dbGetQuery(conn, paste("select count(*) from", tablename))
diff --git a/clients/R/MonetDB.R/R/mapi.R b/clients/R/MonetDB.R/R/mapi.R
--- a/clients/R/MonetDB.R/R/mapi.R
+++ b/clients/R/MonetDB.R/R/mapi.R
@@ -315,7 +315,7 @@ REPLY_SIZE    <- 100 # Apparently, -1 me
       protocol <- redirect[[1]][1]
       if (protocol == "merovingian") {
         # retry auth on same connection, we will get a new challenge
-        .mapiAuthenticate(con, dbname, user, password, endhashfunc)
+        .mapiAuthenticate(con, dbname, user, password, endhashfunc, language)
       }
       if (protocol == "monetdb") {
         stop("Forwarding to another server (", link, ") not supported.")
@@ -327,8 +327,10 @@ REPLY_SIZE    <- 100 # Apparently, -1 me
   } else {
     if (getOption("monetdb.debug.mapi", F)) message("II: Authentication 
successful.")
     # setting some server parameters...not sure if this should happen here
-    .mapiWrite(con, paste0("Xreply_size ", REPLY_SIZE)); .mapiRead(con)
-    .mapiWrite(con, "Xauto_commit 1"); .mapiRead(con)
+    if (language == "sql") {
+      .mapiWrite(con, paste0("Xreply_size ", REPLY_SIZE)); .mapiRead(con)
+      .mapiWrite(con, "Xauto_commit 1"); .mapiRead(con)
+    }
   }
 }
 
diff --git a/clients/R/MonetDB.R/src/mapisplit.c 
b/clients/R/MonetDB.R/src/mapisplit.c
--- a/clients/R/MonetDB.R/src/mapisplit.c
+++ b/clients/R/MonetDB.R/src/mapisplit.c
@@ -1,36 +1,74 @@
-/*
- * The contents of this file are subject to the MonetDB Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.monetdb.org/Legal/MonetDBLicense
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is the MonetDB Database System.
- *
- * The Initial Developer of the Original Code is CWI.
- * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
- * Copyright August 2008-2015 MonetDB B.V.
- * All Rights Reserved.
- */
-
-#include <R.h>
-#include <Rdefines.h>
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
 
+#include <R.h>
+#include <Rdefines.h>
+
 typedef enum {
        INQUOTES, ESCAPED, INTOKEN, INCRAP
-} chrstate;
+} mapi_line_chrstate;
+
+void mapi_line_split(char* line, char** out, size_t ncols) {
+       int cCol = 0;
+       int tokenStart = 2;
+       int endQuote = 0;
+       int curPos;
+
+       int linelen = strlen(line);
+       mapi_line_chrstate state = INCRAP;
+
+       for (curPos = 2; curPos < linelen - 1; curPos++) {
+               char chr = line[curPos];
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to