[R-sig-DB] dbWriteTable and dbReadTable generics

Hadley Wickham h@w|ckh@m @end|ng |rom gm@||@com
Tue Oct 22 03:00:58 CEST 2013


> I do agree that having row.names=, append=, and overwrite= makes sense,
> because these arguments are common and quite natural to most current DBI
> method implementations of these generic functions.  However, adding them
> explicitly to the generic definition implies that methods can be dispatched
> on the *class* of those same arguments, which I'm not clear whether it's
> helpful.

Not necessarily - you can use the signature argument to setGeneric to
say which arguments can be part of the method signature. Simple
example below:

setGeneric("f", function(x, y, z) standardGeneric("f"))
setMethod("f", signature(z = "numeric"), function(x, y, z) z * 2)

f(,, 2)

setGeneric("g", function(x, y, z) standardGeneric("g"),
  signature = "x")
setMethod("g", signature(z = "numeric"), function(x, y, z) z * 2)


> Here, I seem to see two similar but not-quite equal objectives:
>
> (1) defining an interface more strictly (i.e., the DBI dictates that
> dbWriteTables, etc., must have a more complete signature including
> row.names=, etc.). Perfectly reasonable, yet setMethod for the various
> implementations may (?) need to be revised (if so, not a big a deal).
>
> (2) defining the signature on which methods are be dispatched.
>
> I don't think that (1) is wrong (after all, the current use of name= is
> precisely this case) or that (1) and (2) are mutually exclusive. However,
> the original intention was clearly (2): methods are to be dispatched only on
> the conn= and name= arguments, other arguments (...) may be passed from the
> generic to the method(s), but not used for dispatching.  I still feel that
> the current definition expresses this intention most clearly and
> unambigiously.  Adding row.names=, etc., for the sake of a more complete
> interface may imply behavior we (I)  haven't anticipated, e.g., what error
> do users get when they incorrectly supply "row.names = t" (t as the
> transpose as opposed to T for TRUE)?  Overall, not a particular big issue.

So what do you think of the following? I think it does a better job of
meeting those goals than the current code.

setGeneric("dbWriteTable",
  def = function(conn, name, value, row.names = FALSE,
                       overwrite = FALSE, append = FALSE, ...) {
     standardGeneric("dbWriteTable")
  }, valueClass = "logical", signature = "conn"
)

setGeneric("dbReadTable",
  def = function(conn, name, row.names = FALSE, ...) {
    standardGeneric("dbReadTable")
  },
  valueClass = "data.frame", signature = "conn"
)

Hadley

-- 
Chief Scientist, RStudio
http://had.co.nz/




More information about the R-sig-DB mailing list