Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New odbc method for sql.reader #145

Closed
wants to merge 30 commits into from

Conversation

tomschloss
Copy link

Relates to Issue #144

Pulls through the default options for RODBC::odbcDriverConnect using formals. Args specified in the .sql doc (with type: odbc) are compared to the formals list. Those that are RODBC::odbcDriverConnect args replace the defaults (with check.else.default), while those that aren't (excluding type and query) are assumed to be values in the connection string. These remaining args are concatenated to form the connection string with separated.list.

I've had to specify defaults for colQuote and tabQuote. They were set to double quotes as suggested in the RODBC documentation, although this can be changed in the .sql file with colQuote: and tabQuote: if required.

There is probably a more elegant way to do this, but this should be compatible with .sql files made in the old world (although this hasn't been tested).

RStudio and roxygen2 went a bit gangbusters with documentation updates. Let me know if that is an issue...

Main changes:
sql.reader

    # list of rodbc options to ignore
    odbcDC_default_args <-
      as.list(formals(RODBC::odbcDriverConnect))
    arg_names <- formalArgs(RODBC::odbcDriverConnect)

    # colQuote default
    odbcDC_default_args[['colQuote']] <- '\"'
    odbcDC_default_args[['tabQuote']] <- odbcDC_default_args[['colQuote']]

    # define args: each element is an arg from odbcDriverConnect, and takes the
    # value of the default, unless specified in database.info
    odbcDC_args <-
      lapply(
        names(odbcDC_default_args),
        check.else.default,
        default = odbcDC_default_args,
        options = database.info
      )
    names(odbcDC_args) <- names(odbcDC_default_args)

    # create connection.string from args that are not odbcDriverConnect
    # or query args
    connection.string <-
      separated.list(
        target.list = database.info,
        ignore = c(arg_names, 'type', 'query'),
        sepchar = ';',
        colchar = '='
      )
    odbcDC_args[['connection']] <- connection.string

    # open the connection
    connection <- do.call(RODBC::odbcDriverConnect, odbcDC_args)
    results <- RODBC::sqlQuery(connection, database.info[['query']])
    RODBC::odbcClose(connection)

tomschloss and others added 30 commits February 26, 2016 13:21
* As factors to false, to prevent loads of factors
* Add tidyr to list of default packages
Added possible fields to the RODBC script. Script now looks through
fields and includes in the odbcDriverConnect function if not blank.
A more flexible odbc connection, allowing for variables to be left out
of the .sql file.

This could be further extended to run solely off the fields in the .sql
file.
Documentation updated for separated.list
* Travis didn't like the period in the DESCRIPTION title
* separated.list didn't have the correct link for odbcDriverConnect
…l` files. Arguments that are not specified take the default values from `RODBC::odbcDriverConnect`.
Set defaults for colQuote and tabQuote to `RODBC::odbcDriverConnect` defaults. These can be set in the .sql file if required.
Fixed small bug - `sepchar` and `colchar` were inverted.
Minor bug preventing `colQuote` and `tabQuote` defaults from being overwritten.
Fixed a bug in the default assignment...
@KentonWhite
Copy link
Owner

Thanks so much for this PR. I'm really looking forward to reviewing it and will clear some time over the net few days!

@@ -61,8 +61,11 @@
#' dsn: sample_dsn
#' user: sample_user
#' password: sample_password
#' dbname: sample_database
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does changing dbname to database break backward compatibility?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think on reflection it does. It will also have an impact on the user, password and dsn fields. I'll fix this.

@KentonWhite
Copy link
Owner

I really like querying the driver for its arguments and defaults. Really we should think about moving all of the connections to this method in the future.

For maintenance, my biggest concern is backward compatibility with the change of dbname to database. While the ODBC driver expects a database argument this might just break some projects. Perhaps adding a method to set database to dbname if dbname is given plus a deprecation warning?

To help our future selves, can you add a test illustrating using the new parameters for ODBC please. While there are existing tests for the ODBC drivers, they only exercise the old parameters and defaults. Adding a new test ensures that future changes to the code or to the ODBC drivers don't break the feature.

Finally, can you squash into a single commit please. I appreciate having the commit history while working on the feature branch is invaluable, once merged into master it can make the master history difficult to read.

Thanks for this PR -- it looks really great!

@tomschloss
Copy link
Author

Thanks for looking over it - much appreciated. I'll have some time later this week incorporate your comments

@KentonWhite
Copy link
Owner

Closing for now since it breaks backward compatibility. Please re-open if the backward compatibility issue is solved or there is a pressing need to break backward compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants