[R-sig-DB] Add a "dbSendUpdate" function to DBI?

Paul Gilbert pg||bert902 @end|ng |rom gm@||@com
Thu Sep 4 23:22:10 CEST 2014



On 09/04/2014 03:15 PM, Hadley Wickham wrote:
>> It is the "If the API" part that I worry about. For example
>>
>>> success(warning("warn"))
>> Warning message:
>> In doTryCatch(return(expr), name, parentenv, handler) : warn
>>> is.logical(success(warning("warn")))
>> [1] FALSE
>> Warning message:
>> In doTryCatch(return(expr), name, parentenv, handler) : warn
>>>
>>
>> So then every package writer trying to build on DBI has to write a wrapper
>> that anticipates the exceptions that may be thrown. This becomes even more
>> difficult when different db drivers, different OSes, and different servers
>> are involved.
>
> I'm not sure I follow, because we hadn't talked about warnings. I
> would not expect that DBI backends to through warnings instead of
> errors.

Well, in my experience my programs usually fail for the reasons I don't 
expect rather than the ones I do expect. I guess that is mainly why I 
like a function that returns a logical, I know what to expect.

>
>> Given the philosophical constraint I think I would generally prefer the
>> function that is guaranteed to return a logical. The other wrapper is easy
>> to write too.
>
> But it's fundamentally more dangerous. If all modification functions
> return TRUE or FALSE and you don't explicit check the return value, it
> is extremely easy to create invalid code. The same is not true for
> errors.

If I understand your logic correctly, you would recommend using 
library() rather than require() when one of them is necessary in a 
function? Or rather, you would not provide require(), only library()? (I 
always use require(), and check the return value.) It is, of course, 
always an interesting question whether to provide tools to protect in 
the case of badly written packages, or to provide tools to simplify 
writing good packages. (Personally, I avoid the choice by not having a 
strong commitment to the philosophical constraint.)

But I think maybe an important point is that a function that returns a 
logical does not necessarily prevent errors from  being thrown. It just 
distinguishes TRUE/FALSE errors, that a package using DBI should try to 
deal with and handle gracefully, from exceptions that the programmer 
might ignore and simply allow to be thrown back to the user. A simple 
wrapper like your success() above cannot easily make that distinction. 
Perhaps this is really not very different from the way you are thinking 
about it, except that I would allow for a FALSE value that the 
programmer might be expected to deal with.

To make this more explicit and constructive, I would probably consider:

    - a SQL error message should return a FALSE with the message as
      an error attribute.

    - a database access error message should return a FALSE with the
      message as an error attribute.

    - a faulty driver, non-working network, or expired con,  should
      throw an exception (other than the case of the function to
      check if a con is good, which should return TRUE/FALSE in
      the last case.)


In any case, I can work with it either way.

Paul

>
> Hadley
>
>




More information about the R-sig-DB mailing list