DBI/0000755000176200001440000000000013575400712010654 5ustar liggesusersDBI/NAMESPACE0000644000176200001440000000466513575266110012110 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("[",SQL) S3method("[[",SQL) S3method(toString,Id) export(.SQL92Keywords) export(ANSI) export(Id) export(SQL) export(SQLKeywords) export(dbAppendTable) export(dbBegin) export(dbBind) export(dbBreak) export(dbCallProc) export(dbCanConnect) export(dbClearResult) export(dbColumnInfo) export(dbCommit) export(dbConnect) export(dbCreateTable) export(dbDataType) export(dbDisconnect) export(dbDriver) export(dbExecute) export(dbExistsTable) export(dbFetch) export(dbGetConnectArgs) export(dbGetDBIVersion) export(dbGetException) export(dbGetInfo) export(dbGetQuery) export(dbGetRowCount) export(dbGetRowsAffected) export(dbGetStatement) export(dbHasCompleted) export(dbIsReadOnly) export(dbIsValid) export(dbListConnections) export(dbListFields) export(dbListObjects) export(dbListResults) export(dbListTables) export(dbQuoteIdentifier) export(dbQuoteLiteral) export(dbQuoteString) export(dbReadTable) export(dbRemoveTable) export(dbRollback) export(dbSendQuery) export(dbSendStatement) export(dbSetDataMappings) export(dbUnloadDriver) export(dbUnquoteIdentifier) export(dbWithTransaction) export(dbWriteTable) export(fetch) export(isSQLKeyword) export(isSQLKeyword.default) export(make.db.names) export(make.db.names.default) export(sqlAppendTable) export(sqlAppendTableTemplate) export(sqlColumnToRownames) export(sqlCommentSpec) export(sqlCreateTable) export(sqlData) export(sqlInterpolate) export(sqlParseVariables) export(sqlParseVariablesImpl) export(sqlQuoteSpec) export(sqlRownamesToColumn) exportClasses(DBIConnection) exportClasses(DBIConnector) exportClasses(DBIDriver) exportClasses(DBIObject) exportClasses(DBIResult) exportClasses(SQL) exportMethods(dbAppendTable) exportMethods(dbCanConnect) exportMethods(dbConnect) exportMethods(dbCreateTable) exportMethods(dbDataType) exportMethods(dbExecute) exportMethods(dbExistsTable) exportMethods(dbFetch) exportMethods(dbGetConnectArgs) exportMethods(dbGetQuery) exportMethods(dbListFields) exportMethods(dbListObjects) exportMethods(dbQuoteIdentifier) exportMethods(dbQuoteLiteral) exportMethods(dbQuoteString) exportMethods(dbReadTable) exportMethods(dbRemoveTable) exportMethods(dbSendStatement) exportMethods(dbUnquoteIdentifier) exportMethods(dbWithTransaction) exportMethods(dbWriteTable) exportMethods(show) exportMethods(sqlAppendTable) exportMethods(sqlCreateTable) exportMethods(sqlData) exportMethods(sqlInterpolate) exportMethods(sqlParseVariables) import(methods) DBI/.Rinstignore0000644000176200001440000000002512511422440013144 0ustar liggesusersinst/doc/figure1.pdf DBI/README.md0000644000176200001440000001372613575372402012150 0ustar liggesusers # DBI [![Build Status](https://travis-ci.org/r-dbi/DBI.svg?branch=master)](https://travis-ci.org/r-dbi/DBI) [![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/r-dbi/DBI?branch=master&svg=true)](https://ci.appveyor.com/project/r-dbi/DBI) [![Coverage Status](https://codecov.io/gh/r-dbi/DBI/branch/master/graph/badge.svg)](https://codecov.io/github/r-dbi/DBI?branch=master) [![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/DBI)](https://cran.r-project.org/package=DBI) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1882/badge)](https://bestpractices.coreinfrastructure.org/projects/1882) The DBI package helps connecting R to database management systems (DBMS). DBI separates the connectivity to the DBMS into a “front-end” and a “back-end”. The package defines an interface that is implemented by *DBI backends* such as: - [RPostgres](https://rpostgres.r-dbi.org), - [RMariaDB](https://rmariadb.r-dbi.org), - [RSQLite](https://rsqlite.r-dbi.org), - [odbc](https://github.com/r-dbi/odbc), - [bigrquery](https://github.com/r-dbi/bigrquery), and many more. R scripts and packages use DBI to access various databases through their DBI backends. The interface defines a small set of classes and methods similar in spirit to Perl’s [DBI](http://dbi.perl.org/), Java’s [JDBC](http://www.oracle.com/technetwork/java/javase/jdbc/index.html), Python’s [DB-API](http://www.python.org/dev/peps/pep-0249/), and Microsoft’s [ODBC](http://en.wikipedia.org/wiki/ODBC). It supports the following operations: - connect/disconnect to the DBMS - create and execute statements in the DBMS - extract results/output from statements - error/exception handling - information (meta-data) from database objects - transaction management (optional) ## Installation Most users who want to access a database do not need to install DBI directly. It will be installed automatically when you install one of the database backends: - [RPostgres](https://rpostgres.r-dbi.org) for PostgreSQL, - [RMariaDB](https://rmariadb.r-dbi.org) for MariaDB or MySQL, - [RSQLite](https://rsqlite.r-dbi.org) for SQLite, - [odbc](https://github.com/r-dbi/odbc) for databases that you can access via [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity), - [bigrquery](https://github.com/r-dbi/bigrquery), - … . You can install the released version of DBI from [CRAN](https://CRAN.R-project.org) with: ``` r install.packages("DBI") ``` And the development version from [GitHub](https://github.com/) with: ``` r # install.packages("devtools") devtools::install_github("r-dbi/DBI") ``` ## Example The following example illustrates some of the DBI capabilities: ``` r library(DBI) # Create an ephemeral in-memory RSQLite database con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:") dbListTables(con) #> character(0) dbWriteTable(con, "mtcars", mtcars) dbListTables(con) #> [1] "mtcars" dbListFields(con, "mtcars") #> [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear" #> [11] "carb" dbReadTable(con, "mtcars") #> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 #> 6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 #> 7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 #> 8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 #> 9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 #> [ reached 'max' / getOption("max.print") -- omitted 23 rows ] # You can fetch all results: res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") dbFetch(res) #> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 #> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 #> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 #> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 #> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 #> 7 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 #> 8 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 #> 9 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 #> [ reached 'max' / getOption("max.print") -- omitted 2 rows ] dbClearResult(res) # Or a chunk at a time res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") while(!dbHasCompleted(res)){ chunk <- dbFetch(res, n = 5) print(nrow(chunk)) } #> [1] 5 #> [1] 5 #> [1] 1 dbClearResult(res) dbDisconnect(con) ``` ## Class structure There are four main DBI classes. Three which are each extended by individual database backends: - `DBIObject`: a common base class for all DBI. - `DBIDriver`: a base class representing overall DBMS properties. Typically generator functions instantiate the driver objects like `RSQLite()`, `RPostgreSQL()`, `RMySQL()` etc. - `DBIConnection`: represents a connection to a specific database - `DBIResult`: the result of a DBMS query or statement. All classes are *virtual*: they cannot be instantiated directly and instead must be subclassed. ## Further Reading - [Databases using R](http://db.rstudio.com/) describes the tools and best practices in this ecosystem. - The [DBI project site](https://www.r-dbi.org/) hosts a blog where recent developments are presented. - [A history of DBI](https://r-dbi.github.io/DBI/articles/DBI-history.html) by David James, the driving force behind the development of DBI, and many of the packages that implement it. ----- Please note that the *DBI* project is released with a [Contributor Code of Conduct](https://dbi.r-dbi.org/code_of_conduct). By contributing to this project, you agree to abide by its terms. DBI/man/0000755000176200001440000000000013575266242011437 5ustar liggesusersDBI/man/dbQuoteLiteral.Rd0000644000176200001440000000560613575266047014660 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.R \name{dbQuoteLiteral} \alias{dbQuoteLiteral} \title{Quote literal values} \usage{ dbQuoteLiteral(conn, x, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{x}{A vector to quote as string.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbQuoteLiteral()} returns an object that can be coerced to \link{character}, of the same length as the input. For an empty character vector this function returns a length-0 object. When passing the returned object again to \code{dbQuoteLiteral()} as \code{x} argument, it is returned unchanged. Passing objects of class \link{SQL} should also return them unchanged. (For backends it may be most convenient to return \link{SQL} objects to achieve this behavior, but this is not required.) } \description{ Call these methods to generate a string that is suitable for use in a query as a literal value of the correct type, to make sure that you generate valid SQL and protect against SQL injection attacks. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbQuoteLiteral")} } \section{Specification}{ The returned expression can be used in a \verb{SELECT ...} query, and the value of \code{dbGetQuery(paste0("SELECT ", dbQuoteLiteral(x)))[[1]]} must be equal to \code{x} for any scalar integer, numeric, string, and logical. If \code{x} is \code{NA}, the result must merely satisfy \code{\link[=is.na]{is.na()}}. The literals \code{"NA"} or \code{"NULL"} are not treated specially. \code{NA} should be translated to an unquoted SQL \code{NULL}, so that the query \verb{SELECT * FROM (SELECT 1) a WHERE ... IS NULL} returns one row. Passing a list for the \code{x} argument raises an error. } \examples{ # Quoting ensures that arbitrary input is safe for use in a query name <- "Robert'); DROP TABLE Students;--" dbQuoteLiteral(ANSI(), name) # NAs become NULL dbQuoteLiteral(ANSI(), c(1:3, NA)) # Logicals become integers by default dbQuoteLiteral(ANSI(), c(TRUE, FALSE, NA)) # Raw vectors become hex strings by default dbQuoteLiteral(ANSI(), list(as.raw(1:3), NULL)) # SQL vectors are always passed through as is var_name <- SQL("select") var_name dbQuoteLiteral(ANSI(), var_name) # This mechanism is used to prevent double escaping dbQuoteLiteral(ANSI(), dbQuoteLiteral(ANSI(), name)) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/sqlAppendTable.Rd0000644000176200001440000000432013575266047014627 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/table-insert.R \name{sqlAppendTable} \alias{sqlAppendTable} \alias{sqlAppendTableTemplate} \title{Compose query to insert rows into a table} \usage{ sqlAppendTable(con, table, values, row.names = NA, ...) sqlAppendTableTemplate( con, table, values, row.names = NA, prefix = "?", ..., pattern = "" ) } \arguments{ \item{con}{A database connection.} \item{table}{Name of the table. Escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{values}{A data frame. Factors will be converted to character vectors. Character vectors will be escaped with \code{\link[=dbQuoteString]{dbQuoteString()}}.} \item{row.names}{Either \code{TRUE}, \code{FALSE}, \code{NA} or a string. If \code{TRUE}, always translate row names to a column called "row_names". If \code{FALSE}, never translate row names. If \code{NA}, translate rownames only if they're a character vector. A string is equivalent to \code{TRUE}, but allows you to override the default name. For backward compatibility, \code{NULL} is equivalent to \code{FALSE}.} \item{...}{Other arguments used by individual methods.} \item{prefix}{Parameter prefix to use for placeholders.} \item{pattern}{Parameter pattern to use for placeholders: \itemize{ \item \code{""}: no pattern \item \code{"1"}: position \item anything else: field name }} } \description{ \code{sqlAppendTable()} generates a single SQL string that inserts a data frame into an existing table. \code{sqlAppendTableTemplate()} generates a template suitable for use with \code{\link[=dbBind]{dbBind()}}. The default methods are ANSI SQL 99 compliant. These methods are mostly useful for backend implementers. } \details{ The \code{row.names} argument must be passed explicitly in order to avoid a compatibility warning. The default will be changed in a later release. } \examples{ sqlAppendTable(ANSI(), "iris", head(iris)) sqlAppendTable(ANSI(), "mtcars", head(mtcars)) sqlAppendTable(ANSI(), "mtcars", head(mtcars), row.names = FALSE) sqlAppendTableTemplate(ANSI(), "iris", iris) sqlAppendTableTemplate(ANSI(), "mtcars", mtcars) sqlAppendTableTemplate(ANSI(), "mtcars", mtcars, row.names = FALSE) } \concept{SQL generation} DBI/man/SQL.Rd0000644000176200001440000000360613233155325012360 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.R \docType{class} \name{SQL} \alias{SQL} \alias{SQL-class} \title{SQL quoting} \usage{ SQL(x, ..., names = NULL) } \arguments{ \item{x}{A character vector to label as being escaped SQL.} \item{...}{Other arguments passed on to methods. Not otherwise used.} \item{names}{Names for the returned object, must have the same length as \code{x}.} } \value{ An object of class \code{SQL}. } \description{ This set of classes and generics make it possible to flexibly deal with SQL escaping needs. By default, any user supplied input to a query should be escaped using either \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} or \code{\link[=dbQuoteString]{dbQuoteString()}} depending on whether it refers to a table or variable name, or is a literal string. These functions may return an object of the \code{SQL} class, which tells DBI functions that a character string does not need to be escaped anymore, to prevent double escaping. The \code{SQL} class has associated the \code{SQL()} constructor function. } \section{Implementation notes}{ DBI provides default generics for SQL-92 compatible quoting. If the database uses a different convention, you will need to provide your own methods. Note that because of the way that S4 dispatch finds methods and because SQL inherits from character, if you implement (e.g.) a method for \code{dbQuoteString(MyConnection, character)}, you will also need to implement \code{dbQuoteString(MyConnection, SQL)} - this should simply return \code{x} unchanged. } \examples{ dbQuoteIdentifier(ANSI(), "SELECT") dbQuoteString(ANSI(), "SELECT") # SQL vectors are always passed through as is var_name <- SQL("SELECT") var_name dbQuoteIdentifier(ANSI(), var_name) dbQuoteString(ANSI(), var_name) # This mechanism is used to prevent double escaping dbQuoteString(ANSI(), dbQuoteString(ANSI(), "SELECT")) } DBI/man/dbCanConnect.Rd0000644000176200001440000000313413575266047014253 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \name{dbCanConnect} \alias{dbCanConnect} \title{Check if a connection to a DBMS can be established} \usage{ dbCanConnect(drv, ...) } \arguments{ \item{drv}{an object that inherits from \linkS4class{DBIDriver}, or an existing \linkS4class{DBIConnection} object (in order to clone an existing connection).} \item{...}{authentication arguments needed by the DBMS instance; these typically include \code{user}, \code{password}, \code{host}, \code{port}, \code{dbname}, etc. For details see the appropriate \code{DBIDriver}.} } \value{ A scalar logical. If \code{FALSE}, the \code{"reason"} attribute indicates a reason for failure. } \description{ Like \code{\link[=dbConnect]{dbConnect()}}, but only checks validity without actually returning a connection object. The default implementation opens a connection and disconnects on success, but individual backends might implement a lighter-weight check. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbCanConnect")} } \examples{ # SQLite only needs a path to the database. (Here, ":memory:" is a special # path that creates an in-memory database.) Other database drivers # will require more details (like user, password, host, port, etc.) dbCanConnect(RSQLite::SQLite(), ":memory:") } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} } \concept{DBIDriver generics} DBI/man/Id.Rd0000644000176200001440000000263613515056563012266 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/table.R \docType{class} \name{Id-class} \alias{Id-class} \alias{Id} \title{Refer to a table nested in a hierarchy (e.g. within a schema)} \usage{ Id(...) } \arguments{ \item{...}{Components of the hierarchy, e.g. \code{schema}, \code{table}, or \code{cluster}, \code{catalog}, \code{schema}, \code{table}. For more on these concepts, see \url{http://stackoverflow.com/questions/7022755/}} } \description{ Objects of class \code{Id} have a single slot \code{name}, which is a named character vector. The \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} method converts \code{Id} objects to strings. Support for \code{Id} objects depends on the database backend. They can be used in the following methods as \code{name} argument: \itemize{ \item \code{\link[=dbCreateTable]{dbCreateTable()}} \item \code{\link[=dbAppendTable]{dbAppendTable()}} \item \code{\link[=dbReadTable]{dbReadTable()}} \item \code{\link[=dbWriteTable]{dbWriteTable()}} \item \code{\link[=dbExistsTable]{dbExistsTable()}} \item \code{\link[=dbRemoveTable]{dbRemoveTable()}} Objects of this class are also returned from \code{\link[=dbListObjects]{dbListObjects()}}. } } \examples{ Id(schema = "dbo", table = "Customer") dbQuoteIdentifier(ANSI(), Id(schema = "nycflights13", table = "flights")) Id(cluster = "mycluster", catalog = "mycatalog", schema = "myschema", table = "mytable") } DBI/man/dbGetException.Rd0000644000176200001440000000247113575266047014641 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbGetException} \alias{dbGetException} \title{Get DBMS exceptions} \usage{ dbGetException(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \value{ a list with elements \code{errorNum} (an integer error number) and \code{errorMsg} (a character string) describing the last error in the connection \code{conn}. } \description{ DEPRECATED. Backends should use R's condition system to signal errors and warnings. } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} \keyword{internal} DBI/man/sqlCreateTable.Rd0000644000176200001440000000362413575266047014631 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/table-create.R \name{sqlCreateTable} \alias{sqlCreateTable} \title{Compose query to create a simple table} \usage{ sqlCreateTable(con, table, fields, row.names = NA, temporary = FALSE, ...) } \arguments{ \item{con}{A database connection.} \item{table}{Name of the table. Escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{fields}{Either a character vector or a data frame. A named character vector: Names are column names, values are types. Names are escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}. Field types are unescaped. A data frame: field types are generated using \code{\link[=dbDataType]{dbDataType()}}.} \item{row.names}{Either \code{TRUE}, \code{FALSE}, \code{NA} or a string. If \code{TRUE}, always translate row names to a column called "row_names". If \code{FALSE}, never translate row names. If \code{NA}, translate rownames only if they're a character vector. A string is equivalent to \code{TRUE}, but allows you to override the default name. For backward compatibility, \code{NULL} is equivalent to \code{FALSE}.} \item{temporary}{If \code{TRUE}, will generate a temporary table statement.} \item{...}{Other arguments used by individual methods.} } \description{ Exposes an interface to simple \verb{CREATE TABLE} commands. The default method is ANSI SQL 99 compliant. This method is mostly useful for backend implementers. } \details{ The \code{row.names} argument must be passed explicitly in order to avoid a compatibility warning. The default will be changed in a later release. } \examples{ sqlCreateTable(ANSI(), "my-table", c(a = "integer", b = "text")) sqlCreateTable(ANSI(), "my-table", iris) # By default, character row names are converted to a row_names colum sqlCreateTable(ANSI(), "mtcars", mtcars[, 1:5]) sqlCreateTable(ANSI(), "mtcars", mtcars[, 1:5], row.names = FALSE) } DBI/man/sqlInterpolate.Rd0000644000176200001440000000627713575266047014753 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/interpolate.R \name{sqlInterpolate} \alias{sqlInterpolate} \title{Safely interpolate values into an SQL string} \usage{ sqlInterpolate(conn, sql, ..., .dots = list()) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{sql}{A SQL string containing variables to interpolate. Variables must start with a question mark and can be any valid R identifier, i.e. it must start with a letter or \code{.}, and be followed by a letter, digit, \code{.} or \verb{_}.} \item{..., .dots}{Values (for \code{...}) or a list (for \code{.dots}) to interpolate into a string. Names are required if \code{sql} uses the \code{?name} syntax for placeholders. All values will be first escaped with \code{\link[=dbQuoteLiteral]{dbQuoteLiteral()}} prior to interpolation to protect against SQL injection attacks. Arguments created by \code{\link[=SQL]{SQL()}} or \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} remain unchanged.} } \value{ The \code{sql} query with the values from \code{...} and \code{.dots} safely embedded. } \description{ Accepts a query string with placeholders for values, and returns a string with the values embedded. The function is careful to quote all of its inputs with \code{\link[=dbQuoteLiteral]{dbQuoteLiteral()}} to protect against SQL injection attacks. Placeholders can be specified with one of two syntaxes: \itemize{ \item \verb{?}: each occurrence of a standalone \verb{?} is replaced with a value \item \code{?name1}, \code{?name2}, ...: values are given as named arguments or a named list, the names are used to match the values } Mixing \verb{?} and \code{?name} syntaxes is an error. The number and names of values supplied must correspond to the placeholders used in the query. } \section{Backend authors}{ If you are implementing an SQL backend with non-ANSI quoting rules, you'll need to implement a method for \code{\link[=sqlParseVariables]{sqlParseVariables()}}. Failure to do so does not expose you to SQL injection attacks, but will (rarely) result in errors matching supplied and interpolated variables. } \examples{ sql <- "SELECT * FROM X WHERE name = ?name" sqlInterpolate(ANSI(), sql, name = "Hadley") # This is safe because the single quote has been double escaped sqlInterpolate(ANSI(), sql, name = "H'); DROP TABLE--;") # Using paste0() could lead to dangerous SQL with carefully crafted inputs # (SQL injection) name <- "H'); DROP TABLE--;" paste0("SELECT * FROM X WHERE name = '", name, "'") # Use SQL() or dbQuoteIdentifier() to avoid escaping sql2 <- "SELECT * FROM ?table WHERE name in ?names" sqlInterpolate(ANSI(), sql2, table = dbQuoteIdentifier(ANSI(), "X"), names = SQL("('a', 'b')") ) # Don't use SQL() to escape identifiers to avoid SQL injection sqlInterpolate(ANSI(), sql2, table = SQL("X; DELETE FROM X; SELECT * FROM X"), names = SQL("('a', 'b')") ) # Use dbGetQuery() or dbExecute() to process these queries: if (requireNamespace("RSQLite", quietly = TRUE)) { con <- dbConnect(RSQLite::SQLite()) sql <- "SELECT ?value AS value" query <- sqlInterpolate(con, sql, value = 3) print(dbGetQuery(con, query)) dbDisconnect(con) } } DBI/man/sqlData.Rd0000644000176200001440000000263513550624555013323 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.R \name{sqlData} \alias{sqlData} \title{Convert a data frame into form suitable for upload to an SQL database} \usage{ sqlData(con, value, row.names = NA, ...) } \arguments{ \item{con}{A database connection.} \item{value}{A data frame} \item{row.names}{Either \code{TRUE}, \code{FALSE}, \code{NA} or a string. If \code{TRUE}, always translate row names to a column called "row_names". If \code{FALSE}, never translate row names. If \code{NA}, translate rownames only if they're a character vector. A string is equivalent to \code{TRUE}, but allows you to override the default name. For backward compatibility, \code{NULL} is equivalent to \code{FALSE}.} \item{...}{Other arguments used by individual methods.} } \description{ This is a generic method that coerces R objects into vectors suitable for upload to the database. The output will vary a little from method to method depending on whether the main upload device is through a single SQL string or multiple parameterized queries. This method is mostly useful for backend implementers. } \details{ The default method: \itemize{ \item Converts factors to characters \item Quotes all strings \item Converts all columns to strings \item Replaces NA with NULL } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") sqlData(con, head(iris)) sqlData(con, head(mtcars)) dbDisconnect(con) } DBI/man/dbSendQuery.Rd0000644000176200001440000001420313575266047014156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbSendQuery} \alias{dbSendQuery} \title{Execute a query on a given database connection} \usage{ dbSendQuery(conn, statement, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{statement}{a character string containing SQL.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbSendQuery()} returns an S4 object that inherits from \linkS4class{DBIResult}. The result set can be used with \code{\link[=dbFetch]{dbFetch()}} to extract records. Once you have finished using a result, make sure to clear it with \code{\link[=dbClearResult]{dbClearResult()}}. An error is raised when issuing a query over a closed or invalid connection, or if the query is not a non-\code{NA} string. An error is also raised if the syntax of the query is invalid and all query parameters are given (by passing the \code{params} argument) or the \code{immediate} argument is set to \code{TRUE}. } \description{ The \code{dbSendQuery()} method only submits and synchronously executes the SQL query to the database engine. It does \emph{not} extract any records --- for that you need to use the \code{\link[=dbFetch]{dbFetch()}} method, and then you must call \code{\link[=dbClearResult]{dbClearResult()}} when you finish fetching the records you need. For interactive use, you should almost always prefer \code{\link[=dbGetQuery]{dbGetQuery()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbSendQuery")} } \details{ This method is for \code{SELECT} queries only. Some backends may support data manipulation queries through this method for compatibility reasons. However, callers are strongly encouraged to use \code{\link[=dbSendStatement]{dbSendStatement()}} for data manipulation statements. The query is submitted to the database server and the DBMS executes it, possibly generating vast amounts of data. Where these data live is driver-specific: some drivers may choose to leave the output on the server and transfer them piecemeal to R, others may transfer all the data to the client -- but not necessarily to the memory that R manages. See individual drivers' \code{dbSendQuery()} documentation for details. } \section{Additional arguments}{ The following arguments are not part of the \code{dbSendQuery()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{params} (default: \code{NULL}) \item \code{immediate} (default: \code{NULL}) } They must be provided as named arguments. See the "Specification" sections for details on their usage. } \section{Specification}{ No warnings occur under normal conditions. When done, the DBIResult object must be cleared with a call to \code{\link[=dbClearResult]{dbClearResult()}}. Failure to clear the result set leads to a warning when the connection is closed. If the backend supports only one open result set per connection, issuing a second query invalidates an already open result set and raises a warning. The newly opened result set is valid and must be cleared with \code{dbClearResult()}. The \code{param} argument allows passing query parameters, see \code{\link[=dbBind]{dbBind()}} for details. } \section{Specification for the \code{immediate} argument}{ The \code{immediate} argument supports distinguishing between "direct" and "prepared" APIs offered by many database drivers. Passing \code{immediate = TRUE} leads to immediate execution of the query or statement, via the "direct" API (if supported by the driver). The default \code{NULL} means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct \code{immediate} argument. Examples for possible behaviors: \enumerate{ \item DBI backend defaults to \code{immediate = TRUE} internally \enumerate{ \item A query without parameters is passed: query is executed \item A query with parameters is passed: \enumerate{ \item \code{params} not given: rejected immediately by the database because of a syntax error in the query, the backend tries \code{immediate = FALSE} (and gives a message) \item \code{params} given: query is executed using \code{immediate = FALSE} } } \item DBI backend defaults to \code{immediate = FALSE} internally \enumerate{ \item A query without parameters is passed: \enumerate{ \item simple query: query is executed \item "special" query (such as setting a config options): fails, the backend tries \code{immediate = TRUE} (and gives a message) } \item A query with parameters is passed: \enumerate{ \item \code{params} not given: waiting for parameters via \code{\link[=dbBind]{dbBind()}} \item \code{params} given: query is executed } } } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") dbFetch(rs) dbClearResult(rs) # Pass one set of values with the param argument: rs <- dbSendQuery( con, "SELECT * FROM mtcars WHERE cyl = ?", params = list(4L) ) dbFetch(rs) dbClearResult(rs) # Pass multiple sets of values with dbBind(): rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = ?") dbBind(rs, list(6L)) dbFetch(rs) dbBind(rs, list(8L)) dbFetch(rs) dbClearResult(rs) dbDisconnect(con) } \seealso{ For updates: \code{\link[=dbSendStatement]{dbSendStatement()}} and \code{\link[=dbExecute]{dbExecute()}}. Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbCallProc.Rd0000644000176200001440000000125013272170454013722 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.R \name{dbCallProc} \alias{dbCallProc} \title{Call an SQL stored procedure} \usage{ dbCallProc(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \description{ \strong{Deprecated since 2014} } \details{ The recommended way of calling a stored procedure is now \enumerate{ \item{\code{\link{dbGetQuery}} if a result set is returned} \item{\code{\link{dbExecute}} for data manipulation and other cases where no result set is returned} } } \keyword{internal} DBI/man/dbGetInfo.Rd0000644000176200001440000000763413575266047013604 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBObject.R, R/DBResult.R \name{dbGetInfo} \alias{dbGetInfo} \title{Get DBMS metadata} \usage{ dbGetInfo(dbObj, ...) } \arguments{ \item{dbObj}{An object inheriting from \linkS4class{DBIObject}, i.e. \linkS4class{DBIDriver}, \linkS4class{DBIConnection}, or a \linkS4class{DBIResult}} \item{...}{Other arguments to methods.} } \value{ For objects of class \linkS4class{DBIDriver}, \code{dbGetInfo()} returns a named list that contains at least the following components: \itemize{ \item \code{driver.version}: the package version of the DBI backend, \item \code{client.version}: the version of the DBMS client library. } For objects of class \linkS4class{DBIConnection}, \code{dbGetInfo()} returns a named list that contains at least the following components: \itemize{ \item \code{db.version}: version of the database server, \item \code{dbname}: database name, \item \code{username}: username to connect to the database, \item \code{host}: hostname of the database server, \item \code{port}: port on the database server. It must not contain a \code{password} component. Components that are not applicable should be set to \code{NA}. } For objects of class \linkS4class{DBIResult}, \code{dbGetInfo()} returns a named list that contains at least the following components: \itemize{ \item \code{statatment}: the statement used with \code{\link[=dbSendQuery]{dbSendQuery()}} or \code{\link[=dbExecute]{dbExecute()}}, as returned by \code{\link[=dbGetStatement]{dbGetStatement()}}, \item \code{row.count}: the number of rows fetched so far (for queries), as returned by \code{\link[=dbGetRowCount]{dbGetRowCount()}}, \item \code{rows.affected}: the number of rows affected (for statements), as returned by \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}} \item \code{has.completed}: a logical that indicates if the query or statement has completed, as returned by \code{\link[=dbHasCompleted]{dbHasCompleted()}}. } } \description{ Retrieves information on objects of class \linkS4class{DBIDriver}, \linkS4class{DBIConnection} or \linkS4class{DBIResult}. } \section{Implementation notes}{ The default implementation for \verb{DBIResult objects} constructs such a list from the return values of the corresponding methods, \code{\link[=dbGetStatement]{dbGetStatement()}}, \code{\link[=dbGetRowCount]{dbGetRowCount()}}, \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}}, and \code{\link[=dbHasCompleted]{dbHasCompleted()}}. } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIConnection generics} \concept{DBIDriver generics} \concept{DBIResult generics} DBI/man/dbAppendTable.Rd0000644000176200001440000000463313575266047014424 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/table-insert.R \name{dbAppendTable} \alias{dbAppendTable} \title{Insert rows into a table} \usage{ dbAppendTable(conn, name, value, ..., row.names = NULL) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{Name of the table, escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{value}{A data frame of values. The column names must be consistent with those in the target table in the database.} \item{...}{Other arguments used by individual methods.} \item{row.names}{Must be \code{NULL}.} } \description{ The \code{dbAppendTable()} method assumes that the table has been created beforehand, e.g. with \code{\link[=dbCreateTable]{dbCreateTable()}}. The default implementation calls \code{\link[=sqlAppendTableTemplate]{sqlAppendTableTemplate()}} and then \code{\link[=dbExecute]{dbExecute()}} with the \code{param} argument. Backends compliant to ANSI SQL 99 which use \verb{?} as a placeholder for prepard queries don't need to override it. Backends with a different SQL syntax which use \verb{?} as a placeholder for prepared queries can override \code{\link[=sqlAppendTable]{sqlAppendTable()}}. Other backends (with different placeholders or with entirely different ways to create tables) need to override the \code{dbAppendTable()} method. } \details{ The \code{row.names} argument is not supported by this method. Process the values with \code{\link[=sqlRownamesToColumn]{sqlRownamesToColumn()}} before calling this method. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbCreateTable(con, "iris", iris) dbAppendTable(con, "iris", iris) dbReadTable(con, "iris") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbCreateTable.Rd0000644000176200001440000000465613575266047014425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/table-create.R \name{dbCreateTable} \alias{dbCreateTable} \title{Create a table in the database} \usage{ dbCreateTable(conn, name, fields, ..., row.names = NULL, temporary = FALSE) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{Name of the table, escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{fields}{Either a character vector or a data frame. A named character vector: Names are column names, values are types. Names are escaped with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}. Field types are unescaped. A data frame: field types are generated using \code{\link[=dbDataType]{dbDataType()}}.} \item{...}{Other arguments used by individual methods.} \item{row.names}{Must be \code{NULL}.} \item{temporary}{If \code{TRUE}, will generate a temporary table statement.} } \description{ The default \code{dbCreateTable()} method calls \code{\link[=sqlCreateTable]{sqlCreateTable()}} and \code{\link[=dbExecute]{dbExecute()}}. Backends compliant to ANSI SQL 99 don't need to override it. Backends with a different SQL syntax can override \code{sqlCreateTable()}, backends with entirely different ways to create tables need to override this method. } \details{ The \code{row.names} argument is not supported by this method. Process the values with \code{\link[=sqlRownamesToColumn]{sqlRownamesToColumn()}} before calling this method. The argument order is different from the \code{sqlCreateTable()} method, the latter will be adapted in a later release of DBI. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbCreateTable(con, "iris", iris) dbReadTable(con, "iris") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/ANSI.Rd0000644000176200001440000000046013054310030012431 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ANSI.R \name{ANSI} \alias{ANSI} \title{A dummy DBI connector that simulates ANSI-SQL compliance} \usage{ ANSI() } \description{ A dummy DBI connector that simulates ANSI-SQL compliance } \examples{ ANSI() } \keyword{internal} DBI/man/dbListResults.Rd0000644000176200001440000000252713575266047014542 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbListResults} \alias{dbListResults} \title{A list of all pending results} \usage{ dbListResults(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \value{ a list. If no results are active, an empty list. If only a single result is active, a list with one element. } \description{ DEPRECATED. DBI currenty supports only one open result set per connection, you need to keep track of the result sets you open if you need this functionality. } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} \keyword{internal} DBI/man/dbExecute.Rd0000644000176200001440000001170313575266047013643 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbExecute} \alias{dbExecute} \title{Execute an update statement, query number of rows affected, and then close result set} \usage{ dbExecute(conn, statement, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{statement}{a character string containing SQL.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbExecute()} always returns a scalar numeric that specifies the number of rows affected by the statement. An error is raised when issuing a statement over a closed or invalid connection, if the syntax of the statement is invalid, or if the statement is not a non-\code{NA} string. } \description{ Executes a statement and returns the number of rows affected. \code{dbExecute()} comes with a default implementation (which should work with most backends) that calls \code{\link[=dbSendStatement]{dbSendStatement()}}, then \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}}, ensuring that the result is always free-d by \code{\link[=dbClearResult]{dbClearResult()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbExecute")} } \details{ You can also use \code{dbExecute()} to call a stored procedure that performs data manipulation or other actions that do not return a result set. To execute a stored procedure that returns a result set use \code{\link[=dbGetQuery]{dbGetQuery()}} instead. } \section{Implementation notes}{ Subclasses should override this method only if they provide some sort of performance optimization. } \section{Additional arguments}{ The following arguments are not part of the \code{dbExecute()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{params} (default: \code{NULL}) \item \code{immediate} (default: \code{NULL}) } They must be provided as named arguments. See the "Specification" sections for details on their usage. } \section{Specification}{ The \code{param} argument allows passing query parameters, see \code{\link[=dbBind]{dbBind()}} for details. } \section{Specification for the \code{immediate} argument}{ The \code{immediate} argument supports distinguishing between "direct" and "prepared" APIs offered by many database drivers. Passing \code{immediate = TRUE} leads to immediate execution of the query or statement, via the "direct" API (if supported by the driver). The default \code{NULL} means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct \code{immediate} argument. Examples for possible behaviors: \enumerate{ \item DBI backend defaults to \code{immediate = TRUE} internally \enumerate{ \item A query without parameters is passed: query is executed \item A query with parameters is passed: \enumerate{ \item \code{params} not given: rejected immediately by the database because of a syntax error in the query, the backend tries \code{immediate = FALSE} (and gives a message) \item \code{params} given: query is executed using \code{immediate = FALSE} } } \item DBI backend defaults to \code{immediate = FALSE} internally \enumerate{ \item A query without parameters is passed: \enumerate{ \item simple query: query is executed \item "special" query (such as setting a config options): fails, the backend tries \code{immediate = TRUE} (and gives a message) } \item A query with parameters is passed: \enumerate{ \item \code{params} not given: waiting for parameters via \code{\link[=dbBind]{dbBind()}} \item \code{params} given: query is executed } } } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "cars", head(cars, 3)) dbReadTable(con, "cars") # there are 3 rows dbExecute( con, "INSERT INTO cars (speed, dist) VALUES (1, 1), (2, 2), (3, 3)" ) dbReadTable(con, "cars") # there are now 6 rows # Pass values using the param argument: dbExecute( con, "INSERT INTO cars (speed, dist) VALUES (?, ?)", params = list(4:7, 5:8) ) dbReadTable(con, "cars") # there are now 10 rows dbDisconnect(con) } \seealso{ For queries: \code{\link[=dbSendQuery]{dbSendQuery()}} and \code{\link[=dbGetQuery]{dbGetQuery()}}. Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/DBIObject-class.Rd0000644000176200001440000000317013575266047014562 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBObject.R \docType{class} \name{DBIObject-class} \alias{DBIObject-class} \title{DBIObject class} \description{ Base class for all other DBI classes (e.g., drivers, connections). This is a virtual Class: No objects may be created from it. } \details{ More generally, the DBI defines a very small set of classes and generics that allows users and applications access DBMS with a common interface. The virtual classes are \code{DBIDriver} that individual drivers extend, \code{DBIConnection} that represent instances of DBMS connections, and \code{DBIResult} that represent the result of a DBMS statement. These three classes extend the basic class of \code{DBIObject}, which serves as the root or parent of the class hierarchy. } \section{Implementation notes}{ An implementation MUST provide methods for the following generics: \itemize{ \item \code{\link[=dbGetInfo]{dbGetInfo()}}. } It MAY also provide methods for: \itemize{ \item \code{\link[=summary]{summary()}}. Print a concise description of the object. The default method invokes \code{dbGetInfo(dbObj)} and prints the name-value pairs one per line. Individual implementations may tailor this appropriately. } } \examples{ drv <- RSQLite::SQLite() con <- dbConnect(drv) rs <- dbSendQuery(con, "SELECT 1") is(drv, "DBIObject") ## True is(con, "DBIObject") ## True is(rs, "DBIObject") dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBI classes: \code{\link{DBIConnection-class}}, \code{\link{DBIConnector-class}}, \code{\link{DBIDriver-class}}, \code{\link{DBIResult-class}} } \concept{DBI classes} DBI/man/dbIsValid.Rd0000644000176200001440000000655113575266047013601 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBObject.R \name{dbIsValid} \alias{dbIsValid} \title{Is this DBMS object still valid?} \usage{ dbIsValid(dbObj, ...) } \arguments{ \item{dbObj}{An object inheriting from \linkS4class{DBIObject}, i.e. \linkS4class{DBIDriver}, \linkS4class{DBIConnection}, or a \linkS4class{DBIResult}} \item{...}{Other arguments to methods.} } \value{ \code{dbIsValid()} returns a logical scalar, \code{TRUE} if the object specified by \code{dbObj} is valid, \code{FALSE} otherwise. A \linkS4class{DBIConnection} object is initially valid, and becomes invalid after disconnecting with \code{\link[=dbDisconnect]{dbDisconnect()}}. For an invalid connection object (e.g., for some drivers if the object is saved to a file and then restored), the method also returns \code{FALSE}. A \linkS4class{DBIResult} object is valid after a call to \code{\link[=dbSendQuery]{dbSendQuery()}}, and stays valid even after all rows have been fetched; only clearing it with \code{\link[=dbClearResult]{dbClearResult()}} invalidates it. A \linkS4class{DBIResult} object is also valid after a call to \code{\link[=dbSendStatement]{dbSendStatement()}}, and stays valid after querying the number of rows affected; only clearing it with \code{\link[=dbClearResult]{dbClearResult()}} invalidates it. If the connection to the database system is dropped (e.g., due to connectivity problems, server failure, etc.), \code{dbIsValid()} should return \code{FALSE}. This is not tested automatically. } \description{ This generic tests whether a database object is still valid (i.e. it hasn't been disconnected or cleared). \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbIsValid")} } \examples{ dbIsValid(RSQLite::SQLite()) con <- dbConnect(RSQLite::SQLite(), ":memory:") dbIsValid(con) rs <- dbSendQuery(con, "SELECT 1") dbIsValid(rs) dbClearResult(rs) dbIsValid(rs) dbDisconnect(con) dbIsValid(con) } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbListConnections}()} Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIConnection generics} \concept{DBIDriver generics} \concept{DBIResult generics} DBI/man/dbGetRowCount.Rd0000644000176200001440000000422713575266047014464 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbGetRowCount} \alias{dbGetRowCount} \title{The number of rows fetched so far} \usage{ dbGetRowCount(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbGetRowCount()} returns a scalar number (integer or numeric), the number of rows fetched so far. After calling \code{\link[=dbSendQuery]{dbSendQuery()}}, the row count is initially zero. After a call to \code{\link[=dbFetch]{dbFetch()}} without limit, the row count matches the total number of rows returned. Fetching a limited number of rows increases the number of rows by the number of rows returned, even if fetching past the end of the result set. For queries with an empty result set, zero is returned even after fetching. For data manipulation statements issued with \code{\link[=dbSendStatement]{dbSendStatement()}}, zero is returned before and after calling \code{dbFetch()}. Attempting to get the row count for a result set cleared with \code{\link[=dbClearResult]{dbClearResult()}} gives an error. } \description{ Returns the total number of rows actually fetched with calls to \code{\link[=dbFetch]{dbFetch()}} for this result set. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbGetRowCount")} } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) rs <- dbSendQuery(con, "SELECT * FROM mtcars") dbGetRowCount(rs) ret1 <- dbFetch(rs, 10) dbGetRowCount(rs) ret2 <- dbFetch(rs) dbGetRowCount(rs) nrow(ret1) + nrow(ret2) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbReadTable.Rd0000644000176200001440000000770213575266242014065 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbReadTable} \alias{dbReadTable} \title{Copy data frames from database tables} \usage{ dbReadTable(conn, name, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{A character string specifying the unquoted DBMS table name, or the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbReadTable()} returns a data frame that contains the complete data from the remote table, effectively the result of calling \code{\link[=dbGetQuery]{dbGetQuery()}} with \verb{SELECT * FROM }. An error is raised if the table does not exist. An empty table is returned as a data frame with zero rows. The presence of \link{rownames} depends on the \code{row.names} argument, see \code{\link[=sqlColumnToRownames]{sqlColumnToRownames()}} for details: \itemize{ \item If \code{FALSE} or \code{NULL}, the returned data frame doesn't have row names. \item If \code{TRUE}, a column named "row_names" is converted to row names, an error is raised if no such column exists. \item If \code{NA}, a column named "row_names" is converted to row names if it exists, otherwise no translation occurs. \item If a string, this specifies the name of the column in the remote table that contains the row names, an error is raised if no such column exists. } The default is \code{row.names = FALSE}. If the database supports identifiers with special characters, the columns in the returned data frame are converted to valid R identifiers if the \code{check.names} argument is \code{TRUE}, otherwise non-syntactic column names can be returned unquoted. An error is raised when calling this method for a closed or invalid connection. An error is raised if \code{name} cannot be processed with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} or if this results in a non-scalar. Unsupported values for \code{row.names} and \code{check.names} (non-scalars, unsupported data types, \code{NA} for \code{check.names}) also raise an error. } \description{ Reads a database table to a data frame, optionally converting a column to row names and converting the column names to valid R identifiers. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbReadTable")} } \section{Additional arguments}{ The following arguments are not part of the \code{dbReadTable()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{row.names} (default: \code{FALSE}) \item \code{check.names} } They must be provided as named arguments. See the "Value" section for details on their usage. } \section{Specification}{ The \code{name} argument is processed as follows, to support databases that allow non-syntactic names for their objects: \itemize{ \item If an unquoted table name as string: \code{dbReadTable()} will do the quoting, perhaps by calling \code{dbQuoteIdentifier(conn, x = name)} \item If the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}: no more quoting is done } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars[1:10, ]) dbReadTable(con, "mtcars") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbQuoteIdentifier.Rd0000644000176200001440000000633413575266047015345 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.R \name{dbQuoteIdentifier} \alias{dbQuoteIdentifier} \title{Quote identifiers} \usage{ dbQuoteIdentifier(conn, x, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{x}{A character vector, \link{SQL} or \link{Id} object to quote as identifier.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbQuoteIdentifier()} returns an object that can be coerced to \link{character}, of the same length as the input. For an empty character vector this function returns a length-0 object. The names of the input argument are preserved in the output. When passing the returned object again to \code{dbQuoteIdentifier()} as \code{x} argument, it is returned unchanged. Passing objects of class \link{SQL} should also return them unchanged. (For backends it may be most convenient to return \link{SQL} objects to achieve this behavior, but this is not required.) An error is raised if the input contains \code{NA}, but not for an empty string. } \description{ Call this method to generate a string that is suitable for use in a query as a column or table name, to make sure that you generate valid SQL and protect against SQL injection attacks. The inverse operation is \code{\link[=dbUnquoteIdentifier]{dbUnquoteIdentifier()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbQuoteIdentifier")} } \section{Specification}{ Calling \code{\link[=dbGetQuery]{dbGetQuery()}} for a query of the format \verb{SELECT 1 AS ...} returns a data frame with the identifier, unquoted, as column name. Quoted identifiers can be used as table and column names in SQL queries, in particular in queries like \verb{SELECT 1 AS ...} and \verb{SELECT * FROM (SELECT 1) ...}. The method must use a quoting mechanism that is unambiguously different from the quoting mechanism used for strings, so that a query like \verb{SELECT ... FROM (SELECT 1 AS ...)} throws an error if the column names do not match. The method can quote column names that contain special characters such as a space, a dot, a comma, or quotes used to mark strings or identifiers, if the database supports this. In any case, checking the validity of the identifier should be performed only when executing a query, and not by \code{dbQuoteIdentifier()}. } \examples{ # Quoting ensures that arbitrary input is safe for use in a query name <- "Robert'); DROP TABLE Students;--" dbQuoteIdentifier(ANSI(), name) # SQL vectors are always passed through as is var_name <- SQL("select") var_name dbQuoteIdentifier(ANSI(), var_name) # This mechanism is used to prevent double escaping dbQuoteIdentifier(ANSI(), dbQuoteIdentifier(ANSI(), name)) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbGetStatement.Rd0000644000176200001440000000310213575266047014637 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbGetStatement} \alias{dbGetStatement} \title{Get the statement associated with a result set} \usage{ dbGetStatement(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbGetStatement()} returns a string, the query used in either \code{\link[=dbSendQuery]{dbSendQuery()}} or \code{\link[=dbSendStatement]{dbSendStatement()}}. Attempting to query the statement for a result set cleared with \code{\link[=dbClearResult]{dbClearResult()}} gives an error. } \description{ Returns the statement that was passed to \code{\link[=dbSendQuery]{dbSendQuery()}} or \code{\link[=dbSendStatement]{dbSendStatement()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbGetStatement")} } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) rs <- dbSendQuery(con, "SELECT * FROM mtcars") dbGetStatement(rs) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbSetDataMappings.Rd0000644000176200001440000000164213071276341015253 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.R \name{dbSetDataMappings} \alias{dbSetDataMappings} \title{Set data mappings between an DBMS and R.} \usage{ dbSetDataMappings(res, flds, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{flds}{a field description object as returned by \code{dbColumnInfo}.} \item{...}{Other arguments passed on to methods.} } \description{ This generic is deprecated since no working implementation was ever produced. } \details{ Sets one or more conversion functions to handle the translation of DBMS data types to R objects. This is only needed for non-primitive data, since all DBI drivers handle the common base types (integers, numeric, strings, etc.) The details on conversion functions (e.g., arguments, whether they can invoke initializers and/or destructors) have not been specified. } \keyword{internal} DBI/man/dbColumnInfo.Rd0000644000176200001440000000457613575266047014324 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbColumnInfo} \alias{dbColumnInfo} \title{Information about result types} \usage{ dbColumnInfo(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbColumnInfo()} returns a data frame with at least two columns \code{"name"} and \code{"type"} (in that order) (and optional columns that start with a dot). The \code{"name"} and \code{"type"} columns contain the names and types of the R columns of the data frame that is returned from \code{\link[=dbFetch]{dbFetch()}}. The \code{"type"} column is of type \code{character} and only for information. Do not compute on the \code{"type"} column, instead use \code{dbFetch(res, n = 0)} to create a zero-row data frame initialized with the correct data types. An attempt to query columns for a closed result set raises an error. } \description{ Produces a data.frame that describes the output of a query. The data.frame should have as many rows as there are output fields in the result set, and each column in the data.frame describes an aspect of the result set field (field name, type, etc.) } \section{Specification}{ A column named \code{row_names} is treated like any other column. The column names are always consistent with the data returned by \code{dbFetch()}. If the query returns unnamed columns, unique non-empty and non-\code{NA} names are assigned. In the case of a duplicate column name, the first occurrence retains the original name, and unique names are assigned for the other occurrences. Column names that correspond to SQL or R keywords are left unchanged. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") rs <- dbSendQuery(con, "SELECT 1 AS a, 2 AS b") dbColumnInfo(rs) dbFetch(rs) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbListTables.Rd0000644000176200001440000000373513575266047014315 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbListTables} \alias{dbListTables} \title{List remote tables} \usage{ dbListTables(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbListTables()} returns a character vector that enumerates all tables and views in the database. Tables added with \code{\link[=dbWriteTable]{dbWriteTable()}} are part of the list, including temporary tables if supported by the database. As soon a table is removed from the database, it is also removed from the list of database tables. The returned names are suitable for quoting with \code{dbQuoteIdentifier()}. An error is raised when calling this method for a closed or invalid connection. } \description{ Returns the unquoted names of remote tables accessible through this connection. This should include views and temporary objects, but not all database backends (in particular \pkg{RMariaDB} and \pkg{RMySQL}) support this. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbListTables")} } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbListTables(con) dbWriteTable(con, "mtcars", mtcars) dbListTables(con) dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/sqlParseVariables.Rd0000644000176200001440000000313013575266047015351 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/interpolate.R \name{sqlParseVariables} \alias{sqlParseVariables} \alias{sqlCommentSpec} \alias{sqlQuoteSpec} \alias{sqlParseVariablesImpl} \title{Parse interpolated variables from SQL.} \usage{ sqlParseVariables(conn, sql, ...) sqlCommentSpec(start, end, endRequired) sqlQuoteSpec(start, end, escape = "", doubleEscape = TRUE) sqlParseVariablesImpl(sql, quotes, comments) } \arguments{ \item{sql}{SQL to parse (a character string)} \item{start, end}{Start and end characters for quotes and comments} \item{endRequired}{Is the ending character of a comment required?} \item{escape}{What character can be used to escape quoting characters? Defaults to \code{""}, i.e. nothing.} \item{doubleEscape}{Can quoting characters be escaped by doubling them? Defaults to \code{TRUE}.} \item{quotes}{A list of \code{QuoteSpec} calls defining the quoting specification.} \item{comments}{A list of \code{CommentSpec} calls defining the commenting specification.} } \description{ If you're implementing a backend that uses non-ANSI quoting or commenting rules, you'll need to implement a method for \code{sqlParseVariables} that calls \code{sqlParseVariablesImpl} with the appropriate quote and comment specifications. } \examples{ # Use [] for quoting and no comments sqlParseVariablesImpl("[?a]", list(sqlQuoteSpec("[", "]", "\\\\", FALSE)), list() ) # Standard quotes, use # for commenting sqlParseVariablesImpl("# ?a\n?b", list(sqlQuoteSpec("'", "'"), sqlQuoteSpec('"', '"')), list(sqlCommentSpec("#", "\n", FALSE)) ) } \keyword{internal} DBI/man/dbDriver.Rd0000644000176200001440000000443013575266047013473 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \name{dbDriver} \alias{dbDriver} \alias{dbUnloadDriver} \title{Load and unload database drivers} \usage{ dbDriver(drvName, ...) dbUnloadDriver(drv, ...) } \arguments{ \item{drvName}{character name of the driver to instantiate.} \item{...}{any other arguments are passed to the driver \code{drvName}.} \item{drv}{an object that inherits from \code{DBIDriver} as created by \code{dbDriver}.} } \value{ In the case of \code{dbDriver}, an driver object whose class extends \code{DBIDriver}. This object may be used to create connections to the actual DBMS engine. In the case of \code{dbUnloadDriver}, a logical indicating whether the operation succeeded or not. } \description{ These methods are deprecated, please consult the documentation of the individual backends for the construction of driver instances. \code{dbDriver()} is a helper method used to create an new driver object given the name of a database or the corresponding R package. It works through convention: all DBI-extending packages should provide an exported object with the same name as the package. \code{dbDriver()} just looks for this object in the right places: if you know what database you are connecting to, you should call the function directly. \code{dbUnloadDriver()} is not implemented for modern backends. } \details{ The client part of the database communication is initialized (typically dynamically loading C code, etc.) but note that connecting to the database engine itself needs to be done through calls to \code{dbConnect}. } \examples{ # Create a RSQLite driver with a string d <- dbDriver("SQLite") d # But better, access the object directly RSQLite::SQLite() } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} } \concept{DBIDriver generics} \keyword{internal} DBI/man/dbDisconnect.Rd0000644000176200001440000000323213575266047014330 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbDisconnect} \alias{dbDisconnect} \title{Disconnect (close) a connection} \usage{ dbDisconnect(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbDisconnect()} returns \code{TRUE}, invisibly. } \description{ This closes the connection, discards all pending work, and frees resources (e.g., memory, sockets). \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbDisconnect")} } \section{Specification}{ A warning is issued on garbage collection when a connection has been released without calling \code{dbDisconnect()}, but this cannot be tested automatically. A warning is issued immediately when calling \code{dbDisconnect()} on an already disconnected or invalid connection. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbClearResult.Rd0000644000176200001440000000345713575266047014475 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbClearResult} \alias{dbClearResult} \title{Clear a result set} \usage{ dbClearResult(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbClearResult()} returns \code{TRUE}, invisibly, for result sets obtained from both \code{dbSendQuery()} and \code{dbSendStatement()}. An attempt to close an already closed result set issues a warning in both cases. } \description{ Frees all resources (local and remote) associated with a result set. In some cases (e.g., very large result sets) this can be a critical step to avoid exhausting resources (memory, file descriptors, etc.) \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbClearResult")} } \section{Specification}{ \code{dbClearResult()} frees all resources associated with retrieving the result of a query or update operation. The DBI backend can expect a call to \code{dbClearResult()} for each \code{\link[=dbSendQuery]{dbSendQuery()}} or \code{\link[=dbSendStatement]{dbSendStatement()}} call. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") rs <- dbSendQuery(con, "SELECT 1") print(dbFetch(rs)) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/DBI-package.Rd0000644000176200001440000000462613575266047013730 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBI-package.R \docType{package} \name{DBI-package} \alias{DBI} \alias{DBI-package} \title{DBI: R Database Interface} \description{ DBI defines an interface for communication between R and relational database management systems. All classes in this package are virtual and need to be extended by the various R/DBMS implementations (so-called \emph{DBI backends}). } \section{Definition}{ A DBI backend is an R package which imports the \pkg{DBI} and \pkg{methods} packages. For better or worse, the names of many existing backends start with \sQuote{R}, e.g., \pkg{RSQLite}, \pkg{RMySQL}, \pkg{RSQLServer}; it is up to the backend author to adopt this convention or not. } \section{DBI classes and methods}{ A backend defines three classes, which are subclasses of \linkS4class{DBIDriver}, \linkS4class{DBIConnection}, and \linkS4class{DBIResult}. The backend provides implementation for all methods of these base classes that are defined but not implemented by DBI. All methods defined in \pkg{DBI} are reexported (so that the package can be used without having to attach \pkg{DBI}), and have an ellipsis \code{...} in their formals for extensibility. } \section{Construction of the DBIDriver object}{ The backend must support creation of an instance of its \linkS4class{DBIDriver} subclass with a \dfn{constructor function}. By default, its name is the package name without the leading \sQuote{R} (if it exists), e.g., \code{SQLite} for the \pkg{RSQLite} package. However, backend authors may choose a different name. The constructor must be exported, and it must be a function that is callable without arguments. DBI recommends to define a constructor with an empty argument list. } \examples{ RSQLite::SQLite() } \seealso{ Important generics: \code{\link[=dbConnect]{dbConnect()}}, \code{\link[=dbGetQuery]{dbGetQuery()}}, \code{\link[=dbReadTable]{dbReadTable()}}, \code{\link[=dbWriteTable]{dbWriteTable()}}, \code{\link[=dbDisconnect]{dbDisconnect()}} Formal specification (currently work in progress and incomplete): \code{vignette("spec", package = "DBI")} } \author{ \strong{Maintainer}: Kirill Müller \email{krlmlr+r@mailbox.org} (\href{https://orcid.org/0000-0002-1416-3412}{ORCID}) Authors: \itemize{ \item R Special Interest Group on Databases (R-SIG-DB) \item Hadley Wickham } Other contributors: \itemize{ \item R Consortium [funder] } } DBI/man/dbWithTransaction.Rd0000644000176200001440000000626313233155325015352 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/transactions.R \name{dbWithTransaction} \alias{dbWithTransaction} \alias{dbBreak} \title{Self-contained SQL transactions} \usage{ dbWithTransaction(conn, code, ...) dbBreak() } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{code}{An arbitrary block of R code.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbWithTransaction()} returns the value of the executed code. Failure to initiate the transaction (e.g., if the connection is closed or invalid of if \code{\link[=dbBegin]{dbBegin()}} has been called already) gives an error. } \description{ Given that \link{transactions} are implemented, this function allows you to pass in code that is run in a transaction. The default method of \code{dbWithTransaction()} calls \code{\link[=dbBegin]{dbBegin()}} before executing the code, and \code{\link[=dbCommit]{dbCommit()}} after successful completion, or \code{\link[=dbRollback]{dbRollback()}} in case of an error. The advantage is that you don't have to remember to do \code{dbBegin()} and \code{dbCommit()} or \code{dbRollback()} -- that is all taken care of. The special function \code{dbBreak()} allows an early exit with rollback, it can be called only inside \code{dbWithTransaction()}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbWithTransaction")} } \details{ DBI implements \code{dbWithTransaction()}, backends should need to override this generic only if they implement specialized handling. } \section{Specification}{ \code{dbWithTransaction()} initiates a transaction with \code{dbBegin()}, executes the code given in the \code{code} argument, and commits the transaction with \code{\link[=dbCommit]{dbCommit()}}. If the code raises an error, the transaction is instead aborted with \code{\link[=dbRollback]{dbRollback()}}, and the error is propagated. If the code calls \code{dbBreak()}, execution of the code stops and the transaction is silently aborted. All side effects caused by the code (such as the creation of new variables) propagate to the calling environment. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "cash", data.frame(amount = 100)) dbWriteTable(con, "account", data.frame(amount = 2000)) # All operations are carried out as logical unit: dbWithTransaction( con, { withdrawal <- 300 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) } ) # The code is executed as if in the curent environment: withdrawal # The changes are committed to the database after successful execution: dbReadTable(con, "cash") dbReadTable(con, "account") # Rolling back with dbBreak(): dbWithTransaction( con, { withdrawal <- 5000 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) if (dbReadTable(con, "account")$amount < 0) { dbBreak() } } ) # These changes were not committed to the database: dbReadTable(con, "cash") dbReadTable(con, "account") dbDisconnect(con) } DBI/man/dbConnect.Rd0000644000176200001440000000675613575266047013646 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \name{dbConnect} \alias{dbConnect} \title{Create a connection to a DBMS} \usage{ dbConnect(drv, ...) } \arguments{ \item{drv}{an object that inherits from \linkS4class{DBIDriver}, or an existing \linkS4class{DBIConnection} object (in order to clone an existing connection).} \item{...}{authentication arguments needed by the DBMS instance; these typically include \code{user}, \code{password}, \code{host}, \code{port}, \code{dbname}, etc. For details see the appropriate \code{DBIDriver}.} } \value{ \code{dbConnect()} returns an S4 object that inherits from \linkS4class{DBIConnection}. This object is used to communicate with the database engine. A \code{\link[=format]{format()}} method is defined for the connection object. It returns a string that consists of a single line of text. } \description{ Connect to a DBMS going through the appropriate authentication procedure. Some implementations may allow you to have multiple connections open, so you may invoke this function repeatedly assigning its output to different objects. The authentication mechanism is left unspecified, so check the documentation of individual drivers for details. Use \code{\link[=dbCanConnect]{dbCanConnect()}} to check if a connection can be established. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbConnect")} } \section{Specification}{ DBI recommends using the following argument names for authentication parameters, with \code{NULL} default: \itemize{ \item \code{user} for the user name (default: current user) \item \code{password} for the password \item \code{host} for the host name (default: local connection) \item \code{port} for the port number (default: local connection) \item \code{dbname} for the name of the database on the host, or the database file name } The defaults should provide reasonable behavior, in particular a local connection for \code{host = NULL}. For some DBMS (e.g., PostgreSQL), this is different to a TCP/IP connection to \code{localhost}. In addition, DBI supports the \code{bigint} argument that governs how 64-bit integer data is returned. The following values are supported: \itemize{ \item \code{"integer"}: always return as \code{integer}, silently overflow \item \code{"numeric"}: always return as \code{numeric}, silently round \item \code{"character"}: always return the decimal representation as \code{character} \item \code{"integer64"}: return as a data type that can be coerced using \code{\link[=as.integer]{as.integer()}} (with warning on overflow), \code{\link[=as.numeric]{as.numeric()}} and \code{\link[=as.character]{as.character()}} } } \examples{ # SQLite only needs a path to the database. (Here, ":memory:" is a special # path that creates an in-memory database.) Other database drivers # will require more details (like user, password, host, port, etc.) con <- dbConnect(RSQLite::SQLite(), ":memory:") con dbListTables(con) dbDisconnect(con) } \seealso{ \code{\link[=dbDisconnect]{dbDisconnect()}} to disconnect from a database. Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} Other DBIConnector generics: \code{\link{DBIConnector-class}}, \code{\link{dbDataType}()}, \code{\link{dbGetConnectArgs}()}, \code{\link{dbIsReadOnly}()} } \concept{DBIConnector generics} \concept{DBIDriver generics} DBI/man/rownames.Rd0000644000176200001440000000270013575062550013554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rownames.R \name{rownames} \alias{rownames} \alias{sqlRownamesToColumn} \alias{sqlColumnToRownames} \title{Convert row names back and forth between columns} \usage{ sqlRownamesToColumn(df, row.names = NA) sqlColumnToRownames(df, row.names = NA) } \arguments{ \item{df}{A data frame} \item{row.names}{Either \code{TRUE}, \code{FALSE}, \code{NA} or a string. If \code{TRUE}, always translate row names to a column called "row_names". If \code{FALSE}, never translate row names. If \code{NA}, translate rownames only if they're a character vector. A string is equivalent to \code{TRUE}, but allows you to override the default name. For backward compatibility, \code{NULL} is equivalent to \code{FALSE}.} } \description{ These functions provide a reasonably automatic way of preserving the row names of data frame during back-and-forth translation to an SQL table. By default, row names will be converted to an explicit column called "row_names", and any query returning a column called "row_names" will have those automatically set as row names. These methods are mostly useful for backend implementers. } \examples{ # If have row names sqlRownamesToColumn(head(mtcars)) sqlRownamesToColumn(head(mtcars), FALSE) sqlRownamesToColumn(head(mtcars), "ROWNAMES") # If don't have sqlRownamesToColumn(head(iris)) sqlRownamesToColumn(head(iris), TRUE) sqlRownamesToColumn(head(iris), "ROWNAMES") } DBI/man/DBIResult-class.Rd0000644000176200001440000000263213575266047014634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \docType{class} \name{DBIResult-class} \alias{DBIResult-class} \title{DBIResult class} \description{ This virtual class describes the result and state of execution of a DBMS statement (any statement, query or non-query). The result set keeps track of whether the statement produces output how many rows were affected by the operation, how many rows have been fetched (if statement is a query), whether there are more rows to fetch, etc. } \section{Implementation notes}{ Individual drivers are free to allow single or multiple active results per connection. The default show method displays a summary of the query using other DBI generics. } \seealso{ Other DBI classes: \code{\link{DBIConnection-class}}, \code{\link{DBIConnector-class}}, \code{\link{DBIDriver-class}}, \code{\link{DBIObject-class}} Other DBIResult generics: \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBI classes} \concept{DBIResult generics} DBI/man/dbExistsTable.Rd0000644000176200001440000000456513575266047014500 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbExistsTable} \alias{dbExistsTable} \title{Does a table exist?} \usage{ dbExistsTable(conn, name, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{A character string specifying a DBMS table name.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbExistsTable()} returns a logical scalar, \code{TRUE} if the table or view specified by the \code{name} argument exists, \code{FALSE} otherwise. This includes temporary tables if supported by the database. An error is raised when calling this method for a closed or invalid connection. An error is also raised if \code{name} cannot be processed with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} or if this results in a non-scalar. } \description{ Returns if a table given by name exists in the database. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbExistsTable")} } \section{Specification}{ The \code{name} argument is processed as follows, to support databases that allow non-syntactic names for their objects: \itemize{ \item If an unquoted table name as string: \code{dbExistsTable()} will do the quoting, perhaps by calling \code{dbQuoteIdentifier(conn, x = name)} \item If the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}: no more quoting is done } For all tables listed by \code{\link[=dbListTables]{dbListTables()}}, \code{dbExistsTable()} returns \code{TRUE}. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbExistsTable(con, "iris") dbWriteTable(con, "iris", iris) dbExistsTable(con, "iris") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/hidden_aliases.Rd0000644000176200001440000001324213575266242014664 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/hidden.R, R/DBObject.R, R/DBDriver.R, % R/table.R, R/DBConnection.R, R/ANSI.R, R/DBConnector.R, R/DBResult.R, % R/data.R, R/deprecated.R, R/interpolate.R, R/quote.R, R/table-create.R, % R/table-insert.R, R/transactions.R \docType{methods} \name{hidden_aliases} \alias{hidden_aliases} \alias{dbIsReadOnly,DBIObject-method} \alias{dbDriver,character-method} \alias{show,DBIDriver-method} \alias{dbCanConnect,DBIDriver-method} \alias{dbDataType,DBIObject-method} \alias{show,Id-method} \alias{show,DBIConnection-method} \alias{dbSendStatement,DBIConnection,character-method} \alias{dbGetQuery,DBIConnection,character-method} \alias{dbExecute,DBIConnection,character-method} \alias{dbListFields,DBIConnection,character-method} \alias{dbListFields,DBIConnection,Id-method} \alias{dbListObjects,DBIConnection-method} \alias{dbReadTable,DBIConnection,character-method} \alias{dbReadTable,DBIConnection,Id-method} \alias{dbWriteTable,DBIConnection,Id-method} \alias{dbExistsTable,DBIConnection,Id-method} \alias{dbRemoveTable,DBIConnection,Id-method} \alias{show,AnsiConnection-method} \alias{show,DBIConnector-method} \alias{dbConnect,DBIConnector-method} \alias{dbGetConnectArgs,DBIConnector-method} \alias{dbDataType,DBIConnector-method} \alias{dbIsReadOnly,DBIConnector-method} \alias{show,DBIResult-method} \alias{dbFetch,DBIResult-method} \alias{dbGetInfo,DBIResult-method} \alias{sqlData,DBIConnection-method} \alias{make.db.names,DBIObject,character-method} \alias{isSQLKeyword,DBIObject,character-method} \alias{SQLKeywords,DBIObject-method} \alias{SQLKeywords,missing-method} \alias{sqlInterpolate,DBIConnection-method} \alias{sqlParseVariables,DBIConnection-method} \alias{show,SQL-method} \alias{dbQuoteIdentifier,DBIConnection,ANY-method} \alias{dbQuoteIdentifier,DBIConnection,character-method} \alias{dbQuoteIdentifier,DBIConnection,SQL-method} \alias{dbQuoteIdentifier,DBIConnection,Id-method} \alias{dbUnquoteIdentifier,DBIConnection-method} \alias{dbQuoteString,DBIConnection,ANY-method} \alias{dbQuoteString,DBIConnection,character-method} \alias{dbQuoteString,DBIConnection,SQL-method} \alias{dbQuoteLiteral,DBIConnection-method} \alias{sqlCreateTable,DBIConnection-method} \alias{dbCreateTable,DBIConnection-method} \alias{sqlAppendTable,DBIConnection-method} \alias{dbAppendTable,DBIConnection-method} \alias{dbWithTransaction,DBIConnection-method} \title{Internal page for hidden aliases} \usage{ \S4method{dbIsReadOnly}{DBIObject}(dbObj, ...) \S4method{dbDriver}{character}(drvName, ...) \S4method{show}{DBIDriver}(object) \S4method{dbCanConnect}{DBIDriver}(drv, ...) \S4method{dbDataType}{DBIObject}(dbObj, obj, ...) \S4method{show}{Id}(object) \S4method{show}{DBIConnection}(object) \S4method{dbSendStatement}{DBIConnection,character}(conn, statement, ...) \S4method{dbGetQuery}{DBIConnection,character}(conn, statement, ..., n = -1L) \S4method{dbExecute}{DBIConnection,character}(conn, statement, ...) \S4method{dbListFields}{DBIConnection,character}(conn, name, ...) \S4method{dbListFields}{DBIConnection,Id}(conn, name, ...) \S4method{dbListObjects}{DBIConnection}(conn, prefix = NULL, ...) \S4method{dbReadTable}{DBIConnection,character}(conn, name, ..., row.names = FALSE, check.names = TRUE) \S4method{dbReadTable}{DBIConnection,Id}(conn, name, ...) \S4method{dbWriteTable}{DBIConnection,Id}(conn, name, value, ...) \S4method{dbExistsTable}{DBIConnection,Id}(conn, name, ...) \S4method{dbRemoveTable}{DBIConnection,Id}(conn, name, ...) \S4method{show}{AnsiConnection}(object) \S4method{show}{DBIConnector}(object) \S4method{dbConnect}{DBIConnector}(drv, ...) \S4method{dbGetConnectArgs}{DBIConnector}(drv, eval = TRUE, ...) \S4method{dbDataType}{DBIConnector}(dbObj, obj, ...) \S4method{dbIsReadOnly}{DBIConnector}(dbObj, ...) \S4method{show}{DBIResult}(object) \S4method{dbFetch}{DBIResult}(res, n = -1, ...) \S4method{dbGetInfo}{DBIResult}(dbObj, ...) \S4method{sqlData}{DBIConnection}(con, value, row.names = NA, ...) \S4method{make.db.names}{DBIObject,character}( dbObj, snames, keywords = .SQL92Keywords, unique = TRUE, allow.keywords = TRUE, ... ) \S4method{isSQLKeyword}{DBIObject,character}( dbObj, name, keywords = .SQL92Keywords, case = c("lower", "upper", "any")[3], ... ) \S4method{SQLKeywords}{DBIObject}(dbObj, ...) \S4method{SQLKeywords}{missing}(dbObj, ...) \S4method{sqlInterpolate}{DBIConnection}(conn, sql, ..., .dots = list()) \S4method{sqlParseVariables}{DBIConnection}(conn, sql, ...) \S4method{show}{SQL}(object) \S4method{dbQuoteIdentifier}{DBIConnection,ANY}(conn, x, ...) \S4method{dbQuoteIdentifier}{DBIConnection,character}(conn, x, ...) \S4method{dbQuoteIdentifier}{DBIConnection,SQL}(conn, x, ...) \S4method{dbQuoteIdentifier}{DBIConnection,Id}(conn, x, ...) \S4method{dbUnquoteIdentifier}{DBIConnection}(conn, x, ...) \S4method{dbQuoteString}{DBIConnection,ANY}(conn, x, ...) \S4method{dbQuoteString}{DBIConnection,character}(conn, x, ...) \S4method{dbQuoteString}{DBIConnection,SQL}(conn, x, ...) \S4method{dbQuoteLiteral}{DBIConnection}(conn, x, ...) \S4method{sqlCreateTable}{DBIConnection}(con, table, fields, row.names = NA, temporary = FALSE, ...) \S4method{dbCreateTable}{DBIConnection}(conn, name, fields, ..., row.names = NULL, temporary = FALSE) \S4method{sqlAppendTable}{DBIConnection}(con, table, values, row.names = NA, ...) \S4method{dbAppendTable}{DBIConnection}(conn, name, value, ..., row.names = NULL) \S4method{dbWithTransaction}{DBIConnection}(conn, code) } \arguments{ \item{object}{Object to display} \item{n}{Number of rows to fetch, default -1} } \description{ For S4 methods that require a documentation entry but only clutter the index. } \keyword{internal} DBI/man/make.db.names.Rd0000644000176200001440000000662713575266047014347 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.R \name{make.db.names} \alias{make.db.names} \alias{SQLKeywords} \alias{isSQLKeyword} \alias{make.db.names.default} \alias{isSQLKeyword.default} \title{Make R identifiers into legal SQL identifiers} \usage{ make.db.names( dbObj, snames, keywords = .SQL92Keywords, unique = TRUE, allow.keywords = TRUE, ... ) make.db.names.default( snames, keywords = .SQL92Keywords, unique = TRUE, allow.keywords = TRUE ) isSQLKeyword( dbObj, name, keywords = .SQL92Keywords, case = c("lower", "upper", "any")[3], ... ) isSQLKeyword.default( name, keywords = .SQL92Keywords, case = c("lower", "upper", "any")[3] ) } \arguments{ \item{dbObj}{any DBI object (e.g., \code{DBIDriver}).} \item{snames}{a character vector of R identifiers (symbols) from which we need to make SQL identifiers.} \item{keywords}{a character vector with SQL keywords, by default it's \code{.SQL92Keywords} defined by the DBI.} \item{unique}{logical describing whether the resulting set of SQL names should be unique. Its default is \code{TRUE}. Following the SQL 92 standard, uniqueness of SQL identifiers is determined regardless of whether letters are upper or lower case.} \item{allow.keywords}{logical describing whether SQL keywords should be allowed in the resulting set of SQL names. Its default is \code{TRUE}} \item{\dots}{any other argument are passed to the driver implementation.} \item{name}{a character vector with database identifier candidates we need to determine whether they are legal SQL identifiers or not.} \item{case}{a character string specifying whether to make the comparison as lower case, upper case, or any of the two. it defaults to \code{any}.} } \value{ \code{make.db.names} returns a character vector of legal SQL identifiers corresponding to its \code{snames} argument. \code{SQLKeywords} returns a character vector of all known keywords for the database-engine associated with \code{dbObj}. \code{isSQLKeyword} returns a logical vector parallel to \code{name}. } \description{ These methods are DEPRECATED. Please use \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} (or possibly \code{\link[=dbQuoteString]{dbQuoteString()}}) instead. } \details{ The algorithm in \code{make.db.names} first invokes \code{make.names} and then replaces each occurrence of a dot \code{.} by an underscore \verb{_}. If \code{allow.keywords} is \code{FALSE} and identifiers collide with SQL keywords, a small integer is appended to the identifier in the form of \code{"_n"}. The set of SQL keywords is stored in the character vector \code{.SQL92Keywords} and reflects the SQL ANSI/ISO standard as documented in "X/Open SQL and RDA", 1994, ISBN 1-872630-68-8. Users can easily override or update this vector. } \section{Bugs}{ The current mapping is not guaranteed to be fully reversible: some SQL identifiers that get mapped into R identifiers with \code{make.names} and then back to SQL with \code{\link[=make.db.names]{make.db.names()}} will not be equal to the original SQL identifiers (e.g., compound SQL identifiers of the form \code{username.tablename} will loose the dot ``.''). } \references{ The set of SQL keywords is stored in the character vector \code{.SQL92Keywords} and reflects the SQL ANSI/ISO standard as documented in "X/Open SQL and RDA", 1994, ISBN 1-872630-68-8. Users can easily override or update this vector. } \keyword{internal} DBI/man/dbGetRowsAffected.Rd0000644000176200001440000000351213575266047015254 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbGetRowsAffected} \alias{dbGetRowsAffected} \title{The number of rows affected} \usage{ dbGetRowsAffected(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbGetRowsAffected()} returns a scalar number (integer or numeric), the number of rows affected by a data manipulation statement issued with \code{\link[=dbSendStatement]{dbSendStatement()}}. The value is available directly after the call and does not change after calling \code{\link[=dbFetch]{dbFetch()}}. For queries issued with \code{\link[=dbSendQuery]{dbSendQuery()}}, zero is returned before and after the call to \code{dbFetch()}. Attempting to get the rows affected for a result set cleared with \code{\link[=dbClearResult]{dbClearResult()}} gives an error. } \description{ This method returns the number of rows that were added, deleted, or updated by a data manipulation statement. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbGetRowsAffected")} } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) rs <- dbSendStatement(con, "DELETE FROM mtcars") dbGetRowsAffected(rs) nrow(mtcars) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbListObjects.Rd0000644000176200001440000001006213575266047014463 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbListObjects} \alias{dbListObjects} \title{List remote objects} \usage{ dbListObjects(conn, prefix = NULL, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{prefix}{A fully qualified path in the database's namespace, or \code{NULL}. This argument will be processed with \code{\link[=dbUnquoteIdentifier]{dbUnquoteIdentifier()}}. If given the method will return all objects accessible through this prefix.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbListObjects()} returns a data frame with columns \code{table} and \code{is_prefix} (in that order), optionally with other columns with a dot (\code{.}) prefix. The \code{table} column is of type list. Each object in this list is suitable for use as argument in \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}. The \code{is_prefix} column is a logical. This data frame contains one row for each object (schema, table and view) accessible from the prefix (if passed) or from the global namespace (if prefix is omitted). Tables added with \code{\link[=dbWriteTable]{dbWriteTable()}} are part of the data frame, including temporary objects if supported by the database. As soon a table is removed from the database, it is also removed from the data frame of database objects. The returned names are suitable for quoting with \code{dbQuoteIdentifier()}. An error is raised when calling this method for a closed or invalid connection. } \description{ Returns the names of remote objects accessible through this connection as a data frame. This should include temporary objects, but not all database backends (in particular \pkg{RMariaDB} and \pkg{RMySQL}) support this. Compared to \code{\link[=dbListTables]{dbListTables()}}, this method also enumerates tables and views in schemas, and returns fully qualified identifiers to access these objects. This allows exploration of all database objects available to the current user, including those that can only be accessed by giving the full namespace. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbListObjects")} } \section{Specification}{ The \code{table} object can be quoted with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}. The result of quoting can be passed to \code{\link[=dbUnquoteIdentifier]{dbUnquoteIdentifier()}}. The unquoted results are equal to the original \code{table} object. (For backends it may be convenient to use the \link{Id} class, but this is not required.) The \code{prefix} column indicates if the \code{table} value refers to a table or a prefix. For a call with the default \code{prefix = NULL}, the \code{table} values that have \code{is_prefix == FALSE} correspond to the tables returned from \code{\link[=dbListTables]{dbListTables()}}, Values in \code{table} column that have \code{is_prefix == TRUE} can be passed as the \code{prefix} argument to another call to \code{dbListObjects()}. For the data frame returned from a \code{dbListObject()} call with the \code{prefix} argument set, all \code{table} values where \code{is_prefix} is \code{FALSE} can be used in a call to \code{\link[=dbExistsTable]{dbExistsTable()}} which returns \code{TRUE}. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbListObjects(con) dbWriteTable(con, "mtcars", mtcars) dbListObjects(con) dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbListFields.Rd0000644000176200001440000000441713575266047014307 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbListFields} \alias{dbListFields} \title{List field names of a remote table} \usage{ dbListFields(conn, name, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{a character string with the name of the remote table.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbListFields()} returns a character vector that enumerates all fields in the table in the correct order. This also works for temporary tables if supported by the database. The returned names are suitable for quoting with \code{dbQuoteIdentifier()}. If the table does not exist, an error is raised. Invalid types for the \code{name} argument (e.g., \code{character} of length not equal to one, or numeric) lead to an error. An error is also raised when calling this method for a closed or invalid connection. } \description{ List field names of a remote table } \section{Specification}{ The \code{name} argument can be \itemize{ \item a string \item the return value of \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} \item a value from the \code{table} column from the return value of \code{\link[=dbListObjects]{dbListObjects()}} where \code{is_prefix} is \code{FALSE} } A column named \code{row_names} is treated like any other column. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) dbListFields(con, "mtcars") dbDisconnect(con) } \seealso{ \code{\link[=dbColumnInfo]{dbColumnInfo()}} to get the type of the fields. Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbDataType.Rd0000644000176200001440000001105213575266047013751 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \name{dbDataType} \alias{dbDataType} \title{Determine the SQL data type of an object} \usage{ dbDataType(dbObj, obj, ...) } \arguments{ \item{dbObj}{A object inheriting from \linkS4class{DBIDriver} or \linkS4class{DBIConnection}} \item{obj}{An R object whose SQL type we want to determine.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbDataType()} returns the SQL type that corresponds to the \code{obj} argument as a non-empty character string. For data frames, a character vector with one element per column is returned. An error is raised for invalid values for the \code{obj} argument such as a \code{NULL} value. } \description{ Returns an SQL string that describes the SQL data type to be used for an object. The default implementation of this generic determines the SQL type of an R object according to the SQL 92 specification, which may serve as a starting point for driver implementations. DBI also provides an implementation for data.frame which will return a character vector giving the type for each column in the dataframe. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbDataType")} } \details{ The data types supported by databases are different than the data types in R, but the mapping between the primitive types is straightforward: \itemize{ \item Any of the many fixed and varying length character types are mapped to character vectors \item Fixed-precision (non-IEEE) numbers are mapped into either numeric or integer vectors. } Notice that many DBMS do not follow IEEE arithmetic, so there are potential problems with under/overflows and loss of precision. } \section{Specification}{ The backend can override the \code{\link[=dbDataType]{dbDataType()}} generic for its driver class. This generic expects an arbitrary object as second argument. To query the values returned by the default implementation, run \code{example(dbDataType, package = "DBI")}. If the backend needs to override this generic, it must accept all basic R data types as its second argument, namely \link{logical}, \link{integer}, \link{numeric}, \link{character}, dates (see \link{Dates}), date-time (see \link{DateTimeClasses}), and \link{difftime}. If the database supports blobs, this method also must accept lists of \link{raw} vectors, and \link[blob:blob]{blob::blob} objects. As-is objects (i.e., wrapped by \code{\link[=I]{I()}}) must be supported and return the same results as their unwrapped counterparts. The SQL data type for \link{factor} and \link{ordered} is the same as for character. The behavior for other object types is not specified. All data types returned by \code{dbDataType()} are usable in an SQL statement of the form \code{"CREATE TABLE test (a ...)"}. } \examples{ dbDataType(ANSI(), 1:5) dbDataType(ANSI(), 1) dbDataType(ANSI(), TRUE) dbDataType(ANSI(), Sys.Date()) dbDataType(ANSI(), Sys.time()) dbDataType(ANSI(), Sys.time() - as.POSIXct(Sys.Date())) dbDataType(ANSI(), c("x", "abc")) dbDataType(ANSI(), list(raw(10), raw(20))) dbDataType(ANSI(), I(3)) dbDataType(ANSI(), iris) con <- dbConnect(RSQLite::SQLite(), ":memory:") dbDataType(con, 1:5) dbDataType(con, 1) dbDataType(con, TRUE) dbDataType(con, Sys.Date()) dbDataType(con, Sys.time()) dbDataType(con, Sys.time() - as.POSIXct(Sys.Date())) dbDataType(con, c("x", "abc")) dbDataType(con, list(raw(10), raw(20))) dbDataType(con, I(3)) dbDataType(con, iris) dbDisconnect(con) } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} Other DBIConnector generics: \code{\link{DBIConnector-class}}, \code{\link{dbConnect}()}, \code{\link{dbGetConnectArgs}()}, \code{\link{dbIsReadOnly}()} } \concept{DBIConnection generics} \concept{DBIConnector generics} \concept{DBIDriver generics} DBI/man/dbRemoveTable.Rd0000644000176200001440000000654013575266047014451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbRemoveTable} \alias{dbRemoveTable} \title{Remove a table from the database} \usage{ dbRemoveTable(conn, name, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{A character string specifying a DBMS table name.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbRemoveTable()} returns \code{TRUE}, invisibly. If the table does not exist, an error is raised. An attempt to remove a view with this function may result in an error. An error is raised when calling this method for a closed or invalid connection. An error is also raised if \code{name} cannot be processed with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} or if this results in a non-scalar. } \description{ Remove a remote table (e.g., created by \code{\link[=dbWriteTable]{dbWriteTable()}}) from the database. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbRemoveTable")} } \section{Additional arguments}{ The following arguments are not part of the \code{dbRemoveTable()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{temporary} (default: \code{FALSE}) \item \code{fail_if_missing} (default: \code{TRUE}) } These arguments must be provided as named arguments. If \code{temporary} is \code{TRUE}, the call to \code{dbRemoveTable()} will consider only temporary tables. Not all backends support this argument. In particular, permanent tables of the same name are left untouched. If \code{fail_if_missing} is \code{FALSE}, the call to \code{dbRemoveTable()} succeeds if the table does not exist. } \section{Specification}{ A table removed by \code{dbRemoveTable()} doesn't appear in the list of tables returned by \code{\link[=dbListTables]{dbListTables()}}, and \code{\link[=dbExistsTable]{dbExistsTable()}} returns \code{FALSE}. The removal propagates immediately to other connections to the same database. This function can also be used to remove a temporary table. The \code{name} argument is processed as follows, to support databases that allow non-syntactic names for their objects: \itemize{ \item If an unquoted table name as string: \code{dbRemoveTable()} will do the quoting, perhaps by calling \code{dbQuoteIdentifier(conn, x = name)} \item If the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}: no more quoting is done } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbExistsTable(con, "iris") dbWriteTable(con, "iris", iris) dbExistsTable(con, "iris") dbRemoveTable(con, "iris") dbExistsTable(con, "iris") dbDisconnect(con) } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/dbBind.Rd0000644000176200001440000001672613575266047013127 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbBind} \alias{dbBind} \title{Bind values to a parameterized/prepared statement} \usage{ dbBind(res, params, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{params}{A list of bindings, named or unnamed.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbBind()} returns the result set, invisibly, for queries issued by \code{\link[=dbSendQuery]{dbSendQuery()}} and also for data manipulation statements issued by \code{\link[=dbSendStatement]{dbSendStatement()}}. Calling \code{dbBind()} for a query without parameters raises an error. Binding too many or not enough values, or parameters with wrong names or unequal length, also raises an error. If the placeholders in the query are named, all parameter values must have names (which must not be empty or \code{NA}), and vice versa, otherwise an error is raised. The behavior for mixing placeholders of different types (in particular mixing positional and named placeholders) is not specified. Calling \code{dbBind()} on a result set already cleared by \code{\link[=dbClearResult]{dbClearResult()}} also raises an error. } \description{ For parametrized or prepared statements, the \code{\link[=dbSendQuery]{dbSendQuery()}} and \code{\link[=dbSendStatement]{dbSendStatement()}} functions can be called with statements that contain placeholders for values. The \code{dbBind()} function binds these placeholders to actual values, and is intended to be called on the result set before calling \code{\link[=dbFetch]{dbFetch()}} or \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbBind")} } \details{ \pkg{DBI} supports parametrized (or prepared) queries and statements via the \code{dbBind()} generic. Parametrized queries are different from normal queries in that they allow an arbitrary number of placeholders, which are later substituted by actual values. Parametrized queries (and statements) serve two purposes: \itemize{ \item The same query can be executed more than once with different values. The DBMS may cache intermediate information for the query, such as the execution plan, and execute it faster. \item Separation of query syntax and parameters protects against SQL injection. } The placeholder format is currently not specified by \pkg{DBI}; in the future, a uniform placeholder syntax may be supported. Consult the backend documentation for the supported formats. For automated testing, backend authors specify the placeholder syntax with the \code{placeholder_pattern} tweak. Known examples are: \itemize{ \item \verb{?} (positional matching in order of appearance) in \pkg{RMySQL} and \pkg{RSQLite} \item \verb{$1} (positional matching by index) in \pkg{RPostgres} and \pkg{RSQLite} \item \verb{:name} and \verb{$name} (named matching) in \pkg{RSQLite} } } \section{Specification}{ \pkg{DBI} clients execute parametrized statements as follows: \enumerate{ \item Call \code{\link[=dbSendQuery]{dbSendQuery()}} or \code{\link[=dbSendStatement]{dbSendStatement()}} with a query or statement that contains placeholders, store the returned \linkS4class{DBIResult} object in a variable. Mixing placeholders (in particular, named and unnamed ones) is not recommended. It is good practice to register a call to \code{\link[=dbClearResult]{dbClearResult()}} via \code{\link[=on.exit]{on.exit()}} right after calling \code{dbSendQuery()} or \code{dbSendStatement()} (see the last enumeration item). Until \code{dbBind()} has been called, the returned result set object has the following behavior: \itemize{ \item \code{\link[=dbFetch]{dbFetch()}} raises an error (for \code{dbSendQuery()}) \item \code{\link[=dbGetRowCount]{dbGetRowCount()}} returns zero (for \code{dbSendQuery()}) \item \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}} returns an integer \code{NA} (for \code{dbSendStatement()}) \item \code{\link[=dbIsValid]{dbIsValid()}} returns \code{TRUE} \item \code{\link[=dbHasCompleted]{dbHasCompleted()}} returns \code{FALSE} } \item Construct a list with parameters that specify actual values for the placeholders. The list must be named or unnamed, depending on the kind of placeholders used. Named values are matched to named parameters, unnamed values are matched by position in the list of parameters. All elements in this list must have the same lengths and contain values supported by the backend; a \link{data.frame} is internally stored as such a list. The parameter list is passed to a call to \code{dbBind()} on the \code{DBIResult} object. \item Retrieve the data or the number of affected rows from the \code{DBIResult} object. \itemize{ \item For queries issued by \code{dbSendQuery()}, call \code{\link[=dbFetch]{dbFetch()}}. \item For statements issued by \code{dbSendStatements()}, call \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}}. (Execution begins immediately after the \code{dbBind()} call, the statement is processed entirely before the function returns.) } \item Repeat 2. and 3. as necessary. \item Close the result set via \code{\link[=dbClearResult]{dbClearResult()}}. } The elements of the \code{params} argument do not need to be scalars, vectors of arbitrary length (including length 0) are supported. For queries, calling \code{dbFetch()} binding such parameters returns concatenated results, equivalent to binding and fetching for each set of values and connecting via \code{\link[=rbind]{rbind()}}. For data manipulation statements, \code{dbGetRowsAffected()} returns the total number of rows affected if binding non-scalar parameters. \code{dbBind()} also accepts repeated calls on the same result set for both queries and data manipulation statements, even if no results are fetched between calls to \code{dbBind()}. If the placeholders in the query are named, their order in the \code{params} argument is not important. At least the following data types are accepted on input (including \link{NA}): \itemize{ \item \link{integer} \item \link{numeric} \item \link{logical} for Boolean values \item \link{character} \item \link{factor} (bound as character, with warning) \item \link{Date} \item \link{POSIXct} timestamps \item \link{POSIXlt} timestamps \item lists of \link{raw} for blobs (with \code{NULL} entries for SQL NULL values) \item objects of type \link[blob:blob]{blob::blob} } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "iris", iris) # Using the same query for different values iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > ?") dbBind(iris_result, list(2.3)) dbFetch(iris_result) dbBind(iris_result, list(3)) dbFetch(iris_result) dbClearResult(iris_result) # Executing the same statement with different values at once iris_result <- dbSendStatement(con, "DELETE FROM iris WHERE [Species] = $species") dbBind(iris_result, list(species = c("setosa", "versicolor", "unknown"))) dbGetRowsAffected(iris_result) dbClearResult(iris_result) nrow(dbReadTable(con, "iris")) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbGetConnectArgs.Rd0000644000176200001440000000226113575266047015106 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnector.R \name{dbGetConnectArgs} \alias{dbGetConnectArgs} \title{Get connection arguments} \usage{ dbGetConnectArgs(drv, eval = TRUE, ...) } \arguments{ \item{drv}{A object inheriting from \linkS4class{DBIConnector}.} \item{eval}{Set to \code{FALSE} to return the functions that generate the argument instead of evaluating them.} \item{...}{Other arguments passed on to methods. Not otherwise used.} } \description{ Returns the arguments stored in a \linkS4class{DBIConnector} object for inspection, optionally evaluating them. This function is called by \code{\link[=dbConnect]{dbConnect()}} and usually does not need to be called directly. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbGetConnectArgs")} } \examples{ cnr <- new("DBIConnector", .drv = RSQLite::SQLite(), .conn_args = list(dbname = ":memory:", password = function() "supersecret") ) dbGetConnectArgs(cnr) dbGetConnectArgs(cnr, eval = FALSE) } \seealso{ Other DBIConnector generics: \code{\link{DBIConnector-class}}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbIsReadOnly}()} } \concept{DBIConnector generics} DBI/man/DBIConnection-class.Rd0000644000176200001440000000275313575266047015461 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \docType{class} \name{DBIConnection-class} \alias{DBIConnection-class} \title{DBIConnection class} \description{ This virtual class encapsulates the connection to a DBMS, and it provides access to dynamic queries, result sets, DBMS session management (transactions), etc. } \section{Implementation note}{ Individual drivers are free to implement single or multiple simultaneous connections. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") con dbDisconnect(con) \dontrun{ con <- dbConnect(RPostgreSQL::PostgreSQL(), "username", "passsword") con dbDisconnect(con) } } \seealso{ Other DBI classes: \code{\link{DBIConnector-class}}, \code{\link{DBIDriver-class}}, \code{\link{DBIObject-class}}, \code{\link{DBIResult-class}} Other DBIConnection generics: \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBI classes} \concept{DBIConnection generics} DBI/man/dbFetch.Rd0000644000176200001440000001305513575266047013274 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbFetch} \alias{dbFetch} \alias{fetch} \title{Fetch records from a previously executed query} \usage{ dbFetch(res, n = -1, ...) fetch(res, n = -1, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}, created by \code{\link[=dbSendQuery]{dbSendQuery()}}.} \item{n}{maximum number of records to retrieve per fetch. Use \code{n = -1} or \code{n = Inf} to retrieve all pending records. Some implementations may recognize other special values.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbFetch()} always returns a \link{data.frame} with as many rows as records were fetched and as many columns as fields in the result set, even if the result is a single value or has one or zero rows. An attempt to fetch from a closed result set raises an error. If the \code{n} argument is not an atomic whole number greater or equal to -1 or Inf, an error is raised, but a subsequent call to \code{dbFetch()} with proper \code{n} argument succeeds. Calling \code{dbFetch()} on a result set from a data manipulation query created by \code{\link[=dbSendStatement]{dbSendStatement()}} can be fetched and return an empty data frame, with a warning. } \description{ Fetch the next \code{n} elements (rows) from the result set and return them as a data.frame. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbFetch")} } \details{ \code{fetch()} is provided for compatibility with older DBI clients - for all new code you are strongly encouraged to use \code{dbFetch()}. The default implementation for \code{dbFetch()} calls \code{fetch()} so that it is compatible with existing code. Modern backends should implement for \code{dbFetch()} only. } \section{Specification}{ Fetching multi-row queries with one or more columns by default returns the entire result. Multi-row queries can also be fetched progressively by passing a whole number (\link{integer} or \link{numeric}) as the \code{n} argument. A value of \link{Inf} for the \code{n} argument is supported and also returns the full result. If more rows than available are fetched, the result is returned in full without warning. If fewer rows than requested are returned, further fetches will return a data frame with zero rows. If zero rows are fetched, the columns of the data frame are still fully typed. Fetching fewer rows than available is permitted, no warning is issued when clearing the result set. A column named \code{row_names} is treated like any other column. The column types of the returned data frame depend on the data returned: \itemize{ \item \link{integer} (or coercible to an integer) for integer values between -2^31 and 2^31 - 1, with \link{NA} for SQL \code{NULL} values \item \link{numeric} for numbers with a fractional component, with NA for SQL \code{NULL} values \item \link{logical} for Boolean values (some backends may return an integer); with NA for SQL \code{NULL} values \item \link{character} for text, with NA for SQL \code{NULL} values \item lists of \link{raw} for blobs with \link{NULL} entries for SQL NULL values \item coercible using \code{\link[=as.Date]{as.Date()}} for dates, with NA for SQL \code{NULL} values (also applies to the return value of the SQL function \code{current_date}) \item coercible using \code{\link[hms:as_hms]{hms::as_hms()}} for times, with NA for SQL \code{NULL} values (also applies to the return value of the SQL function \code{current_time}) \item coercible using \code{\link[=as.POSIXct]{as.POSIXct()}} for timestamps, with NA for SQL \code{NULL} values (also applies to the return value of the SQL function \code{current_timestamp}) } If dates and timestamps are supported by the backend, the following R types are used: \itemize{ \item \link{Date} for dates (also applies to the return value of the SQL function \code{current_date}) \item \link{POSIXct} for timestamps (also applies to the return value of the SQL function \code{current_timestamp}) } R has no built-in type with lossless support for the full range of 64-bit or larger integers. If 64-bit integers are returned from a query, the following rules apply: \itemize{ \item Values are returned in a container with support for the full range of valid 64-bit values (such as the \code{integer64} class of the \pkg{bit64} package) \item Coercion to numeric always returns a number that is as close as possible to the true value \item Loss of precision when converting to numeric gives a warning \item Conversion to character always returns a lossless decimal representation of the data } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) # Fetch all results rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") dbFetch(rs) dbClearResult(rs) # Fetch in chunks rs <- dbSendQuery(con, "SELECT * FROM mtcars") while (!dbHasCompleted(rs)) { chunk <- dbFetch(rs, 10) print(nrow(chunk)) } dbClearResult(rs) dbDisconnect(con) } \seealso{ Close the result set with \code{\link[=dbClearResult]{dbClearResult()}} as soon as you finish retrieving the records you want. Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbSendStatement.Rd0000644000176200001440000001401313575266047015014 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbSendStatement} \alias{dbSendStatement} \title{Execute a data manipulation statement on a given database connection} \usage{ dbSendStatement(conn, statement, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{statement}{a character string containing SQL.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbSendStatement()} returns an S4 object that inherits from \linkS4class{DBIResult}. The result set can be used with \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}} to determine the number of rows affected by the query. Once you have finished using a result, make sure to clear it with \code{\link[=dbClearResult]{dbClearResult()}}. An error is raised when issuing a statement over a closed or invalid connection, or if the statement is not a non-\code{NA} string. An error is also raised if the syntax of the query is invalid and all query parameters are given (by passing the \code{params} argument) or the \code{immediate} argument is set to \code{TRUE}. } \description{ The \code{dbSendStatement()} method only submits and synchronously executes the SQL data manipulation statement (e.g., \code{UPDATE}, \code{DELETE}, \verb{INSERT INTO}, \verb{DROP TABLE}, ...) to the database engine. To query the number of affected rows, call \code{\link[=dbGetRowsAffected]{dbGetRowsAffected()}} on the returned result object. You must also call \code{\link[=dbClearResult]{dbClearResult()}} after that. For interactive use, you should almost always prefer \code{\link[=dbExecute]{dbExecute()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbSendStatement")} } \details{ \code{\link[=dbSendStatement]{dbSendStatement()}} comes with a default implementation that simply forwards to \code{\link[=dbSendQuery]{dbSendQuery()}}, to support backends that only implement the latter. } \section{Additional arguments}{ The following arguments are not part of the \code{dbSendStatement()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{params} (default: \code{NULL}) \item \code{immediate} (default: \code{NULL}) } They must be provided as named arguments. See the "Specification" sections for details on their usage. } \section{Specification}{ No warnings occur under normal conditions. When done, the DBIResult object must be cleared with a call to \code{\link[=dbClearResult]{dbClearResult()}}. Failure to clear the result set leads to a warning when the connection is closed. If the backend supports only one open result set per connection, issuing a second query invalidates an already open result set and raises a warning. The newly opened result set is valid and must be cleared with \code{dbClearResult()}. The \code{param} argument allows passing query parameters, see \code{\link[=dbBind]{dbBind()}} for details. } \section{Specification for the \code{immediate} argument}{ The \code{immediate} argument supports distinguishing between "direct" and "prepared" APIs offered by many database drivers. Passing \code{immediate = TRUE} leads to immediate execution of the query or statement, via the "direct" API (if supported by the driver). The default \code{NULL} means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct \code{immediate} argument. Examples for possible behaviors: \enumerate{ \item DBI backend defaults to \code{immediate = TRUE} internally \enumerate{ \item A query without parameters is passed: query is executed \item A query with parameters is passed: \enumerate{ \item \code{params} not given: rejected immediately by the database because of a syntax error in the query, the backend tries \code{immediate = FALSE} (and gives a message) \item \code{params} given: query is executed using \code{immediate = FALSE} } } \item DBI backend defaults to \code{immediate = FALSE} internally \enumerate{ \item A query without parameters is passed: \enumerate{ \item simple query: query is executed \item "special" query (such as setting a config options): fails, the backend tries \code{immediate = TRUE} (and gives a message) } \item A query with parameters is passed: \enumerate{ \item \code{params} not given: waiting for parameters via \code{\link[=dbBind]{dbBind()}} \item \code{params} given: query is executed } } } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "cars", head(cars, 3)) rs <- dbSendStatement( con, "INSERT INTO cars (speed, dist) VALUES (1, 1), (2, 2), (3, 3)" ) dbHasCompleted(rs) dbGetRowsAffected(rs) dbClearResult(rs) dbReadTable(con, "cars") # there are now 6 rows # Pass one set of values directly using the param argument: rs <- dbSendStatement( con, "INSERT INTO cars (speed, dist) VALUES (?, ?)", params = list(4L, 5L) ) dbClearResult(rs) # Pass multiple sets of values using dbBind(): rs <- dbSendStatement( con, "INSERT INTO cars (speed, dist) VALUES (?, ?)" ) dbBind(rs, list(5:6, 6:7)) dbBind(rs, list(7L, 8L)) dbClearResult(rs) dbReadTable(con, "cars") # there are now 10 rows dbDisconnect(con) } \seealso{ For queries: \code{\link[=dbSendQuery]{dbSendQuery()}} and \code{\link[=dbGetQuery]{dbGetQuery()}}. Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/transactions.Rd0000644000176200001440000000731013575100404014422 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/transactions.R \name{transactions} \alias{transactions} \alias{dbBegin} \alias{dbCommit} \alias{dbRollback} \title{Begin/commit/rollback SQL transactions} \usage{ dbBegin(conn, ...) dbCommit(conn, ...) dbRollback(conn, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbBegin()}, \code{dbCommit()} and \code{dbRollback()} return \code{TRUE}, invisibly. The implementations are expected to raise an error in case of failure, but this is not tested. In any way, all generics throw an error with a closed or invalid connection. In addition, a call to \code{dbCommit()} or \code{dbRollback()} without a prior call to \code{dbBegin()} raises an error. Nested transactions are not supported by DBI, an attempt to call \code{dbBegin()} twice yields an error. } \description{ A transaction encapsulates several SQL statements in an atomic unit. It is initiated with \code{dbBegin()} and either made persistent with \code{dbCommit()} or undone with \code{dbRollback()}. In any case, the DBMS guarantees that either all or none of the statements have a permanent effect. This helps ensuring consistency of write operations to multiple tables. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("transactions")} } \details{ Not all database engines implement transaction management, in which case these methods should not be implemented for the specific \linkS4class{DBIConnection} subclass. } \section{Specification}{ Actual support for transactions may vary between backends. A transaction is initiated by a call to \code{dbBegin()} and committed by a call to \code{dbCommit()}. Data written in a transaction must persist after the transaction is committed. For example, a record that is missing when the transaction is started but is created during the transaction must exist both during and after the transaction, and also in a new connection. A transaction can also be aborted with \code{dbRollback()}. All data written in such a transaction must be removed after the transaction is rolled back. For example, a record that is missing when the transaction is started but is created during the transaction must not exist anymore after the rollback. Disconnection from a connection with an open transaction effectively rolls back the transaction. All data written in such a transaction must be removed after the transaction is rolled back. The behavior is not specified if other arguments are passed to these functions. In particular, \pkg{RSQLite} issues named transactions with support for nesting if the \code{name} argument is set. The transaction isolation level is not specified by DBI. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "cash", data.frame(amount = 100)) dbWriteTable(con, "account", data.frame(amount = 2000)) # All operations are carried out as logical unit: dbBegin(con) withdrawal <- 300 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) dbCommit(con) dbReadTable(con, "cash") dbReadTable(con, "account") # Rolling back after detecting negative value on account: dbBegin(con) withdrawal <- 5000 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) if (dbReadTable(con, "account")$amount >= 0) { dbCommit(con) } else { dbRollback(con) } dbReadTable(con, "cash") dbReadTable(con, "account") dbDisconnect(con) } \seealso{ Self-contained transactions: \code{\link[=dbWithTransaction]{dbWithTransaction()}} } DBI/man/dbUnquoteIdentifier.Rd0000644000176200001440000000642313575266047015707 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.R \name{dbUnquoteIdentifier} \alias{dbUnquoteIdentifier} \title{Unquote identifiers} \usage{ dbUnquoteIdentifier(conn, x, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{x}{An \link{SQL} or \link{Id} object.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbUnquoteIdentifier()} returns a list of objects of the same length as the input. For an empty character vector this function returns a length-0 object. The names of the input argument are preserved in the output. When passing the first element of a returned object again to \code{dbUnquoteIdentifier()} as \code{x} argument, it is returned unchanged (but wrapped in a list). Passing objects of class \link{Id} should also return them unchanged (but wrapped in a list). (For backends it may be most convenient to return \link{Id} objects to achieve this behavior, but this is not required.) An error is raised if plain character vectors are passed as the \code{x} argument. } \description{ Call this method to convert a \link{SQL} object created by \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} back to a list of \link{Id} objects. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbUnquoteIdentifier")} } \section{Specification}{ For any character vector of length one, quoting (with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}) then unquoting then quoting the first element is identical to just quoting. This is also true for strings that contain special characters such as a space, a dot, a comma, or quotes used to mark strings or identifiers, if the database supports this. Unquoting simple strings (consisting of only letters) wrapped with \code{\link[=SQL]{SQL()}} and then quoting via \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} gives the same result as just quoting the string. Similarly, unquoting expressions of the form \code{SQL("schema.table")} and then quoting gives the same result as quoting the identifier constructed by \code{Id(schema = "schema", table = "table")}. } \examples{ # Unquoting allows to understand the structure of a # possibly complex quoted identifier dbUnquoteIdentifier( ANSI(), SQL(c('"Catalog"."Schema"."Table"', '"Schema"."Table"', '"UnqualifiedTable"')) ) # The returned object is always a list, # also for Id objects dbUnquoteIdentifier( ANSI(), Id(catalog = "Catalog", schema = "Schema", table = "Table") ) # Quoting is the inverse operation to unquoting the elements # of the returned list dbQuoteIdentifier( ANSI(), dbUnquoteIdentifier(ANSI(), SQL("UnqualifiedTable"))[[1]] ) dbQuoteIdentifier( ANSI(), dbUnquoteIdentifier(ANSI(), Id(schema = "Schema", table = "Table"))[[1]] ) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()} } \concept{DBIResult generics} DBI/man/dbListConnections.Rd0000644000176200001440000000146613575266047015364 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \name{dbListConnections} \alias{dbListConnections} \title{List currently open connections} \usage{ dbListConnections(drv, ...) } \arguments{ \item{drv}{A object inheriting from \linkS4class{DBIDriver}} \item{...}{Other arguments passed on to methods.} } \value{ a list } \description{ DEPRECATED, drivers are no longer required to implement this method. Keep track of the connections you opened if you require a list. } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()} } \concept{DBIDriver generics} \keyword{internal} DBI/man/dbHasCompleted.Rd0000644000176200001440000000462613575266047014617 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBResult.R \name{dbHasCompleted} \alias{dbHasCompleted} \title{Completion status} \usage{ dbHasCompleted(res, ...) } \arguments{ \item{res}{An object inheriting from \linkS4class{DBIResult}.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbHasCompleted()} returns a logical scalar. For a query initiated by \code{\link[=dbSendQuery]{dbSendQuery()}} with non-empty result set, \code{dbHasCompleted()} returns \code{FALSE} initially and \code{TRUE} after calling \code{\link[=dbFetch]{dbFetch()}} without limit. For a query initiated by \code{\link[=dbSendStatement]{dbSendStatement()}}, \code{dbHasCompleted()} always returns \code{TRUE}. Attempting to query completion status for a result set cleared with \code{\link[=dbClearResult]{dbClearResult()}} gives an error. } \description{ This method returns if the operation has completed. A \code{SELECT} query is completed if all rows have been fetched. A data manipulation statement is always completed. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbHasCompleted")} } \section{Specification}{ The completion status for a query is only guaranteed to be set to \code{FALSE} after attempting to fetch past the end of the entire result. Therefore, for a query with an empty result set, the initial return value is unspecified, but the result value is \code{TRUE} after trying to fetch only one row. Similarly, for a query with a result set of length n, the return value is unspecified after fetching n rows, but the result value is \code{TRUE} after trying to fetch only one more row. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) rs <- dbSendQuery(con, "SELECT * FROM mtcars") dbHasCompleted(rs) ret1 <- dbFetch(rs, 10) dbHasCompleted(rs) ret2 <- dbFetch(rs) dbHasCompleted(rs) dbClearResult(rs) dbDisconnect(con) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbGetDBIVersion.Rd0000644000176200001440000000045513054310030014615 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.R \name{dbGetDBIVersion} \alias{dbGetDBIVersion} \title{Determine the current version of the package.} \usage{ dbGetDBIVersion() } \description{ Determine the current version of the package. } \keyword{internal} DBI/man/DBIConnector-class.Rd0000644000176200001440000000273413575266047015313 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnector.R \docType{class} \name{DBIConnector-class} \alias{DBIConnector-class} \title{DBIConnector class} \description{ Wraps objects of the \linkS4class{DBIDriver} class to include connection options. The purpose of this class is to store both the driver and the connection options. A database connection can be established with a call to \code{\link[=dbConnect]{dbConnect()}}, passing only that object without additional arguments. } \details{ To prevent leakage of passwords and other credentials, this class supports delayed evaluation. All arguments can optionally be a function (callable without arguments). In such a case, the function is evaluated transparently when connecting in \code{\link[=dbGetConnectArgs]{dbGetConnectArgs()}}. } \examples{ # Create a connector: cnr <- new("DBIConnector", .drv = RSQLite::SQLite(), .conn_args = list(dbname = ":memory:") ) cnr # Establish a connection through this connector: con <- dbConnect(cnr) con # Access the database through this connection: dbGetQuery(con, "SELECT 1 AS a") dbDisconnect(con) } \seealso{ Other DBI classes: \code{\link{DBIConnection-class}}, \code{\link{DBIDriver-class}}, \code{\link{DBIObject-class}}, \code{\link{DBIResult-class}} Other DBIConnector generics: \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbGetConnectArgs}()}, \code{\link{dbIsReadOnly}()} } \concept{DBI classes} \concept{DBIConnector generics} DBI/man/dbQuoteString.Rd0000644000176200001440000000566613575266047014540 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/quote.R \name{dbQuoteString} \alias{dbQuoteString} \title{Quote literal strings} \usage{ dbQuoteString(conn, x, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{x}{A character vector to quote as string.} \item{...}{Other arguments passed on to methods.} } \value{ \code{dbQuoteString()} returns an object that can be coerced to \link{character}, of the same length as the input. For an empty character vector this function returns a length-0 object. When passing the returned object again to \code{dbQuoteString()} as \code{x} argument, it is returned unchanged. Passing objects of class \link{SQL} should also return them unchanged. (For backends it may be most convenient to return \link{SQL} objects to achieve this behavior, but this is not required.) } \description{ Call this method to generate a string that is suitable for use in a query as a string literal, to make sure that you generate valid SQL and protect against SQL injection attacks. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbQuoteString")} } \section{Specification}{ The returned expression can be used in a \verb{SELECT ...} query, and for any scalar character \code{x} the value of \code{dbGetQuery(paste0("SELECT ", dbQuoteString(x)))[[1]]} must be identical to \code{x}, even if \code{x} contains spaces, tabs, quotes (single or double), backticks, or newlines (in any combination) or is itself the result of a \code{dbQuoteString()} call coerced back to character (even repeatedly). If \code{x} is \code{NA}, the result must merely satisfy \code{\link[=is.na]{is.na()}}. The strings \code{"NA"} or \code{"NULL"} are not treated specially. \code{NA} should be translated to an unquoted SQL \code{NULL}, so that the query \verb{SELECT * FROM (SELECT 1) a WHERE ... IS NULL} returns one row. Passing a numeric, integer, logical, or raw vector, or a list for the \code{x} argument raises an error. } \examples{ # Quoting ensures that arbitrary input is safe for use in a query name <- "Robert'); DROP TABLE Students;--" dbQuoteString(ANSI(), name) # NAs become NULL dbQuoteString(ANSI(), c("x", NA)) # SQL vectors are always passed through as is var_name <- SQL("select") var_name dbQuoteString(ANSI(), var_name) # This mechanism is used to prevent double escaping dbQuoteString(ANSI(), dbQuoteString(ANSI(), name)) } \seealso{ Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbUnquoteIdentifier}()} } \concept{DBIResult generics} DBI/man/dbWriteTable.Rd0000644000176200001440000001541713575266047014311 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbWriteTable} \alias{dbWriteTable} \title{Copy data frames to database tables} \usage{ dbWriteTable(conn, name, value, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{name}{A character string specifying the unquoted DBMS table name, or the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}.} \item{value}{a \link{data.frame} (or coercible to data.frame).} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbWriteTable()} returns \code{TRUE}, invisibly. If the table exists, and both \code{append} and \code{overwrite} arguments are unset, or \code{append = TRUE} and the data frame with the new data has different column names, an error is raised; the remote table remains unchanged. An error is raised when calling this method for a closed or invalid connection. An error is also raised if \code{name} cannot be processed with \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}} or if this results in a non-scalar. Invalid values for the additional arguments \code{row.names}, \code{overwrite}, \code{append}, \code{field.types}, and \code{temporary} (non-scalars, unsupported data types, \code{NA}, incompatible values, duplicate or missing names, incompatible columns) also raise an error. } \description{ Writes, overwrites or appends a data frame to a database table, optionally converting row names to a column and specifying SQL data types for fields. New code should prefer \code{\link[=dbCreateTable]{dbCreateTable()}} and \code{\link[=dbAppendTable]{dbAppendTable()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbWriteTable")} } \section{Additional arguments}{ The following arguments are not part of the \code{dbWriteTable()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{row.names} (default: \code{FALSE}) \item \code{overwrite} (default: \code{FALSE}) \item \code{append} (default: \code{FALSE}) \item \code{field.types} (default: \code{NULL}) \item \code{temporary} (default: \code{FALSE}) } They must be provided as named arguments. See the "Specification" and "Value" sections for details on their usage. } \section{Specification}{ The \code{name} argument is processed as follows, to support databases that allow non-syntactic names for their objects: \itemize{ \item If an unquoted table name as string: \code{dbWriteTable()} will do the quoting, perhaps by calling \code{dbQuoteIdentifier(conn, x = name)} \item If the result of a call to \code{\link[=dbQuoteIdentifier]{dbQuoteIdentifier()}}: no more quoting is done } If the \code{overwrite} argument is \code{TRUE}, an existing table of the same name will be overwritten. This argument doesn't change behavior if the table does not exist yet. If the \code{append} argument is \code{TRUE}, the rows in an existing table are preserved, and the new data are appended. If the table doesn't exist yet, it is created. If the \code{temporary} argument is \code{TRUE}, the table is not available in a second connection and is gone after reconnecting. Not all backends support this argument. A regular, non-temporary table is visible in a second connection and after reconnecting to the database. SQL keywords can be used freely in table names, column names, and data. Quotes, commas, and spaces can also be used in the data, and, if the database supports non-syntactic identifiers, also for table names and column names. The following data types must be supported at least, and be read identically with \code{\link[=dbReadTable]{dbReadTable()}}: \itemize{ \item integer \item numeric (the behavior for \code{Inf} and \code{NaN} is not specified) \item logical \item \code{NA} as NULL \item 64-bit values (using \code{"bigint"} as field type); the result can be \itemize{ \item converted to a numeric, which may lose precision, \item converted a character vector, which gives the full decimal representation \item written to another table and read again unchanged } \item character (in both UTF-8 and native encodings), supporting empty strings \item factor (returned as character) \item list of raw (if supported by the database) \item objects of type \link[blob:blob]{blob::blob} (if supported by the database) \item date (if supported by the database; returned as \code{Date}) \item time (if supported by the database; returned as objects that inherit from \code{difftime}) \item timestamp (if supported by the database; returned as \code{POSIXct} respecting the time zone but not necessarily preserving the input time zone) } Mixing column types in the same table is supported. The \code{field.types} argument must be a named character vector with at most one entry for each column. It indicates the SQL data type to be used for a new column. If a column is missed from \code{field.types}, the type is inferred from the input data with \code{\link[=dbDataType]{dbDataType()}}. The interpretation of \link{rownames} depends on the \code{row.names} argument, see \code{\link[=sqlRownamesToColumn]{sqlRownamesToColumn()}} for details: \itemize{ \item If \code{FALSE} or \code{NULL}, row names are ignored. \item If \code{TRUE}, row names are converted to a column named "row_names", even if the input data frame only has natural row names from 1 to \code{nrow(...)}. \item If \code{NA}, a column named "row_names" is created if the data has custom row names, no extra column is created in the case of natural row names. \item If a string, this specifies the name of the column in the remote table that contains the row names, even if the input data frame only has natural row names. } The default is \code{row.names = FALSE}. } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars[1:5, ]) dbReadTable(con, "mtcars") dbWriteTable(con, "mtcars", mtcars[6:10, ], append = TRUE) dbReadTable(con, "mtcars") dbWriteTable(con, "mtcars", mtcars[1:10, ], overwrite = TRUE) dbReadTable(con, "mtcars") # No row names dbWriteTable(con, "mtcars", mtcars[1:10, ], overwrite = TRUE, row.names = FALSE) dbReadTable(con, "mtcars") } \seealso{ Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()} } \concept{DBIConnection generics} DBI/man/dbGetQuery.Rd0000644000176200001440000001375213575266047014014 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBConnection.R \name{dbGetQuery} \alias{dbGetQuery} \title{Send query, retrieve results and then clear result set} \usage{ dbGetQuery(conn, statement, ...) } \arguments{ \item{conn}{A \linkS4class{DBIConnection} object, as returned by \code{\link[=dbConnect]{dbConnect()}}.} \item{statement}{a character string containing SQL.} \item{...}{Other parameters passed on to methods.} } \value{ \code{dbGetQuery()} always returns a \link{data.frame} with as many rows as records were fetched and as many columns as fields in the result set, even if the result is a single value or has one or zero rows. An error is raised when issuing a query over a closed or invalid connection, if the syntax of the query is invalid, or if the query is not a non-\code{NA} string. If the \code{n} argument is not an atomic whole number greater or equal to -1 or Inf, an error is raised, but a subsequent call to \code{dbGetQuery()} with proper \code{n} argument succeeds. } \description{ Returns the result of a query as a data frame. \code{dbGetQuery()} comes with a default implementation (which should work with most backends) that calls \code{\link[=dbSendQuery]{dbSendQuery()}}, then \code{\link[=dbFetch]{dbFetch()}}, ensuring that the result is always free-d by \code{\link[=dbClearResult]{dbClearResult()}}. \Sexpr[results=rd,stage=render]{DBI:::methods_as_rd("dbGetQuery")} } \details{ This method is for \code{SELECT} queries only (incl. other SQL statements that return a \code{SELECT}-alike result, e. g. execution of a stored procedure). To execute a stored procedure that does not return a result set, use \code{\link[=dbExecute]{dbExecute()}}. Some backends may support data manipulation statements through this method for compatibility reasons. However, callers are strongly advised to use \code{\link[=dbExecute]{dbExecute()}} for data manipulation statements. } \section{Implementation notes}{ Subclasses should override this method only if they provide some sort of performance optimization. } \section{Additional arguments}{ The following arguments are not part of the \code{dbGetQuery()} generic (to improve compatibility across backends) but are part of the DBI specification: \itemize{ \item \code{n} (default: -1) \item \code{params} (default: \code{NULL}) \item \code{immediate} (default: \code{NULL}) } They must be provided as named arguments. See the "Specification" and "Value" sections for details on their usage. } \section{Specification}{ A column named \code{row_names} is treated like any other column. The \code{n} argument specifies the number of rows to be fetched. If omitted, fetching multi-row queries with one or more columns returns the entire result. A value of \link{Inf} for the \code{n} argument is supported and also returns the full result. If more rows than available are fetched (by passing a too large value for \code{n}), the result is returned in full without warning. If zero rows are requested, the columns of the data frame are still fully typed. Fetching fewer rows than available is permitted, no warning is issued. The \code{param} argument allows passing query parameters, see \code{\link[=dbBind]{dbBind()}} for details. } \section{Specification for the \code{immediate} argument}{ The \code{immediate} argument supports distinguishing between "direct" and "prepared" APIs offered by many database drivers. Passing \code{immediate = TRUE} leads to immediate execution of the query or statement, via the "direct" API (if supported by the driver). The default \code{NULL} means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct \code{immediate} argument. Examples for possible behaviors: \enumerate{ \item DBI backend defaults to \code{immediate = TRUE} internally \enumerate{ \item A query without parameters is passed: query is executed \item A query with parameters is passed: \enumerate{ \item \code{params} not given: rejected immediately by the database because of a syntax error in the query, the backend tries \code{immediate = FALSE} (and gives a message) \item \code{params} given: query is executed using \code{immediate = FALSE} } } \item DBI backend defaults to \code{immediate = FALSE} internally \enumerate{ \item A query without parameters is passed: \enumerate{ \item simple query: query is executed \item "special" query (such as setting a config options): fails, the backend tries \code{immediate = TRUE} (and gives a message) } \item A query with parameters is passed: \enumerate{ \item \code{params} not given: waiting for parameters via \code{\link[=dbBind]{dbBind()}} \item \code{params} given: query is executed } } } } \examples{ con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "mtcars", mtcars) dbGetQuery(con, "SELECT * FROM mtcars") dbGetQuery(con, "SELECT * FROM mtcars", n = 6) # Pass values using the param argument: # (This query runs eight times, once for each different # parameter. The resulting rows are combined into a single # data frame.) dbGetQuery( con, "SELECT COUNT(*) FROM mtcars WHERE cyl = ?", params = list(1:8) ) dbDisconnect(con) } \seealso{ For updates: \code{\link[=dbSendStatement]{dbSendStatement()}} and \code{\link[=dbExecute]{dbExecute()}}. Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} } \concept{DBIConnection generics} DBI/man/DBIDriver-class.Rd0000644000176200001440000000172113575266047014607 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBDriver.R \docType{class} \name{DBIDriver-class} \alias{DBIDriver-class} \title{DBIDriver class} \description{ Base class for all DBMS drivers (e.g., RSQLite, MySQL, PostgreSQL). The virtual class \code{DBIDriver} defines the operations for creating connections and defining data type mappings. Actual driver classes, for instance \code{RPostgres}, \code{RMariaDB}, etc. implement these operations in a DBMS-specific manner. } \seealso{ Other DBI classes: \code{\link{DBIConnection-class}}, \code{\link{DBIConnector-class}}, \code{\link{DBIObject-class}}, \code{\link{DBIResult-class}} Other DBIDriver generics: \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsReadOnly}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} } \concept{DBI classes} \concept{DBIDriver generics} DBI/man/dbIsReadOnly.Rd0000644000176200001440000000421113575266047014246 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DBObject.R \name{dbIsReadOnly} \alias{dbIsReadOnly} \title{Is this DBMS object read only?} \usage{ dbIsReadOnly(dbObj, ...) } \arguments{ \item{dbObj}{An object inheriting from \linkS4class{DBIObject}, i.e. \linkS4class{DBIDriver}, \linkS4class{DBIConnection}, or a \linkS4class{DBIResult}} \item{...}{Other arguments to methods.} } \description{ This generic tests whether a database object is read only. } \examples{ dbIsReadOnly(ANSI()) } \seealso{ Other DBIDriver generics: \code{\link{DBIDriver-class}}, \code{\link{dbCanConnect}()}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbDriver}()}, \code{\link{dbGetInfo}()}, \code{\link{dbIsValid}()}, \code{\link{dbListConnections}()} Other DBIConnection generics: \code{\link{DBIConnection-class}}, \code{\link{dbAppendTable}()}, \code{\link{dbCreateTable}()}, \code{\link{dbDataType}()}, \code{\link{dbDisconnect}()}, \code{\link{dbExecute}()}, \code{\link{dbExistsTable}()}, \code{\link{dbGetException}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetQuery}()}, \code{\link{dbIsValid}()}, \code{\link{dbListFields}()}, \code{\link{dbListObjects}()}, \code{\link{dbListResults}()}, \code{\link{dbListTables}()}, \code{\link{dbReadTable}()}, \code{\link{dbRemoveTable}()}, \code{\link{dbSendQuery}()}, \code{\link{dbSendStatement}()}, \code{\link{dbWriteTable}()} Other DBIResult generics: \code{\link{DBIResult-class}}, \code{\link{dbBind}()}, \code{\link{dbClearResult}()}, \code{\link{dbColumnInfo}()}, \code{\link{dbFetch}()}, \code{\link{dbGetInfo}()}, \code{\link{dbGetRowCount}()}, \code{\link{dbGetRowsAffected}()}, \code{\link{dbGetStatement}()}, \code{\link{dbHasCompleted}()}, \code{\link{dbIsValid}()}, \code{\link{dbQuoteIdentifier}()}, \code{\link{dbQuoteLiteral}()}, \code{\link{dbQuoteString}()}, \code{\link{dbUnquoteIdentifier}()} Other DBIConnector generics: \code{\link{DBIConnector-class}}, \code{\link{dbConnect}()}, \code{\link{dbDataType}()}, \code{\link{dbGetConnectArgs}()} } \concept{DBIConnection generics} \concept{DBIConnector generics} \concept{DBIDriver generics} \concept{DBIResult generics} DBI/DESCRIPTION0000644000176200001440000000336113575400712012365 0ustar liggesusersPackage: DBI Title: R Database Interface Version: 1.1.0 Date: 2019-12-15 Authors@R: c(person(given = "R Special Interest Group on Databases (R-SIG-DB)", role = "aut"), person(given = "Hadley", family = "Wickham", role = "aut"), person(given = "Kirill", family = "M\u00fcller", role = c("aut", "cre"), email = "krlmlr+r@mailbox.org", comment = c(ORCID = "0000-0002-1416-3412")), person(given = "R Consortium", role = "fnd")) Description: A database interface definition for communication between R and relational database management systems. All classes in this package are virtual and need to be extended by the various R/DBMS implementations. License: LGPL (>= 2.1) URL: http://r-dbi.github.io/DBI, https://github.com/r-dbi/DBI BugReports: https://github.com/r-dbi/DBI/issues Depends: methods, R (>= 3.0.0) Suggests: blob, covr, hms, knitr, magrittr, rmarkdown, rprojroot, RSQLite (>= 1.1-2), testthat, xml2 VignetteBuilder: knitr Encoding: UTF-8 RoxygenNote: 7.0.2 Collate: 'hidden.R' 'DBObject.R' 'DBDriver.R' 'table.R' 'DBConnection.R' 'ANSI.R' 'DBConnector.R' 'DBI-package.R' 'DBResult.R' 'data-types.R' 'data.R' 'deprecated.R' 'interpolate.R' 'list-pairs.R' 'quote.R' 'rd.R' 'rownames.R' 'table-create.R' 'table-insert.R' 'transactions.R' NeedsCompilation: no Packaged: 2019-12-15 08:59:43 UTC; kirill Author: R Special Interest Group on Databases (R-SIG-DB) [aut], Hadley Wickham [aut], Kirill Müller [aut, cre] (), R Consortium [fnd] Maintainer: Kirill Müller Repository: CRAN Date/Publication: 2019-12-15 09:50:02 UTC DBI/build/0000755000176200001440000000000013575372776011775 5ustar liggesusersDBI/build/vignette.rds0000644000176200001440000000060113575372776014331 0ustar liggesusersO0ˆP#xHP$/dzZNvik7nXgGA׷}B> stream xڝVn8}Wme I^`v/Յbt}"Z*'`r*,l}8ÿ_nǢ>ͭE]X^"!&ڟgIvl6 E<*w 7,0BQDeJY]wH8D(B͉0ra"( m.K=r. h_:X[%2Ia*%kou]l 6'>NC~GlVD=“ >UjJU NZ'*\p|o5Z>Viͻݛ!kj_,39TJgJq6M\/ZVvI9Jjnjţh6oK㔕L5tPr}w,y+=1O=~{Xn3AMxZ~Cǫ]ٕq@H`3V vBj+?|^kT7i66"HN)]ř@]x=H[-ҹ} `% &/3 }> ~Bz/bkZ)^O\=/B~2Hv h151q{<&zC(摲"sT~/ &+eNM;O<|CGR\pmwyzb6ۦ_\|4Q7 m2*髻e6/j&%[y`!E~x8:&SAʋ:kr^Сכp2Kg=75ӗzQe'1h9Iyj!L g|?w#S> stream xڅWMs8+89L>*5U̺*[qT( h@gdj#qW<3#8c_$+KRF" `n*AYu@i^T\aLskRsԐhI3@䕢ypC=ix.O3ԥ:2)PVEprB}n+]Чcy|q6?^di|JOXї/'8>otrev>;exonnl|޴h=ǻtgtC_WnzZ?5=i`7u L_]k!EZ 5Xܝcb㼸;=mΫUGb[*'DzHfpn;GJU=-T\8?P/&6asJ!{7 fbz;-lH_-)֦ #u|uպyݛ?:rLi1"oIM[ӈ}<A~Kýc@?iMq{W׏w.?y|[en΍;̚g^y62}wp[ 15i2\Q/ Ī*v8=l5޳psem endstream endobj 245 0 obj << /Length 890 /Filter /FlateDecode >> stream xr0~ Mt&B9@&o_ x2bUlϏ$>I`\Lo(K a?"kZ6r~,>]L}b{ YM#o$#!^@UpE2YX!XA]6ŀx -EOVh2E7Wzd6 rfvXTWY;A`܊&=;&3 pJx?\Qf H2I\* yYŸuyHAc˙h[eVpV#ʚ6V޸Y@ '1*!h~H^ly8j/q؞)|tZlί֭ 16Ӷec Dz7*V '2l/ [䣬H3kPb3 sBNqh& (6ϡNt^U1+b K,CkmpadoNv 6O 7 yݼr"q w3Ie_M1'O'&؟eP lSwƏ4qg/L$?eAwt+&6)v`ls9"~dB&givɹ]I8Gc}]Q`2>Ο'r]j֑7pʥ L&{ׅFPԙjlƛh#rUqtd6_ 儓lw/ ;e `oc'kFNԙ6,pfml~}K| 4XS@!iu63>g4.r9':guO*f!i/qt_q1X7o>|vjUyl_Z// endstream endobj 302 0 obj << /Length 1633 /Filter /FlateDecode >> stream xZKs6WVjƄ|$;$d[PBBv 4%3l'="bþHz7:z;;:9H7K#1ϼһOߞ"o)$Ch9Q8%^&0[C$>\D==|gk' w(ix"E9eܗ%ƶ 몶cjޖBH+}Ti&˥}UaX<,١OkY®7Zd#Y>hnfS%ը%U(]* åRKKҕO4t/jΫmc9'o?^[30JГ>ш6UEks=_NE/\L5GQDҸ0vDB@ Ōk/7$Mpڶ"!qpS{ yVbe]Uk7lH"P!a+<b"ҫj^*i~fQcWZnԱq LItW&ľF ڒ xp{d=P 0ǩHXJe\,oN !C؆ )z_&PE0:!QG}019 B0zk Á0XZ7vxImvccӃT=܂ԻrYmt;1waԝ6"\V;5]>4K%!'{&ij^J[Rv &M? OtWf=1Z.9xBFPƻ,Q>3.> stream xڭXmsF_KԺwyv8n2;3Ep(bw@䎒t2wrϾ,caXl:z #dxtnؖŸ ߶Cc7F.]Q,ty22,}\v|OCիHzf`}.L'l΄_@%ڹuwP]2ZiuqEYlֺhKGu4*]M//&g;R^-Ǜ(ThAwhq:eufED_0tbOO4˗+ZB_qk_xKNP=jFY\LJ_)kAws{?)C.~.~+@C=OpB3K6_c #CT0MPxǛdH{EyGT3by;:5j>ٓ`fնE.knHGm1B'DUA;jtdQ!B 3t'ڀ&>u7''tud+ˆW/K(ьqXW_3zIӨm[P$l>Q'T0hqW/{6nދ @}f cn*.uӺ΄7 ~69$has*!Y5D=ҖfI 1t2i@-fB5I`ԛV&!;`wxV!:ȁK,_)v: pmv+YHr!ڃTBy.pqʫo`=H$߷n.M%uJMvrFv*NeTNXח G0$ekY78f%"*%"KTy3{0'\p%_HUˉUJMrQ/H,yLIT|:l*Qo4Ьsj@CND;~WOP n6` č?n[A> stream xnF]_AI<8pZVڇ4XP%};{"i arwv瞝a֧fVrm]#,u'Y<-hs)ܥ 2rm<ԃE3wՖg 9{<۔z. s ȷ yBO&9up'$l?y2Sc˪xVO2P0^c?y9F^E=9 0h8,]BkXnBRndEjQ<$f0X!K~$CdȵʄaiP}>L+>ƢM22ԳuaD~FLaEyZm3=zDg0(A-ɪr dC-Cp;z˖TlT ]Fm "3+/iLHPKh!3N8 S X&`r3jR-*.v0n˗v-2 sk]DWC~eeE7H.7%b~CGGp|Oq[O9 @)BYnDE)'?XnjH2 yąa4^c6EbDq7or!dΨ vhya$ 4jID$S\ARDݷK-I$Fa~-Υ( OY,xX PWx\[Eߏ#ľn fG{ND= Ypmca[Sqȣ'9Gx//#;ďA7:`x%Gxd endstream endobj 212 0 obj << /Type /ObjStm /N 100 /First 906 /Length 2631 /Filter /FlateDecode >> stream xڽ[[o[~ׯ!< @7-u\&Bɕ6GޮN`G29p. 9g!獏- m4xDhYIC0g )T+I !;2EĒ3F|C2WoH> [C?#tЯd|bع Q ST D^- Tf)eo8:#|# Nr6WL!4QQp&Ă)7! QEpC҇Mf FD34d\L\[QTq&9<΅nyS (h$^IR8@]LOL*9f̅a1q.C,pCR2W-h3%fQ?G$=)3(T0t)E*%H .@` V;c*y`SjbUew.KoP / ,xyTQ0(%dtQFT:jv3;;K O'!2C*|HAF <Y^/Ȉ:0Oͺ_{ӽX,YrWeOݛ>@٬;/6潧ht A]֕~n>l |0Cb3_.w_O6?t凹8|`g?8#QrcYf~5)-oc¥ڄ} *t6]7_ocL ;sbg 6}}A3L ί9:2k0{FNeŻz3צ;l}ݿ=ϺW/6kؼ(E_q/6+~oX5fFAmI۬mv"rl[-iH#G*TM'j5)㮠 F Ew&E02&,aG 2aウ\-b w&nBq{ ce!lCPBy6FC-|}10G ؄8a8ǀ&By6&0<XF PNc^ɇDMsR,Bi= 4w 1Ȝ$~!GBAAAA\DEsEsEsEsEWT^UyUUWU^UyUUWU^cUYS%ߐݖ`|MYg1 ~EFgqJ6CթtJ82 Y剈%?U[i<ɜ' L>ټC.N@h$qO@hGDnFp f[qd,pQc{Jw#%cA i2,Y56[Y\=FC|8"TP;ASt_ڟWDl1h mJ-3dOqd(Ζ|Fj3A?+e; IRKL#p@n9(kyۖ9&D*XHM'=V;4x;2,xroK_f_c9~Ggl%9@rC)0N.ОZvfL]kG }AS_҈Ej_痧'rLեV0曾1\ޢ$r5i#P.RnOFϛ!-eYu2|}p qGݭbH8@M_ܴ"upnR^:)i(|z)!oF)mY2:Wa9K@OЙ|A&ɥ { ݟk偃=ZsVݟOR'd*7ӊkŃZ`xV$whOd'Di)dD#rӿSU"'9@+C-9OA~. endstream endobj 435 0 obj << /Length 2674 /Filter /FlateDecode >> stream xڵ˒6!B3{ز8lJf&[[H$=|v8I "_.o^|Ve7ۅ0^$BXe ^/߆jRBY. p8yawd@Em^Fb%R;"dJqb{:xM,W"17ACoG6р7Ӧns^=M+2ED#d,©d^{)`Iأ h(r%" LvT,!G,hcO1lѸHM](jӻjs8^Vlwۄ)c-5qXUwXkC(`}^]hӼ)wiBLb7luӖmעBwE!/N7 PS1Ze|@Y[zmX6GS{<ؙCǺW_2rIhH"΃^dBiYqvﬖ>Y: '$jރFݎ*,Lwe#Z4@ׯ_󞜂\b0N(+AoJ-G [+l5q GKzn:kʛLm&zjZG*6o(`S5M(q /s;h)U bMMca. N8R`'0v`Oda<%%Dxғ#r{ el<#7mY@:9? &p]T5h\eE=P޳DK/GQFˣdj2KKv|otq5H8 ˣR@<^xIM0ݞnryKmrpEUN2AX=]IΠ 2׃t\f%?Jx{[ | l:\t֔dB?Q^.4 L -nM`'/K BnpSаT+WE1hIJs %|K(W#u!&\x^is S'd1Ě<#}Kd "T6+蔔.AHz+*RE}oldk PUp[ɋۚ:miGGMNKX\ny3nzš3S!230½8aY[²x0$Zaz63ϞsY\'M#g h[ ܎𩺃~XhEx&~rH*{NY/ pZkw/V\5%Yȕ]k II;`Rm΄<6CNiۋ쭆^B3UC.y8o aP=^C xB(k?({X  r e 7#xF5"IG`Ki4"`?7W?T0hʛ75/4J!_W_?B5|-^WMk:,dBMܠ$}JMqs' L'dښbL vހyy$1"W6[@;lQE~mRoeoO>/Ocd&|guX<ʁl\ҖˡKD.vPg)=}^}JIܼ?LS4 endstream endobj 478 0 obj << /Length 2123 /Filter /FlateDecode >> stream xYr8}W$UY @һ/'T*V%RTxݸP"Eے=V*!7ğ]//^_mf *fWٌ1 gW*y~- vVBAa/.%/|lɄ -i0HjʶY,OyiMgy7[wnt#ԟ[>Wn4r쇪noՃ*[|[P>E쪦l]˓L\?`siO hVaϖ\̹ENjq%epxTBR j]t鍝1[,WZYHo,$\4fgVR߿ЦtԌP}K&t 9?>PMWS =F[Y%U)1d_Q>☚ہs.T[ ShD3ѫ['NVy w@#46WVWQ'H? }*"EdJo_;XyIՎ9-=.a>wpD^C͉\~EG[oUO8."CP!ƀP|+m[|>AT<"E8=__T{Q62CpO||KRڵ9x=!< $Q:/^Zr8o3`80 M|/G<X9JVM]P W3QD큞s a̺2ՠڮ.oh DِbVeR L07a]Tx Y-3߷҈'U3Qz(;H|]3J&X0th8 8 2-gtd"Sqvd(om3-`Yd 3TWVVvTH'-׾Jv 0S pf*NFk꟦ 2K\Z(HTTLnm=jjIOY.Y}' "~C'ڽ¦&Q_4u*sr y#'0'/̧.7.V[Ev5dx;ԊH[7V 8j8ʗFeh"}> +;\}fJZq6_2t4 gd*Js,Ò8D$leƗ)إsEÁyφg.qE<3oz[dYKzԩc慑8&7IMeKS5Pho:0`ㄌxႶāf- pp\ѐ z.}ymhtBgT*G)+1QRQܡ_|j,rLBt<M!SuS+t\ wW]#Z sS+^NXD' >O'S[u*7Ɛ/b@!<.|ݴfUQ734ڻ/z$ ]᪤tvk\z_0>5*cpr:R YS)DTJ²x]˂Ɇ+!a確}n(,^WXc'gMO"Ҧcؑ iH\B\D-8_? !r~+v 6_+iO-[9Mw.ZS>H廊f^M}ݻK>Ch^.?3ȩ&:AGjRj q8=U"*'DhT6~še#ВT-+/]\#_szD/I`^;eZȦ9<9\"iqwH=Us vVݺ_2 cNMoPd>`!n ]sijtX<'fӵZWK9֊NBw?jJ&o:o^8+Ջ\; endstream endobj 517 0 obj << /Length 1541 /Filter /FlateDecode >> stream xڽWr6}Wp>H!A8LKIL"! 5 *eJ$+f@^{s=IQșP@"'}3ɝA2|?9 Z9OO8-`YO{rlR{b̓AYMQ (Dt`O!0͵Θ$_֞ Jc%VS_C#Nz@ !6`Y#!Aq6ɀN #4д2H׍2wChs^ٷF,lHVPfb]N*, q0tr$ њ0eQ`\2̒GǠY 2L"M0nj43kmro|QY7w`]Lj;=ۜӁDB[obخ%-PGщᘯEA>卼;dI5#^~ievX0uLj͹eΞ_I CmgL`" A e ?Bw?] ͅA݂De:J3eͬ(dž.;mQN/ڝ[w]ghxf+`@-- c9xz`$ c\DFN6S̼`f"-…/dYʙt[ R& K"]-+7_R!E{4)JW(U;KS]=$#^!\.0V(/3:8\r)9 {q8@iknoAI~rIaS<S)5Fr#\y1s8xz~r9 5AC]}Q=ڗRzbU%mMtfƌBeb%# #n3kPS "92#(s ą;euEvgBS-ъNsL(`z]G&z/7 bV~hhwޝ^(JO{Aat~[i[=u,_|!v endstream endobj 403 0 obj << /Type /ObjStm /N 100 /First 908 /Length 2662 /Filter /FlateDecode >> stream x[r}W1yqn[ծ+9&.?PfBI3 m9!5*`gnQ8EgFL(m6-3'gdNh)hO>N+"/Eds۹_OdoB`9&0L&HNل-H pƢBDڱD.w(" )Ȍ9C .D]IÄ% oKQB4^aN b8b($(VȄZX}=z#ӈ T<*%#%V,(CHs"3K1 /00!\F1yD$z6cb\beMI?R&GJ&)ĠPX;ɱAq2 ,&'BXH).4,I4ELa*[Dݒ2$CmKQ[c.x܃z1a#=`m*J;;a N! )$I@w4DGO;,H@l KUm* Q! C ulPpG(.@J3` GLwI!SѼP}өr%Œ?&͸0n>/ڶ$w 9~}br:}u\Wu=졂 "yri"2ܽvaQ> LD$7~ZN/(<=3W͇ys__N61r ~m(jBt[Mu[ioM-?V&M}9Y]]$U VEU]kjkKJmSmsmXNޛ\'\V !֖V#0\oۢ/hH*7Q +ZB̋NK+tȅ̛ɪsZs I=8,id);G^+p?aѩJZKdLHj"Dd:ǖ߹d\+ fw$ `H'4)-Y.la6&wtmj:Y)RUmuw$&* G:Y-0-ZYpݢ5ooAvdt £[H+Li>Y޾7_ H3>Dgg dW$9jLq5>vv'd{8Үv%Et +JҨ^ږ+J˸Ǖqe\iWy\qUTyRI'UTyRI'UTyR*/UyKU^Iq i̼Iw@o\ެ&CV@E3Ewµ񂃖4To;+ZuG ])$V@= :E&if*Vxu5[ 8)_0 04'''LVد~:<#J)&BUrfo8b[I@mm}YͦGq 3*1#ۯt2?X]I &栗w{AUzuMw7<ϔ'`>t22"=*nBQiAw)kТ'V23! jݶ糐nV 0y=b HҦRpuU̶;A f,ˑszzi u3(.Xg9] {fAO m0I> fľ M-{Sc[(ۣ6 _c؞CldO8G ZNu QwPJ$ Z}pX)‡+4 $kmX/7wEK0]*W9nfCһ c"R꟤E|9$dvK`z¹ܬf+qؖepN Y{i+*x>ӫ3KYMdzWgQ~Ve =e .Zmmm5\?=X4l SPyj(K/C"V"(r{[7(> stream xXKo8W݋ )R4iXHAh[[YtHi%mEj c= o~MfQz!(7ɽa>*y*jze eC ( }Pi'z;k`nLR{{\\NcЅI?F_Eͭ,*se~ViR-wiNSőK~fo.|)䏋7v\ϊ7$Hzv,/Ji[M\-!b>ϲFƥ:sQV);ZNRmbP_RXv8,d"@mZGDk@̾{(\J[ϵt;ym2SślPq1m2xvIL7[X^6GᏀ+Q6궚 +^2b>dyå'X3 Jm J4U}^`\]f@WȂW`3b_!Ru%o@ޘݪ{x|ԿJ(/[9-TBS6i4`? S)_OrY endstream endobj 574 0 obj << /Length 1707 /Filter /FlateDecode >> stream xڝXo6~_!IbV$3&):ےx{iX-w䑲(M63y;~)QD)K}@8 2JIʋ`YBͿ,zsNpe=ݻv4E`xl-XB/Zvύo r8lR^]]yp~r9:p" hIeA}J /n1 #ͻd54HxA஗`g9h3Fڼ5KPܵ;S5Yhk:`M 8d)/.c Fb ٕZ`}yư,(Uծš0+Wb#QWB㬲z%es{4 pҭݺJY=Iv wF4FM\NvΒL> stream xXIo8W=@Ŋe撵"K-6Z\QJ?dqR-Zo{k,z=9O^]JPz5_ZuOB+~b3룝-Ϋdi3<' (:<2q }8;$Î:^ڧFT1 <}]fv\6orJVTbDVIЩtҜ P'ŗ$(pIw/[2On?c~?Aq\-pRg_&]k\(jD r1J` mu^f.NKHmvL%$%ڰ"*ΫbWϳf!0 xBZ|9~GV |ɡS i@55/W?ߗ_};HC,Ś7*IǠ0$=DJrkAX鵓=vG_ꇓ 걑gnZV?HZ#5|{y> ә9㍷#GE)AGţ*1Bѻ"|uU#Q|Z|Ob^-,e$"2rk6yѪ7Y ZHEBx_9bxCIgy=#(euS>_;{FvJC_M0QdI&Қo\ǷuɑAifJ}f]Wj-ljSse37){p$eY[3! YU\&Dkq6@IR]=y^M~ZN63W!9ѫ7PmLO\/ ؼIHW_h7kn\e#FQ+zAW26oTmi-'3.Y-}lh 5ۻ{K״DaՖbRu=I3°N,/eJ[>1,'xwp)Z@C}[9h ˪6_YCyԊ<`cx堾ǖvA:DH)5ba  ]\Y!t'S}uY}gp!RsZː_)W?ߑ{ !TQC&)ִѻgI^ULXx~_"pE1k o\4y.pP )Qՙb8i^4Vһh܁N>:%#|Sr```-.I>/jhx R/L0y<7wy.Ҽ͘qu }+w C%W|%\tO(ZWyJpqyEI *ŃGzM*K5ݕ B4AUqǸ F88Qxc꼽7&axKԣ6Ba;fM[#:wa9zz%xX`u@Klp\w,pzȷۃȴT$ lQi䚢-etϛ)YkQ=*:,WdO^Yw >Aaؿ<}(A(O<kw`ͺXkOd>df[w&^T#׍:TB 5cIrj9:3cz0yk_;0P54hoL endstream endobj 616 0 obj << /Length 1642 /Filter /FlateDecode >> stream xn6=_ad/6k=Mۥ֮[,y.CP%bsd5&o^,Ξf$%iDv{aA4}D,,ɟSZ}:`H%$Cc`˺Dh3 ;41,2{Vd'ϣo! 걙 (^\,Rdf#\Nۺ, _=.g~2]dWi7B9xP;Q5iֶ\d#X#mV]v3ۨ_P=lOu+ng&_6=L|F͐i`?Qlc$!AԲSBA)  5ZdG1:g0vRce3$I"k8E-WK-I ?,9yB`KֵjNP9vr:l[~MH)cVf\rK0p8}X5VmW#=Q.=`<1 41~ NAxV3?~.ra7મK3xSgL s nWris+{k-$`i/4?0H!2wXu'4#QNvzǽ "hJh'pV)o^Jq+Ygۂ\7ʨT$at(~H Z#F< M_a]uhTv>c>e&m,UQqais?!+$WO4 Р+) ³R4;YU L6x…֠z˝@r{οj]̃VoJC.ȱ\L!)AcQ(t& 14V? O<*EIYQ5Ǭwq}ezj[)iTe~⑰mZ]}i#q̞Qp/mef~A4uyk`-xj[Y-d&rh/ od"5v~ky㊠$k_rEQk}\ Bn !uΔQk+!(툂s(4ׄ6TQaD8m!½+$JvBQ 祪Gqn̵WR Pڦ7-,S: bC,zQEo]d˺VvC%5EYyV-QA!@>}L1&^:/{Dpz^Jb<h}C H5AAxwΗoDs]G4_*G<eo ռlo Ј~ׁ O1׸rJ.@\z:HRE$%w i\c#{t*F L1-WͶB8|hBA ħf6pY3ZhF5lgHW?]}3S-p˾ˍ΋>^҃H =;MGS%5`˨,aluwqfz/EYڑ C!^jk>pߓ\Zq(8(s5֜)Î.~r ֤4lׂ&U6羯g endstream endobj 524 0 obj << /Type /ObjStm /N 100 /First 892 /Length 2264 /Filter /FlateDecode >> stream xZ]o8} M^@1@ 3N]l7QZc{vv~Ε|#R;hJY:"9% l}'OgA3EH8WŌ3Q#|o7hpd!oB $D&$8z9 %!!  gl(zxbqI e8 ?LAmΌQ'f0`"cpȑgjLm`b8P8 ۤ01pg*αBj#:ie %ZO):{xlub֯VQdIqve9ɈguSj\!g|)L0BFH{IXM6)AR{I2-٤O1)bq&;WsP`9ƙ3l)f690!`4g/tْ)1YIA3d = rc.L)&\D7jħs:xl<,DcbEL  >KgϞ?֘zo//6f!AO~Ϛy[œ,ifyCs왙3?69Z=\>؋byTӡbo)^T65oЖ_m7 _y0^-79}߬;tergIٵT=rxݴ'J@4Zlqҍ];UbQuϣ0::RcRꏪ?bX/) }!R$dXĤެK"$f&V"Ek#Iެ/iǯ9!P (đ/=X}s x-ń`)ZrS-R, |b_Pdzjn8ڬnPqAopYE/faD @zd4|(atl͘qbUUv`B&ig 1 OaTH$ 4 4AAtC-B&<m[5$w+( YIh']A+9dĊB;:vR/o6AZ)BB${=&nc ro՘bA젅j1 ċ.NErhpחKy]Ges6q)l#u14И%;8 % 4?WWwFzɢL)~&R^UL"XbDq)1=ͮ-ut;h,7< Dsmoɘ-* GCT 2VNTh@JUy~FƤygyne}slc24Q" ,vta\è^[.nEC&GF7Қ< ^[8š P:01%2or0Jhdcy\ endstream endobj 655 0 obj << /Length 1782 /Filter /FlateDecode >> stream xY[S8~Wx Q-ٖefСö Iw>[:vj9=8[ɶss?unywfzEPg:s"ϧN1^LS 9x\鐹&ï=w1 v`O.9r 5 ȥ̏>u>wSĜ{tENLm !mE.~>Z nМUC/ȝ @z1j՝y5~~ W0}ꢄ Lf-I-,,0sFfTB?Hl2-QHȒ7pﱒL%5oy. S:ݶ~&/ 4PD ;i)+7 ?dYw(f+o)h^J}Ъj( :)]߲gw\9)XZ;(97YTU=~M>]^5/*VւɸʃHO+t#">T;!$@:=!J[o\< fAy7|<6Y*ͪG$ H+CQ ER̈D\ Ej>ZT2WhD0J.) ?2B4k| 4%W噊]BEx&>ɞM$*q#a2[b"vfU97e^ivַS)Tbuâ}AƋɰnwFć[IO k4\^XT 7OsQ>ALffr,'=a`7 QBt(pM;],۽ꁏF(7e;>t&-) >}:жHVCtL㇄/4 Q:PZZqW} =1EocI&,}_!Q]jΆJݷ_s_T_41 |{.v;y6j}C1'MӃ>چ=;Nr Gծ|mSHu!$}sѺ\]''zl85¯N`MUþfsVeyX;ξ߶̾Q endstream endobj 681 0 obj << /Length 2070 /Filter /FlateDecode >> stream xڝ]6}OLHwf!n:ƽDɢJq HYjnvf  0rr/OXlvN^%N^ΦrAkۏQ8 cy |4M-b|q)wn}'H؋)7_ :3IN2p4Η?~_cc-KI̋l"\:P+le^V[sy[Zw xr֐oњ߼˶/1_a p (R]_vUg:ȼ40yZ,ڄYJe EOPrEb>l#MbJ I$t|b +[`S ʭby"k}MLR=oK+K A ?HFܛewB+0 C9[R@u>+o=UcqA rWArZ/-ׂ uB*YXIȩ<ֽn0 }sۗ\ +A}U`(ii; .<({nؐeoI/|`]0 {b)qCbthgib{1'b5=_ˇq:o8o~W߷ľN=<Kz/1'|ŬX ,NM@e6׾dK "x+|8e;+o.< "F?qOF UD%^eRq>5/?עs:f6y3Q"8BA^ ^BĮ5kyZ <"N 5ynKQi;*ZT>+R)dCXH˦ޡhw\za tƜb{g[Ea ,-ϜP'#5b6Pċz!4\Ѓ>m|1c s 8/vvAPbbCVnQB^ox3T#}tNYֻfۮa@ں}Lя}I(̪ތݝNz=\>%'a#)!!1 ˒r<|PateMu3۬JpÿT ·hroԏH ޺DfJSMcND!Rb M"svo.PjBPj==Y#:?AKs/OQԊI>ٖ+5oMJ:Vv nM4N(ݜB.c,uzb1#^MrdcЗeE(z!Q[[Fࠆޒh:9 d{^ib]qKieՒ3Bj&3&5~4~0~0J0  G y(Ƽ(H,Ѡby tvyMfJlX rGyA1#]ރWك,f`a:mWHMpi)И'=·?Ƚ&i D!5wyaE!UhK"zDC&~-'jL`mڈD|1_gu泑R@wj f3 Q^~콽[p=O$ ɽ0liGґi6uBĴcD¤,, >!68C{Z=䝆qnhzRiӏy"^KNyݼ9,\`k#u |$o9 54au#~bMj> stream xXo8޿"S6^;@SuB!mN8tƱy%Х:!qdugay|GE[E0FȊS뛝N.yn 6븮k'"D9e%Qס7WHA MUJ-J?ZE]mTF3Heu]f?t D.,W"9 тD$S.喚 ]/6޶Ԇ=^2aw* b8z9ZqQХ( _i0|a'2.׀˻66{6gܺkψ5X+nH}}ʧxSaۤǖOj\/'`(AU6{A.I^R`D;3I)0SZzTj 3x9mȾfe&_bN!Z-|U]RBF+(⽞r;O5jH,mvz-ekS 9?!&߼x0\˥ >e endstream endobj 624 0 obj << /Type /ObjStm /N 100 /First 906 /Length 2633 /Filter /FlateDecode >> stream x[o7~_ǻ 9dHgq<:՝,$M~nZ[r]g 8\4m2A2Z1#lbh䨭79 b瀋&aLpD\b}0^X"s &PpMqQL$AG$ @L(N!!!_ !"CO6$’a/a S@fÜѰ'7 CCIhɑ)&zL$')zYMBc!PBɀ.Yn1´K%A):+^?]UYըw=Z$U~OL)8̪zϓ$HY#dD$l$.s$졣z4]HQ`232Ip N4#Y:I .`GtJDL*O A QȔaMҟ)ߖJ-UzMت YXyEd-0Hq0SMN1Ti Q賤N1z8UxGx1^3ӗz7/VLYo歃wӿMϦ'o}3wW;j.XxTeG 3}c߭/fzjr~zWkDz8OE(ی9l{?lcc\!m aB$/j)jP5mL@d(Qtrz7gzcOj96DF-Ȳ:l~y: b.(XK,!jzyP9\-{D1Fa0?SV;sn 0Fv|X_־3zTgJy\8'_W_"^aXn~o bzzAf^tw}7bwjBۃIخo7Wݶ_{G7돦67RlXd]~ƷxvQ,Jg]k{IJ~Z_:8ڦVyTQUWy\qUWy\qWLocx']#s _߀-VP:0^Wyҷ_lٮ].v p"]C(qPQ@WNłfa+ɑBw``ʢ@_Vd }5 " L%@zםịEi8k0$*' &}D$*Qf-!NO[ yWZ H"Oy^OۛUKf$.O,RM i4f}CcDTռup9*pԲ8sK"cYǨtjjb΄\s&{gPBьբ[[&q9=򺐗h~/4`:{8H8ȱn-ᰃ;=0qp 2(GwVzS \# _>á,"ӓHn?N|K`B$)q,24 ˛UZ?i@,$֊Ku}u3a'FJ.C_23! .묵*.#axG [e=r=eB?>ʕ\R>ʕj5)jRդTIVR&I&I&ININI'UզPԃy$z;DɢfswZ8[ Xcea; .bsW,Y7!aUC㵃jlR-DH'* u:XX$YtUC Y=i]iK=B V[r?(JIrR\TV*g+KWqwzЃ8wm-Ֆkkj+͵][՝WU^{_*Wy U^B'(& @shszۀI)q􂻆Ŷ(p(،q#q?WaǨC'U O8ҀY5F{(x jy\> JHF i0.90ͅ=t܅tAs3q!}87@;"rqKFDq Dz7X`A; X۾¬*ǔ9t?/VB4vi^n P1P;l p4`gWO) xrO]$X@J(uu; 3ҕޙ׫LޙFi`UgP w5B9ίH4PT~$Ov~ys endstream endobj 759 0 obj << /Length 1238 /Filter /FlateDecode >> stream xXKo8W=Hy) !AG[=$C%q#gp|3Hqa>z8X *9` &`n1^qa_SzW1{$׃ic+ ?b=pqo a&ȔMq~M9V3݁լm6V4UQ 4ԫ ~7ZW;Q>X'Лn54ϤPAݾj}-:P FGo7|3eDٶ&x7W*SEqĦuNZپ-KVجm&W02}[?S&L]2?Bx8v=p]l_c9֥~+{?!Tu//֪x| M9xh|y/dP.תho-*аׇm_V'vf_+N`\#-0~h@sN:m$Z`wq^x |]gOp9=2*{_gAsxUoh7II+)3}tT?Oƻ]~BE|n endstream endobj 773 0 obj << /Length 1719 /Filter /FlateDecode >> stream xڽXY6~$5Cg6'-u Id^R7_!%GqP,"Crhx{z]=~/%i#oD3F"z,ewryKL68-7 ˊ;^lW_W cQ0 ^}Lx&ޭe$A6UxTFI0/ c"bqa dz 4vl`~֘/c 4M^;dkz'{uv,2dgMA6FPdvH%ʫVC ؗ:kYՖ-BD3vKQAxPRd[/ jlKȅAkmeH%G0ݓS] 2~2L@$!8h )`6PMf,Ud5""q04RMN7Ge1<9)ʺE-G'B92+`_6ILjBL[ , P-%.b# Z f{lF_8km_8TK]7OOX*^lW8 endstream endobj 806 0 obj << /Length 2023 /Filter /FlateDecode >> stream xYs۸~_Q_G/O\w*+:E(HXGxIIۣ@H"j%תT+Y Ti\RYxJو⌇ރ2&.~X_W4 ǒAP-ꚤ,Y>} v!m/9,% JeKÜ'4d"J^'EzŪ$f2nge=b%Eg bq*{$|Nx <l뢬 ,lipzZ gK ѡgCv뵡/E^7n0bh,KÐ@| .1[T@2ua { dHYۯ=Ő\2.ҳ*Z ӨI6p @Q 980 P!$. &joTBcHxfQl=]莭AkJ2^- 0ȅJ뵈i0$1k]SSyeٍ)36]SVIMR9=Z7B +ISȺ'ˉ{4lSmfIÌy{>l@M ,^WZ-Ud66UߎB@cZ}i&Ty+H],)bp^b95F~'B!W7w}p 6^kqmc=S d2Zvm{;nC,= w\U1~%$-8/ 2C b?g2[68|6T~}2G(}9̡ӏZBȥlDI]BXe xUE{6 ,?4Xck]4r GnH,G_2)ޝug.C+r8'ɫG `_^w_jۘ^z VM--vLWomgg80KyB;bX{+Y;4;?OrQG{.ɘfG@Ēu7,aA*Y23D$qCs(]s\c *&:KHmEpC4Vx2o]ϥz>Ex }$` 7HG(Octqs ~fcf#G \$' k N?;!K/zw`8`w/-1pbߋkss|z6e6{o ޯ270lCZ[9X^^ݘLj?" 3Jø;JnOvv?]ގIgjvԲkgNqƷ.n^mGր-𱟻6mtO7/uqދ endstream endobj 731 0 obj << /Type /ObjStm /N 100 /First 903 /Length 2248 /Filter /FlateDecode >> stream xZs~_X`1Ɍlũg҉+yJlHc2t̆`ğӱaȑ3Dx$y)&snT0Iz0@$L! P qq{ drTXe Yљ A<&dnBJ:&ӯ؄"G JƲuXR XLdؙX'\Ģ+Ae`bORXA <&E&O;^Y%$>Aݠp2ʙ!\avHM jfܐX픊I|Τ ;<= @, cVV;u[W墑+SWF#c.(@  9DHTH6.F B 7b)NTa, -j\"V]Q)D,NsB'!2''(gCO7a-RLlrV'!Vc20E@[-6h#{f-j)"nC[ϟ>虔=O|*{G? ֈ\jMi%XRyT0rp~hA9XWQm@ ىyBNȕʍJFrR<"5H#RTT}+U_JWRT}O4>TI[*PxPMf_o6i<ʥ|f+Wqy?<-8|nSٛF07A` dsG4#}}ͬuF=}z)OC_W,,5`_O ,z Rk3P #? hK(L 6o<)q, h2/Ѝ vO`W4#݀f.BPfe4݄f>&81`7F 7QGo'"+>eFS`椯+n2'{=)8%VRHm}pD}MX_>7 Bnba;uGxGcVcz endstream endobj 852 0 obj << /Length 1540 /Filter /FlateDecode >> stream xڥWKsHWPUYypU*v[dc+$9`KlaPYߞ vt`Lއɻg^##/$,nM̧BNz}x ܪOXLR/ـ+9j:$McVIvnraR*;LN gX麕?Z@YҪ<;|tjn\~64ef%evl3[+V 5FFv^< s''=/N"D+dsCuZ_x<:2v-]6fAyզq(A1L[69O~MP'@8n'2.E,83b'_:>5u=hC Nln,IogEFnn{ӸtU*e5%scSߦ1U}<wz4p,}9VwÈ2 ]J]:a}57E `J*-"'ؽJ{R4 i XX㭁Qg`R4U7xr O(p$pBiRUklûTn`7-}YWm.x":zV-u;X-rf^hUi3>h)(e!mUfFclEW>TLZ{;n!|([myjNYm\j`LRmxМ Gch?~P*v ŤN_ RuKhcvL+>Kkx gvE#M^FQVYke"i2Y5/Mgp1ξq GKIϝMl爧* x )`kfw8+_)8ìNL*SvK:PꕎY78lruɊ;YtcDq endstream endobj 865 0 obj << /Length 1552 /Filter /FlateDecode >> stream xX[o6~$+-X&)2xCYmmr"rvA@;7rwћ+BŁX]X!( 5ɬ/玿N~sEI(35B=ަpZ ah;Ǝy!x|MOǁfp,X=vH@wyUybu3PdՒ~*Z}uV٫V{xuUu8̖ %\ 1?uyY!2tdmեnnAA[i9յ2"Gփ:ZZ@H% nymߘM> =:oWзf}{gzLB\PS~KG%}Wjgcϵuۖo]p{G1H@^DZO[)NeLVR?6:,{Gp]E& t%j>|A8uz@~<$Uڬ#ioLn.adh(@nK.d,]j0eDI6oⴙ!ԋFѨNkTmz]{w1fNa؁W~+&[ _`/ 纁-$5T &bhWۥ^o} 593}CAl0gc^$"v*k<^kdR#n6udfzw*1{PDo ud  >e `' L!nEFG#G{S=~Rkv[8xiNِ*4e7T*}?L_ĒyRtYe^j+&J ljN2"D}Ekm6rYL ͘jrk{jϳYKq{P!M.1ɚu=Τrgkr w5͋Y-l?/_x1sR)r0Tx҃f5_MͫOڂ2YU F? ﰮh#[e('&9t +LVDWWC\͆b/M+Pb2w:f4~s%6"}]]W-Nm1M#!bWΩ Ӄ&oA$^g;ߍڴ+5Ŗ endstream endobj 891 0 obj << /Length 2673 /Filter /FlateDecode >> stream xڭZ۸b?@I=O\" d*K$vw3$[u6A5|7Ron›^}#}5)HSGY1s2 FWTiLq /I@8CȡY)8D=L̂4C7-#mm * Es4ƀV]g?GKZ·ovXCM%<ƶiբDzC@ Vī ]YB1[kE;`a#)S uxJ{چ+1,n0#Fapr a:**Bk,b.0<>2OHÉM8Z2Sx*dݤDZ =}/A!⑚ ;kjSS`F׀ d$%Kst=!ǃ)+ %w9D`㚌I&f ýp+d0bU Yw*afd8bh[cʅԆ =YYG$A쎖Sqs<ÌۓR#GvD([h= |,~ C#]BF [ C88,'lN:ѹTc:xy CǣQ;nhGx0[[qf`&F%GiϢq5zD^T" *-=>D}G 6EǒHlCi <#I" vS)ٸk>~`IV~}uo).D8 JZ۴f@hӕ G"OVĝ<Ӏ_WR 5$X'"wWւ;JPqGI6wTK1V?ÇT*%"Dk8I8! mĀ5edS_>%Vx<#pP5Y:/~AG5ZՒרn*8 U<} =>=omMQRHiܿ/b'`;cgYN:ɞQ,E>E:X}Z!S U12O1Pc:`.P؇')]ԉ{"*N58NK,;Nҵ^ל!+o9؂H:,lC/` #籤C%2Lؼ8uQ~t\`p zҝOP2uϨ\w3;D"|~!<pz߼)"I a!cX=a$@z #>IEۈw LH#KoD<8^A1/!QOB_?ʫ%i"C?P,q_Y$r8.eeWD0f0mFD1_\ʣ7 ].*l:INCT:?C]^u wtoM ']OF~(|"bdm}7J"P̊$d??UYyؘbG נDl8 b{A|E Z ڝ/kP,b9Mj;n&6]> stream xXKs6WE=QdKJsHrIbKAZt߻x&eɱG#vn,l^/׊PSߚ/,1r\ AYz?tq3taLZ^j̋%i9"F]ln4IGS162=~C&9D4:X03Xg RéY9˩{~d[.Ah; =jf6փ"ˆ؈zûy \tzDlQ!h(끮<ר (G9W//FIqt [vB<>>?Y``{4[NB|9l@J2y^b#8h6Ć:~ yG";31tEuğUqV00rױm^ygoSo|sD_ Gg#_ռb)} S\f+??9{~>y:^ $"Mnw,J|VB`|Li#Յg[?ePh:'wr g'+Y9 #\mfJR<3m3V%K=\t&]M=ZmfHjVnxM.'~`MeM߽L'zl SBZ1.1"m;Ff0Y_^{%]/镒/گH ( mE8 V>QDVKW $peL˭j>mĉP YwWr M_d$ޤ9ExDXI|ҐB4m+&2UNYU¦k TC5Ro%2jf#zBc4ηCίo(Y!nک\onO:LۧX:;hL5 怾;(-Gkz=hzö̈ ^<3`_P4Ʒ27D;S+˯oE|Þ\[նI}坉].|C}0 \Xn˻G;p"A[jۭBKپ|X|9y>}ۆ!}[anN,L3JRP9̳dGH1RC\4>'hѶwÏPA_B?{Q֙ͣȧ[Uh\uV(ukLrQ> stream xZKs7W\@4JReq*oHnv(qp"$8~[ f==2Lh$`H]6z[ e{gd|,a{6pĈHxLTv>߃-'2=k$|)y H46\SE' %"O@>qIqf|Rf<>efC'&8_E p1I, QPY( .1d,0cHA`j"A O%&(FT9L ,ћjŝL`ҋT@hrbƅj$ |%DIp"2Sd@'f$URb*IΨOPa41A9%9e`8'#Ix 0 )qbZ['LV KMG>0T+|fĻ^Wh݌)Rr?s2zXNeijlt{Yz'8[H1; ^f@__Gg=W٫xZed5Cl!و|"k鼈 /|p=H~] =vˆ۠A-Es&}EUC6lBTjb|9޳u@瓇A>wizd#mǂLj%Ք4P읍Ȳ=$p_|?Bލw"$ȼO1|;Q|b J7#QXc,5rO*?O**O111|O0[cpS.k P6[JҮQQ Q}_by<^ dTm,LWW3.b=[4켍% @vP0LK}%Gewo7] h"ޮJl~hM$-r8OŇ!;+Vxl>kT@[x442dz餥VF\0BDK'n6i < y Rҵa`]L2lH"KNAr;k& A$ h>VڨHVl(y%:CdZp8!`nN>FޡaU!4eCCNCNCNCNCNCNCN3εΕ_r+\/5bV*QHQhAAB;//M NB@嶗du Z%j{RRBCf {rQe#087rzrН>FL]IhXOGub .bRq|sZA%K$; RteZOt;.O.g[ \:V8)0ڳs0[^gGx@Re,/_6^- Deu2EJb>x#r!?i-yd0 =xe[q)dݻAёaݻ㷛7Lׯۂ(EBOSuZ''.~iuHzjx8wMAz >7-2֩ >F jW;_kּyLlF#Q峙us)ʏ*?50P_ni Li_z:MrۡfT1UbE$faNslDZţ1{\`z7X?{l{yX# "+CN,)3tE|g=##]~B endstream endobj 947 0 obj << /Length 1407 /Filter /FlateDecode >> stream xڵX]S6}ϯ̬֗meڇ2 i_NDZ@dvLXH^+{$Xwc}.'/.qŽ(s-cRa-#v>2[_>^Pq`FjKB166j)g6tyϻ;#G:Uu/3=;g LqXMdAUyҍO(}ޤԍiIP|\~8~VE+3eo*⑍ y泠 O&780AqWB$qY)h Sc^D=6 8څվv#RN쑤Z*̢,g47CP_,ܜ7&\ )VNn;V0+·kbmSKɷgiQc_˰1G㏨cSy$|p<蝝~ѭTVAw 5#פV@y HNk,"(BEeUrFa(5)ҠZwoc+caݚ<+\P*>pn1ȋ\ri4)<ЧN/Nϯ}>-WxB)̢a8*̪Ê"P A] qgwzl]PVW:lF4FbVF]NP8א=/YgFoT)eGUfQ9x4h3AARW;_=:,X-! Qmޭ.+]V:eܵEi%mi;=Dם}P| nj'2(ln$UFpCY&FIcr3> stream xr6QP<ͱԙdb! E:eŃIɪ(;ʥbߋrx$ap3 ƈ0A!KieLכ\p֚Bx>v?/Ud掰~8&4A^1. I[64ZAewͫvJe^wpo(m*1ಘa៸%E"ZQzYa(…\3]V=E-=WR \Y Ǭ3D A\ܗ*jkЄ!.`n"ঢ়ǝEbCu-o;o!OPLX3ד q;K]iKH,|{$ s60Dhւl `D.kLQf cٝ4}Щb[N V"L8( $EAGrQhGNSrq*&VX^LttN Jґ)mboifM}3o)z3s⽨BAϢŘzȯh6Y|= L6 LOLooGV$"}SЭ-L>;=Ī0FlwY*sqFtSvY3A߭'cVeU͌kWG_:cw ao/ZZg ཌྷ Ov@1!"%!xi`S:+ 8- X#wzB DvJGrJt?C@+cы*3b`fNU<2$nUMqJBh;:YY aG6X Cx9sop(<%ڗ{܃GI;ݻWJN?Pm<99ā03 HŢkB}7vC i7o{з4Vxsz捼͇(X8J>:}f?:p-g:==qtS`ކ ʩ&usC8T[ٿrF3:':rg|E>+sowOn]C& }7?to<FԢ|8c{iC|<U6<0ӭ`=0,jn-|C 0\D=˕~rQ1s慹vJ / ;{ Nt618V׾ *}!?s?/Z]N,t Zg1Ψ1`Ecd[} l0smB ]|>~,Xv"4yp=qۯBznIH8&Gy?  8ejf=ٟZ;H`=a[(DKs*Lbjޕа)Cjg1WXhFtK8ϙUrжg01C8$y.G'(--ʃ<ڨu+m0Ы$W1-1\S~4[7s0(m Z2f&ٺWSz@53$/Qz)CXi V^VjŲ(Vp4RQٲC>Y3BăK[aCޫ.ڪ*Ӛv\]n=}PKݞ>؉n 6;)sݯ W]Oe' R7z3T2B}b`,ё6@Go wPz4޻&]{33Uݨy, It^Oh馯uÕE]_m> endstream endobj 930 0 obj << /Type /ObjStm /N 100 /First 916 /Length 2598 /Filter /FlateDecode >> stream x[[o[7~ׯ !H ES;{ ['v)+7-ʰW-u&vЫb/98JiejeneiejH{d>l'xU=Uf}d`:p$4D A1o,$&XC7TowC8SX{=VAm:]BTDj+ &@Б}Xvem4{F)B'+3r Ǭ^ͣQ9mrl,('w[LX0ZF13 Ke2"ҡ`;SN1<%ۯ&?J1QJiTRF%QԨdjT25*L&/7yM^nr&/7y+M^iJW&4y+M6yiM6yiM6y&6yɫM^mjW&٭BCJ*2TPC :@ c|:ʕ2.XWY+<-&36#U0nNH`#"] `6v?%W! P(a47rw/&Wm.%z\lw wl0qX!eg@{-t {>&CQb< }؝m޽&T"}N.0q vLC'HJN|b F s 1CN"'1mxO 0cq.=F#!&ܣ*HGP-鷁DW*#LDH"N|Q͌mBɊkwчf3!‡CbѸ$'|3AcmqZNcp4nޝZĒHxkb ,d8p W7 9xQ4g|b4<|a|٘|DE>c< ĉ(YJ tTWrTHh(U\d҃#S) qps X[p$4Njv{£ T7s!c4u"w 'c$G:d\~9ٱs]()[_5#@Ǡ9)h2}b Y]MfwL(I%q^"n7SdD=)s߮?No l XJr{)cXQlaxS/K%Ի-;,IG`8g-Ur\XP̗K ~@$!"h~r%%r oz9pfݨOn%;c[ژʎf[`|<T* endstream endobj 1025 0 obj << /Length 2155 /Filter /FlateDecode >> stream xڽَF_!NwjmY/3xȞ2ߪ"Ej  ]wUFn~yo$~~mbD'|mO~0[H%b v};Χ%?>-nn~¥Rihݡ;? &'x7-W#E x7t"P#_X剠2Ebkm {^km?5aӕjP_Mf󡵠%ܾ64Bv`-/3WBy@n5rƊDdvu,ٴfmi(F7ݑ(饧ύ"Nq`[DR-TsT #ofd:G_ѱW' c}JPq(S2XxPK12%ȚEYɈ IM$lu=ZnB6^mq@׷MCsK,0:> )I ?k ;6Jo,/8DyEd"mh/-{%-^|r^i!!xi GS5#۴Z}Ǣ?ߔY-N˸tisF>Z쀾}vpi|؜;CdVo֔CDKZRj[VM0+ܛ,,=Od3{EKHŗ?m; z-:mۺƧS)N\GWAaǀde3qv1Y?fM] nHeTݩDZѸ+/7}5Wdȑ_2Ɇ:BQHX$XHJV!4#ug 2P0U_HpZNw+ӮsM;4C<-aO*G^\9:;&xx-:nVyq/}q|x5.m}Q:/F݉ϑͽ9=(wGX3g=Apf3Yr9lj 2YTr{ ?ҨSODB(`ѣQ@iխMZqr@OďD<>y~KqX/ST k?G="+iMsrګ0𬡓͉xeZ@ ۥ53~V)z 7=ΘaӢg~UB8ړhwUv{󨃤6y6xskA*b\ 5GQPҏ1\@K̫eyL2r611iC}CTc\~ (3e yL~шQrňf؈/Sȧ!$tF/HiϲCqФצt֎Ȭd]׭w2nXd< 3Dz:rMC%VZI9פ*IQ$n~w i.'%;fp|;m3"hk8tj/4#tV+.&D(Q@][A UZ0|!<}8$/hN1NHDY,9֬yHF@+^хw> BJƦt7V.j`kCCOcP:5 /N$&x} W$" fο>0,Xfb{o endstream endobj 1058 0 obj << /Length 2065 /Filter /FlateDecode >> stream xYsB ALwg_q㋭k>@$H].HHx~v`>Oޏ}A@lr< Be/N=kQz`2OE3|O]<";n%Qj$BxڻN_9*<; ;;yArI!ZܢЭ5HW+=MUi);re<Ք8q3߬tVvmivu "b2UɍTj3o*\l( θ3MMfMj .Έ`8M CIeS ׅ^BODv/yP(,}jB:+S|gJ5Q'/y}E]v2=|Ʃ2qy~q]ؑqtԐeN7O&vɆTZ4/SN#D#$cJ`:y:_SE?'!Ct: f&hSeA߾u=&ͦ=>yv}غ?#P!"`.Ӷ2/M~nԹ0DuP6kh t :Plq {WD{#[C;lz VCCS(~Bk\vCg,/}ȳ Z-:ët&x̅400%K% ]b&z +Lt??|u^_Upl?|?!?&\ݏVGҭk>4}~ ZE1MIb]#:'tBZw?]gg5=% Ga>ޠ 훍AZvU&0C;Y b?bØ&m?Sn jU-7ڎ~V7 8q4T} 82FƋ2'9̾|QZ)Jk@%Vdu(ޣTPHg3+ǵ 1MmH$gi$+{Ô)Y7Vwԁ芢K5pڷ7_~#X6h/n/L6dm%lW(=Fmݷo.%, endstream endobj 1098 0 obj << /Length 1620 /Filter /FlateDecode >> stream xXIs6Wpr:qԙt2@I㺿 7YV$MF.`g`rcN"r|' ,r磻Yr^L)w/:O7/;an'hLR'XfQ_,WI.\埘c@= CZ} &?ag8) {5s<@>brʳ?j= ==S  )Bhcy+3ʱJf^lXN=Ym\O wo~#P8#:F2;dzhD.;o{lJB֦s!2dY8=hTuzZ'ְRXAB9tzȰ$h̴Y]P/@(UJkB!g{ΌsUUXCmTW$t1vB }-}q)D.b=%gCF_ s`秞830aht٭O@ܒU&U8q~LbSt3b-aQ7NkD|s_ Ql `\9錸&Or)Tv K,#`ݵbPL0V{)V]R/Q9.HĹ5ՀA"o=m+݌QC@T9 {S.,DEpJ0of،MMW F$FEG-&c0&;#ߧ_CV-*M4F`>C4 ّ&Y"yT )@-(,V֮ WS)|PS|b cw5.XvhL&HyJ Ju)JIf 5WMV4h@fr틊2 =mq$! etGh[\qJTȟ! P3T@%U4u{6@ e|\]ƺ1DR4Y2JRUue4# BĢ =wŦH#%NbEt+͢qnVMdk ej@؏}TY{&Bj]HHKqҞ6Qtb:Ome:D.]w8@P\x=+V~QEW'[GU1+'qr'rUMX[ g*s9\{;,B!'ζ#'EZgu-F#+XD`*!05C=#>-߅3tv Kmw`{LoquQdwu5]]{(0i+)>i wSR\o6O?-[Khi YvϬ}y=lX/U0U?tPm>^U=:3*k|qvvfFR",YQ>=kW1.%[ƫTl&qY=K_C0}I.}{..^^,3\grD[mqŌ*jY##\N} endstream endobj 1127 0 obj << /Length 1464 /Filter /FlateDecode >> stream xXIsHWP> 4q*S)JnzA-I\qq-^/`oabp<?gS{!gWo֚ɘ3'GS]NDL/`9^ 2xeFȈFɬ!"P(AjA<Q7"\L$LTe Pmƃ#+`8,_a/AX{f ^ Vo}>q@IAV H(I\ G4ؖ[Qz5e= BV: F1X}K2d!H`nM=rRw*ʎkGD!1¸4׎_52[, ľ2`@ 0LG]RTEv,;D!kqrwY3 o2[-2[i㩡$7t@HBTf]rٟe:;˵ hfLyj9!l}OI} DNݷsQ*/g=z5닁:=[GG9@{Y gΈpa܃O@PitݥRniI$f9 RɴDiq`u6r:뼄~-4/B͚ʕ0:Ju &Z0 r[oNfahm5˹1::kV k'R.M`!W'4l![7nm*Wp`w 3vCX^0*-F0. R:Uk*B׀`efJH[++fr&ܼXgk/"!;j2 TAbF[P$5*gHf-,B_`q7W %r/j` A4p'# .miuVL+}1MptC_WM utU6þ П?R;9k}&Ԇ9L9 Aop[/p'6j \Zq|.Q6˵K5Dss[k. =@v~#ܥ塚ՏܥAB: Ms&JJ ؊+I'ړi/t6O'@zh%Ob(/iC7OPP{7rBDbyt=ؓU4Z"W>!?RyR- _kfJ{aCG(1ۤyԻZVJ\f|r ײc׉x7^a}.{9ř>s"}Ed/ۯ=Bw7~W#[bJGЖp~<lӟm DZע_U6nl<tL endstream endobj 1017 0 obj << /Type /ObjStm /N 100 /First 992 /Length 2461 /Filter /FlateDecode >> stream xZKs7W{@7UT%VT@4%kD&PMNO~H3(voφJ a%%gb %Ȥ8UDP TyTDOz Q`(!_VϬ x<x0x_Dl<*/YO^Q7z5@#>b (%HTLHC%u5.&&}@'dا0o(|bTJ 琱fz TBb3&Q@U),&#u$w@`aT0H;ֈU kX s]R&BX#%8F}M5cAm!0J,fo> &ARlRȕOL_FxZdeԂ0T*\]]8}}B&guc|l94@W+7oN.]ݬ?A% +XX- D:\<&bc$[u|q?fx=!uZ[A #[nd9|ې j`@t> 5z@&2 bP{rDx_$%ýjD{IN:%I V҈؈ԈBp2 ǾM27$sM27$K,M4$K,2hZd=SZ&:x>'jQŃ Ei\PBlY|r0U7t (g> لb&0v@t 3F] I(^F0!c۳xWaSnBmԠ1r&?|ގ/gjfT E$p^.;xpYdv K{мK*46hx2]]mhHmh/H,| *{A֫]Fk;8cMLJ|׭x}`0j)tg *=ᠸ[ Lu&b Gh~:ƓRZ G/gɐC" @Bt8鴛M r`~7 BIDV'Р伙 &ZUo7>CSjXrцi((6tq_Tk( Idu6xJסlnv?tLda 3sXҼv9ꪶ>Ͼ|~[ \I_ }:dr&[64y'7EG 9Ul˭u:5ZGur?n-1}wIy`dRbd#1Fjc1rc6m#1Fns$&4ɥI.MriK\")h5 ̀! }n}ˀ;Sɶ`7P2hITlL(y%UpfB%{[#lS)00mrVP (>&( vn4EK<\lT@%o22ˍ  ؂\/\9Y}]Q = Ձ F5aG1hˑwpL(S_pcTWlKz'z1 "oҐ@/(g__CP7~TPF1mXAx^.uKݹAbGem# R$ (cβ(Kͼa(?, fz=CR`SZ]r<0af*r:ymX٢J'R8-V@yh$ds V!t{r DHEBOn=@wɥ{[jG3fg#f["5"7bۄ-hI&vv)jg7ɾIx7p3[d-*p>;7Zc& 1M =f "YM}0m"9oul`3ya&/feaM3YE?y3@mLnaɃ8LnpL:-5{> stream xXKs8Wr @余Tl!; D“Ϳ$L\ _wK&hOz ,d(!v8r)h~883I61vBuKQr5=(L |LeA!hrȸdJ:GNQ*ʢd^g*]'z(޺<T^dCcΐ \=P^ V6IŸ" N4ax%tG43L8wT5.t 60Xeu}S Y OJ1Y[ѵp+knآ9(̤YR$Ha`ƲzGû$~z;J8 Wi&oCh,I‚Q&[ v#ێȯd߀<ȝS醗A~ί;1oI"7k4ϣvzZtrTT\n_pA[w'fYb<)gEMچ׫IGw6Ӳ2N/#1)'m endstream endobj 1187 0 obj << /Length 1826 /Filter /FlateDecode >> stream xY[s8~ξҲeaxp%cۡHk!$aȒssKU@G/gG/΅ bk2`!u2F"8tyŹBrs_IuZo3S?^! X+@4X([ׁB`ztٞ7Vp޵Q% Hc6'q;i'\QU'lLjbve4;M^j^Vv H*&֦)8F7eҥo(nMxa&#x"8PPa۳әSec{M夶J&Y&bjts::fjdPZ 8Xyg\\z~ a Nh&K0kj I6uboLiڟH^> >]^^\j= )?L t:7DO9Zکۤ,Doj]xٸ%N.@1m7$k]ѣUc]/ğptsn-C(;oDMi&6q~ C9`W[&_\]s47N'.q% 2Y֠(2-I0DUr( jsٖxDU9<˼Ir0NR]z$u`x$0 XH&;9}0 1և,6l*u HEI[*LrfDѧ⴩I6.A_APƲEiPok"#;`#/<#h enx~2yg`D8<3Iis*<8?@^\YjZZLV)6"| L|7eYLOy:yx8 I"jI^1d! [D=cbfnuێη~"*R}B F(s}|f+ Vc>`Yy*JO88\bCiENl(jM}J}EV6*գM^51 {t-:ȗuLB=ADČpAD)Kh|mML";-6}d47 Y˟c~b?Q]d遬z))e8dE!o`妨[ej@JdV..׿0__$섢_K"R.Z˶P9^fE"!SZWKD6oώZgPq`=)YrٗAZ'e?1 HcjcUT>~ίCGkPK|4f/z endstream endobj 1224 0 obj << /Length 1101 /Filter /FlateDecode >> stream xX[s6~Wx/0+-ߘltMaV;f% G eLYD|*3wIfHm#@k #GrDvvҔyf0);_& mb<klXZDZKib6-h^Me yvBLQ* [h:y ,U32ۏe]8aZ k:| 6"BƷunPFb[kOE [1\J ǡbnz5 |REcZnoD췐RDibaa/l#.\"^l[/Z<Dzcj"_Dk:-O< r^Rg^2ngп}|]RHĹ&,D!FTԂH;ZluE: ?*:TLQu,e3>iBi.X*YaLڥ(#Tv0LI"Z*#%m"r~DTFiw7EHHhRz$x9SSc\SZdDpX2VYʳe)}\yƕa=PVaIQW\vKq|Čjx[|gOfbovpP(0"~zy xmK!YPݫ!=)y$M֧m4X4iR?J:~w Y&Ed'@z}7w7D@4p7<8k,sy|/19 (}.u@~{ ?Ei:Oa#K>ysi\za4 <mORwTXUһ%ح/jt)<{ -SnmaWZ`9"j*-kT"6 7q8P-+TwGo8~Zwz֬W9$Xu~3l>|Xde|&8n-%5󫊰[gMCҶǟݨ&' endstream endobj 1134 0 obj << /Type /ObjStm /N 100 /First 991 /Length 2343 /Filter /FlateDecode >> stream x͚osSe3Rx&8I J:'li%}qmH{gu&G>wG>PbŨ&&^72 Xl<|F)ϔ Ñq1GbS$'8NQ|Nb9#`p )^*'6"n&Ccb([ 0{PBP`6!6.r6P\ hFlr]6cE΍p[ $pOrl;ǟ* ?h2 n,^7'?&5ƖVpnr#juL&(fexjRjsI95zL&;еcC`psNЁӜ\#KmǪ)LE•@2Ou.K0%vlx!/u*WS][Ra9:S[y @@W"DUjTQ%!Gr?Bv ,}m+.\ U'KRm]) w-fĒSfvm3r-%i'jJl٣Ggjޝͮww?fO֛a!Wogf/}p6nv%<ڄ{DS>X,G̾YXم땽f=[^|IX#I%C\|}ڍ\rUNn jq8y+4ηnl|!PzVr~Z: R"MHUHVf/byA BQ((tp n4׋a3f$0E m ևb7l#uIY@خj(WbӈAt4(<8^u!șK3C]E&gu\`T6"O2:fj79co#Fۂs+عsthmrtڵE}E*i;)8a? "~Gn? f7뛫df/ًμ08f,be+]Sbp }֎i]̟ߙ I8|>l1h?nݱ`d5`SëAj5X 3gVQ=GsTQ=ǽW#e8&F:Cô,t>V? kH+"DaбZF3A@ I !0Z<J$w"nf9nǜ&l }U΋XC|.ˮo t؈9ꃙۓ'$c 5^/fp#Ppq M l+ .drOҜVGݚ[cf6C[Imь͹{wI)y+?r?HiUn{UZ4MEjѬZ4ͪEjѬ*7笞z깨碞z.V*[t`71)ڈd"O}avS  j> stream xڵW[o6~XCҤE]{芁[,i~ɢ,N!p~w?],fo,&s c(on@߼ %P0Kp99\wB3߈ZaII|=w Pk'Pw*fuU&26 (G)"8}5˻Oh & l=ô}a2` th8A1 *Ll-vM(}7N[!M ns'O[1PϜo0cM foYզ`zkJ;&^<+CnxeiX;i⁇(ֆ &mӭ(V֪Aah]XT2lT-im0+V荇׎ZvDڎVHICͿ? %Y=ղ[zY/QiE;Ңfc&(Jj|SwYOce6Aͬe%^y i_!u+FK?4U?1䅰4SYCU7iۆwf`7 ?Zmv!x,Bl0PuwG&,J,Hp-܋ČLT?q?ԚXl=>I2h/Z֢h{XTce="pr=Lz8&E qs1I @0Q|ØKE#gz`Hb8qA&oJK,vT=O LWEUÑk&6 Q>p0B=zȕ%/itp%]S7C(n/\l[JE۹ Tʿ5yp`LR\CmŦ/Z Kk^?ͽݷAc?yxPM\o!'c̞(w)}^Eo~*;vvONd#TqVStͬ5[7|{v;&6'5.0XvSSww+l~Rܟl=@G5Màqji|L^siuI}U}0U5է =F㯓njQ|doSd3FePf1t1>yT%PN^1d^( =/+{9 cGOR`f0=Մ6[r ]*U)%6* PLJQ8^OkZ M>zAj'H2x3^fCyAn䲴\%۪;@)QtTkkڶ@ 8 8J^_1qYCs64D>{m/&|( ۯ?S^ˋ NAq*Ud]dHR^|k `c9vka EET-K\^}aٞZSG~d endstream endobj 1267 0 obj << /Length 1586 /Filter /FlateDecode >> stream xXo6_!/2HKEf]oAX,y4<ʖlys.IԹv~v6yNp'&ql0J 2F;잼=xJ[/-~=6A #isLg*<{CqdTjop52"D]z걘jkqaUk+HZ./P IֹܸϢX@ȎpHwV?b;> !P^8@ELxC%2KIO}Nt;*U>hmdvu6 *)$SSYBnbt'IW!02xbGWY9#ڞ`LeЙp\$Xσ8bϚ_"Ϟmݔ,&N֭* ᏠǑsg.Nw\N>Ú(Tud!R~݆}3xf,J{s\&!oY~s\:WLs}& 1M \>+mXa0ED08˩P}CSX % Mrvw~q[eB׈`XRyIqci$hf؂E% ܳaS2JGy;r8Y  LB[/e){c^p?? 0uhQDCv,@b 8nߋOV~ZeNSLw\3{dmK2>( GI71N#~ /ĠU endstream endobj 1343 0 obj << /Length 1334 /Filter /FlateDecode >> stream xXr6+x, Hp%%v4klM. "} )ReVfU&@uoajt6}$8pkZƈx: Hl&KVCN&O u?#lt6=hbbt [ L~`*'<@FlK'o8nQ9VIh|g&,r*"0 ]GNˬ9>۷3[fDcu_g'JǜqAZ&zPԴfzJ;B:{qmODJ#ocZ'2МbהB_.rA10gzQ Vcی9]|72S=d`VX:,Z*iprkS3Ʈo?鉢 DO3ݢO٢fk0rZ1NOzkrөzC-K:TcF6cn^,JP%]zG]v3#Og>[W%I٤mZ[BuDf} i^jBU{ѴL21Kka Cʌ\l0J9cC4ϻ,i lՎE`̣([&]Te }$y(7TW.Ay7E9-AB\ XD@23s&cTn)ӵrqdǹ.8?Sq^0JqU{]!@!N_4ϒCO\m4ǟBGVCPok.~{ILH0kOoݕ5tTUUe"&f=Q7LC?89D[T j5's*K0Ѿ z϶xIk Z}LCBcl#zeS.F8b'-P3U sz*k8 KJpBV2JΥ*vgN 3n).Ki;exHeDMw)aof< wu,@tD]t J{]8 `. endstream endobj 1230 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2366 /Filter /FlateDecode >> stream xZߏ9~w/rm fiOp?ie$bܝrrW; u@&h8U6I)΂'1 |F2W h^UHTAHƳK:fr1~\\g>\A$Fĺ2=;Bdp5≜%6Tr 0Fgؗ3bb&CFꏘ'UCĽ#楨#hAhYŁ UqADWmMDb5&E/MQKaX b(l!_( s ,B=jΆKTs1jg%/Br&=2"յ$Y-cIA#4>E N:~O𪆄3)8]Mj=*R(R"*̅3x r}$&8)MMR19z՜S&K_s095$kl%pJHs}*MOJMAfpjV_:^QlQwN͊YP^GEw6Iԡ! OHr_3{Zwgۗzb٣z<׽^~==~rx3}+ٌ@[/r̓fvef߯^q],`E9!`?eD8nx.}p.rL8.vy6D2gCY4GԴm,-ڽHnֿ cc):jF: jX]|;lގD,fBNC9raqK؈ERӀY>t9?4HV3%jE3G4'.N$:+XF j)j&'}^/PziʦPϞ@2"$=ݬ_] p==0g;y:3cYVy| vjSz1ԘT|^ Wx*< a@Ahj Ob邅H`C>}t'?zrY6l|}oGL>Fw%9uh`ť{6(\sW A`rʵ_f;yy3qJ`@ kbz5@Cz@2(;`4zYm,j{kO&rbVCTlF~]l_s*#G6$jv|7ץG"Ѣψ K,@$aE)G$ʤ̧"cUdYr:ѓ\b̗1ѐ*3:@5|=}W4LF BA _5f+Tυ77۱u 辪-TU~hSWUdS#`^'4_w I{hwJ,^$W5#wzVMQ;MѾn*.(.(.(.(.(.(.(.(.(*7͹iMsns\44ͥi.MsiKRDt=~'h-IC:I7d-Iw IjI֔^^z] !&M?Z䌂 Y ܁roul BMz2Iᬗ7q9ƌ/ֳ؁bؽe EأITi!o' a3|r1k;`Plfꃳ}5 c'A"Aw^ 6*G1c|x}r>Z;1ҠC= g[=[FkPP~zϷAxF( n̗cqsG,1s/fz3b Q:瀆 A{$?=HK>pzLcPX+jJ_~M}^mVЬqbo u$ɗ)Xי{^/27"wJsRַB•, endstream endobj 1377 0 obj << /Length 2139 /Filter /FlateDecode >> stream xZYs۶~ۥf"ۇםfb+CJ,v(!8=%eQvdrarJAHB{b(%Bz1p0:u1DI<5$e^.\\rF-X[0G܇9a>Uj8.uI5Qsd@Df|**˜y<}\SY_K`#u3A&י0A\VzU>%QQKwsQz fOR:6 %9u辜ETF{Շ5({Gr#nd;C#$$ V_Ty.f?3r'Ĝ?EigiCW҇G<6'i1@" ēbkJhqcQyRÜ' q1;]4n1fR"p,N]6叙ۃ=+h<@Ak?L9LWJE_W ^9di7yG7X'2v1n$9@{7*<Q:Um1۵-!ǯT'PHЀwRxy<(_ ժq' 8lv6̳dJ{ޣS*g>g@I߬p_Mp$ѯy1^, >?+1!EyOT?5{~Tu) YoW}^gEܫZ|LG @-8;}Imk$bZ$3b.H>Lv@S6ɗ鄍vA/@c? +ƹ׿W"D-`S< ^WUB]Nξ1/rH lu/:_" zj !4 n>?)JiՍB}_zi|]rŇn(T3.8I;yjZAuW_ œqIUx]s=H*:딪(R󑙛_LBM`AE [!,E)]FE! KgTjymRȬ03,!GY~);u8;lւj2~n8r)u!OdKq>dXwɧDa,~ȫw͎ؑsv7.1w<[ZzdӲiG&;}uCm/ ) bPh9,˶njv΍S1𭱙I#T0(3+l^t=4 9Z.j8*o`*y " )1T)$gPFfc[`X۞I'7_.;8BA"c0x^?)8pbQ0Z hT|֥pInRSEYOP413~K%#!š ~SQ<ǚ#R&|;Ul6 kd(u[o 4!.GtbjCϧ2 z4t0؀^]M`rVҬ8F/EEѼ ga~-t.*!ùդa g|D)]據{f'Hʬ~`! ػt9&̏TO%̷[jhqw:OX$Z`HrȎVApl5ρw` (0zjX (:y,e CfW0Z`M'4hNҞt> stream xYYoJ~WX})%KBHo"EzCc6K %"/xwΙ,3'_[k  #-&Y5cͬΏ῟9+},\J@NWɵ/_paf1Τ6d联 ܾTT^Saf;&}uys*"'\/"8hWus\n紷 -4 < ûETuv |%n$Pg2Shpv8_0vP0ݭeє=6\ rfڿL_] Z5\`9"@zqS4U(Xšշqo^d4aq~ҍar\]L&P{e7^dmj$Sh6d=Sxڨ d/Dތa_kX$H5b{ $>>j Y!."oӌV[v7zA9$Z%.ny?ZzϳkX3)dcGzH`bf>;βO?Ϡ+?n viu%-_>n{a@Ío~ZG#}| [Z$%'Y?0,c4k=~~:38+kƠuM!Z/`D ?`Ҥ<;V=(;1C̀m4ɮ^v;n#YةTm9ա0#y +(7wU> stream x[MsW\@UrDYM)*VHބUv=3q͈p17@7]0pbϊ?Y*A.T%xi+ߜ|O,-93CtrIA,._}p]\6D^Xb(vG5*xg("-o(8yZl!4pjfcjB29.+}ph(((xTUP(2GRZ+<*}jxDy,C(bc,c210Ē}`oI=[H&Q.Xġ+&6.8eؙTƈdOr/r[d<ɱ|L&g.1\)ə"hyS ȷ){< &E4]2 [aU:W`!+b a5eZi 32cVki&Džb .LP#NE@ÞduC h ~ ڬEYQHA  n3AU 2g ߂Of,-NhFHfu٣Gg5lf ,,{{s}쫯M43e+>7lW?l=G H0S@p/pvl9<\ x˗Ѽ6>3Wݧz?wgs mY,.fzSkڬ>2|Jo0zekv~+>m+m IO Fk#j#i#khC"{E+Wd^"{E&E&E&E&E&E&E&E&E&E&E9(rPA"E9*rTQ"GE9*rRI"'ENz3f*g7ofՓ73soV߮_v!y lkc]؈b[C͑^7W;GŻ}no/ևp,`zZ9؈M{nʌlJpс ©M>Oa37;[J%b6N=6jW+B`%J"ǤΌ<"䋭DϷv1d0$(?7W32&$MVRq&/6j7.\fDXJ"'on"6qjWom^^W-UtLGݜ1L o7#"fCQ"ܻ0hSO-RSwys z(3T}N~LPoX)JN\8%Lv ?]vŻgt!wQLhyyぺHn/ xω Qud 3JEӳMw}uX:$6߽;P щK~"7sa$IӓitsݟbV>PcB[=jWr-l|4w&y bt9+&J}tu0J쩔T۹d p 3ˀ{^ΨRH8O6۫9ܲ^"[Gy_w}?Cs&(t4 @gw}aH"9lI*]>#~/9W"1" D**8y#2͜[LpђKo+/x&9<~8݌Y;e9!ZI؃ h2ЉY1:߮YgG)šMBŪ!"Tc] %&Pfw_a66sQH%@)0bF~}=s%7pX>if~ΐP-H.\@.\-52c[y\cRgvY!L_eUց 3rT'Pc5KD52M43\(HMhLXRgB})|1%YHj)>rrDleNT zYr([C. >XK I_H9H& jHJ :.x6p="^`JE9 r V,cFl%э!C.š_:NfbB@=+Re|:x 0{"?t(&}͚([ PMeO_Cw;`(8LV2="{)MjM-%!{g*WwU+DI&ɕOU$UdUdUdUdUdU⠢CU:D!Q*rU* *c Xc1VpU8*c Xc1VpU8*c Xc1> f=#zBËN=lnEOl=TnEOcT=!> stream xnH_!N<}q{EAla! (%q"&U}PL'30GuU]]ՄN~;{7?{{IBr(%'c$dOxcѴYL(ZDrF- '030G&KNN0p"f au!˼J lHTTLg"#l4k2ߧ,@uښTi+s0-KRlYQv--tQ=xC'3 VZYxd: MmFSFoDqͶVzSK^mY^8Py FQ;V8Uښp#F`h©!C޷njeVvm,84< g|ɛ\Vm,~N a@Ǹoy Uݚ%.vstʮ+e^aϨhdN=Y8񇚸>/X@Ƒ>nahkk9XXDN$TܜCrjbo[5L9!]pD„9zipZXk[V֕I$?$xVbA$3NI_9P_f5ش u>4WhN꽳[$x>lbPr~fu 8TldSFǼ6'V'0*vܫ(Fxx{G&djL~p*J.e"hF㢧|}j#4Ź0111XUed+hSiNY"Zj#B#-K̙c'9WxQN|Wu)2i-W D'%?yi^O /|">HgY6͏DV/Ǔ+v+|^~T8$NЗg C}0c$$`_^'O~Ճ̺$AIOPT߼ޅl2}R2<_cb;UK<3BC>w~7-7~Aʦ+_AY77W0̇*Rqv&4/@n._= ~Ѯw-Qx<}xG|X^=?cmLhWP5_3.ۻ =7o.6L\<5wvfjةa"&o>E<ƞ ٷ3 2$&˟t$"'r3!#ܝ}~Vy=Ag.Pl'a*"кqAAapZ1ևg %PĚWl2Ul_u-oNc CP_5+Y&RDj&CwvK=lM e3Z*` 0t]mXmuWc-.vfs1Z31=Ȁv=Y^y6Wycѡʌj+I$<ioOU~x7VfPho*#䇱^#(}(y0`;ع@Hހp; Z?/VV0NwX'Ӥ @/ { ST q&E[>+ؽ=Xi +ʂcOL1v($5xY֎m3%8m=P׺< 0.LR +Ju6B)e0qĹ <dzڑ2yFXk dT0_wU SmPiFصКmI2!%}%" endstream endobj 1495 0 obj << /Length 2543 /Filter /FlateDecode >> stream xZ[o8~ϯ0emfEQb!3M,-ڸXJr=-J"Ed0n=1K7p\p@h |{̲;j~>,q\ݛdҜNQ#\JcrWAn ^.M zyM jIđi:0G 8s֨*m t`>o1|,ju6U8scuL_mIt/ \8^ջQ-B+CFl|#3EzWǛ5q<`Cccӱ,DYjUZ kn+IX=ҩ[>-bt'VNu20NE:uh` q;lϫ"dÈٳ5M%u460nɎIߘ j(JYQݪaZjx&"ve %L+q-WM6 d DCk[ A 49R*N_Hi/mak;zđK|)1yiLRBr,6`(6бPַȁO*pO5sJ,QieS1>&bex5ѷFDGɊ`{  ̏(Ŧ jOy7SJ/p>{ 0I|Bc )UǔDD5FXL +D؇r~Y(x~̭GVY 'Sj"f@Q7i. Y'1}-ѾK,Ztxe 6o@TTRwA59Dx9'cښU2v&.,Z}Em+cZijjD.1A%.q 6U(4 2+p=*-EM ;*ꓥRSOf,8$9@x, UdƱ,>hEHL #+=7c^"t3άxpIzDVsȘtybDE=%C%ScSأB&k~OӐчmFVSJaQBMO lߺth9,v 1t{G\Ə?ϻ[}8>WNxidcEħ^cJD hRo ->s\ "MRc A  <v/&MI Ce04;?h -9V}0S1 ]Q0ˍ:Cmf J-'v{Pdp }OȜ=z1LG (MCUO+4iHIs5;QD'O B/n1r7]uy<4x6s1VNYߒЍUnW'j14-ɳB?8~8W]/4/'JwAR@t|wP\Wx:]!^9K \s_ܪͱ>l2M-yQFF?*o_9xʠ*~ޯJ&'H.S%O00)ϞlTˣo<ewx^#N68'y9e/v؁kOMﲜe_װk>]~&/?ak{ďkS+^C$Cm&.߂گ^jjW{Sy>=n杽 endstream endobj 1429 0 obj << /Type /ObjStm /N 100 /First 1005 /Length 2438 /Filter /FlateDecode >> stream x͛]o[7+x{CC?@m. ujW} lΉ % KG3>:?AdF04T&N2[ljM>Гr<ы]Oƙ2/QZ[g6䃐dP^1)J>` rMdh#yxB"f)@AQFń@BȄ@bo`@*˗d{2[AjN6 M,+&V.#Tîʧ(,E73hXNI,G,Iq >M&",1Dmb1)d1b5ۊ`jRjޤ\[LmAvY7L^8gڼs19TXFr&c"gcslf94WJUS0֊ɧM m${7+ٔ_"SJ۩؏`1;S]-{SZL I`*/zȝ2{;L>ʝ_0ܓ Fdt/q|HF " ) 懐6A. u"-!#%NM_=rQIT~g:¼ D `x P>dd_wiVLqѧ1/J+l"]~m >=LNl0\kK*K"&#:DpLE>E#j4Sj(H,$Ee,jJ2J?d ( APT$q$I™D%*=:W9>&,L,SjJ4f"MoP$_,bTI%"4e|A9h D#3Qv3['? 0R0¨ 9f:ARiT짙PT$L(Hd?˺&b"Ef8^ {s6e[nOFx endstream endobj 1530 0 obj << /Length 1576 /Filter /FlateDecode >> stream xXKo8W=@Œ" 6IE"{ KL]YrI}"eK"!o[;'o7: JB?t7Q:!(3ϝ/nPH5M%ӯ?\P[0AQ hE&تysN !ӲhoQ(>  0v_T vMD{$i/ϔe}wg dGۄ mPB!c'[M|N)Iܵ+A"(vJzr m#QEqB ۨBʢb%1M=?ZqW$"b  QL+g\fX< #1 Y͸jD%ő|4շ\MJWJ7vqNKY@e);NeݔVqQy[,؜MgS?pbiqWZbc- F]L}6LUkҌ)xJafM vy[%EefשPE֔?.OhT=Y!n`zh c18 v6Zf (' vȏC_2{!vr B{:JBuL1HoҷTSmVRUG 0c]O(P[8_ژ|`g+`ڜ@*-y3Nz~Y/wK80%ۥ~q@>/@ Gv B'aRQ\Ȯ/eS5P17Q ua5nȎJ󮰻X<5 a (B&A؋{5D@j5%mDMdݜ}nވzendMZ t {J./h+0b-mAA^ 9462Q7C$IAC8 HA+}́ۋ AieLBtf\n+(8tx̀T4J٧#m4nw4f G3MN/@(vܞԩ<˼?,O-(2yrDѡpc>J`C?<׏WB;p-k)gThC E$Nޑ'(hB(grEl`<4y#kK7!DO@ֽXcǶ|q \# ~`8B w>_/߈A1!>΃%7"Kl\bjL;xo]_}ONLY=8Mbs{OC?H?]q=| endstream endobj 1563 0 obj << /Length 2193 /Filter /FlateDecode >> stream xڽ]s6ݿ򍅒uoI/=}HHE"eX"eFN!X,{<{wk.eq{K/}E%Abyi&?Z&> b[uS-P5̷G?{8 `{AJ,M"/ߞ} XŃ, Hƻ;;Qp(JX^,&\LɈBȲ4p"0gPiCfZF$ [:|2Ɯ,KǬ]]u[ x5 eiTwyr'cݟ\M9C^[]/oڮTA=$9_|kjYĸ"pɘ|9EuF|-)MB~(z1:|{Mus7&ka_*F%#,+HW/ևvT$ h'vⲊ㝪 L[&:,d٩TzCā>2})plYen*}/U̹c^'0^_i9Mץx:lj-<^a]{Uݺ"Е (a#bQU͘H#>KwPZW-6S>q>r*p0Y:c1ggbTnjk._q`yqC&Rީ#d^6šڽF<1s{!B TQanM]o *@C~![i5TX* e*b?Q8p6OqД8@t.\MMq<]iQ"{MBZsS AK/hVVKj264ٔ3gA 5c9BW/(2CfCL6Y]qQ%<44]Lʥ޺l-Ҧ4(W]MX϶˦)("wN\ݣQLyI\#IL "k  c z>%z'gIwU QBk63yollnL ^B `{Iy`>5fS+Ǵ{ti$.+lVD@E {v+N\Ĵ19̋|L# 4qI[¨vCzԤvݮnLc$[XwyGp@!hW|> stream xڝXo6_!d(JнmRdڦq4hʒ4w#eQd>GuV|ޜ ߉YЙ:2_Ny,cgteS"U)7gǢCk S<Anzߜq`s( ˛1$6;F|EWM ^˚(Y.Һ厦im̗VVu[D4F wA>8\yܘLiypx-:su c~P9 ɍŲ2+j#TbUI!RZ5i-uL=qG#pW/ O8:1BV6㟤(K(d S۪cC4n䏉A3w][Ԯh{@H4xʶ|'Ӽ_`_]GLgu;:]N+6tK8)ܔcT]j61Un6G!(zbX͜rXǑs{i<ޕlf!2W&3,p0[|θ@(n1Sw9x/d~d539 mHg}BV挞RF/W3QEBNڜ3}_-?(k:n_ +S)]f>s(`FJ@ 8ƤPekֲ ~֏! "g*}5B*S^"ڳk1ˀP S4QRm#rpRMwZZϩ;T2k{B'^+tg2}㬍͆Vw#wK.!y-"< a" F9ǩCwK1S *Ap~IRK82nˆġ&\L2`,;vC0պh%IYUE:|نV!;AUeEe#wCH. m ۴M<7.~مm3˔:UxՠSbrALZZSr1/j]ഗJs,3/U)^.SX带aBOREpuzq~N4}HjUs)qE⣪/Q2H\b4*P=::~ @U{>H`RT@Z5%KFl,nDLxeuއ x9f|HZkڤ8)Ӊ7Ni?݋Ȋ<"Q1AixЊt2 #?( & G C6!J툮:\yx5K.`0_VQnrAh;ѧ/puTQ$|z{9..$ iߗzCRjIY xUu9A؁/l endstream endobj 1608 0 obj << /Length 1571 /Filter /FlateDecode >> stream xڽr6งJ !>^d[NQXC@$H .H[v$œ bk[ ˶>N&wĵ"oMmD\ 0F>v]RI<r|g'I6kUʳ[D(=MFwS#O\elAۏP@wI9 MY/`uQHEM6dŞ{{ʣ4/aEo>g3wFqI]h{g'|uWla~@]f/&}}=rh0'w }׺Y,N`L*Yl3:0F]g2qzݖRՍL\Vrk: Q>MΔ圜&Mi$fs!UInAׅU;+sFBdzkPnʪ_ׅfpm &a_㢔F#]Æ; qJ.ƃʈЁ _֦,+Vv"9~O+w$V` ƫ?36r9oḿ#z;Hf9=wTȚ_.Q87*FC>A,@9,_n:y^.fXi(y0]`)>sj|ǚeuwXY"V+܈upvEʚy9ML\WdWm |]xնfxB$ {uePRkܺzW'/'"(D}uUNUY\=uSPЋb:|`1ul8 y$5yrS$yvC CIZbjGlR~9zRWePFIAəsPyNLC( 62v9p1b7c]{D ]ui<6bٝmOMͣf冃  ]t`wU$6I{}EAob{!l,ׂ.ʋfm82fDTL=eǥzubu$+|u%{(ݞ NQw\ԍű1qVOx6^L_BF6> stream xZr}W1yƭʵUUS8^3Is$h9Zc׌v\ƈAKaSTQ&8A41Կ$JA60+'ON&kx/o %uyX9grk<13ؠZ} E?"&?Wחּ6ɫ_)VۍzN}drmV7n?uy"6zkW.+H{ p AnPpH4ɾIMo}LM25$SLM25$N)ndrys/Lֳn]UL~ON_Zy_-8m,ƉǬ/ի>vsZB|杽^L7?iCѧCgGͮȆ Y7st6@,iH&@z^Mph(誾`D) ,=3)4dEu r6t2y"q8n:y,*zb;i-YvK%{e-=7C`3zCÎlD;v@Ű#U@Q^Pf`-5zMGmx}PgУRZ4m~cC֑ Gm#jG?>! B @8z.[~tNЏȾ-FFߖF JAi4b4b4e/9: dмVJDe|r XJѨ8FVF3ka>#+{{^(hcϪ28`FTЈMS5:r6 endstream endobj 1635 0 obj << /Length 2243 /Filter /FlateDecode >> stream xڽY[s6~и+X( v_NMKmDA/~)ֱL@s@g9w'o'?^1o8hC<B%x|9DΘ/214W[TCH}SCa`@BX'<K8XI$_&>@VMQgK͑g#V?>z,xK3͖?5 ٳWm4-de cy n5-1sn˓'TLo7BlN) 7/*:-i{Ir4 gvl'Oǡ W{q8Qv0Ks7fJaS>27/: =cs0$4h@e 02z>vAg`߻č6G 1 S ӳ1wwOSƚcG~%>W`(91G%8plQYAcAϳy+HjCw<% ;>344osI񲨡A/EZ'Y&0W&=diRA-`E=bG`*SZIa b13 Y$ P .Q!aж"0QyVW) _U@kNJ,3D;8CN@|>H:TJf?F-D]B[V^%S{,-[Q:,WOTȍ[SHw9c$ eM|sTrOI@ϝ??0IPt-nny'Z2^^uJ 4Vd@&`(`l]F@`,}RU\fZ8>G(s,H8s([S@( C{I#MwJ(kj=^b?!evi[:ږ.zᚬ6ry{z1mx۝PDwVfj&IJukdˏcBɑ Ѯk Mj7=jt8 PmuKPYXAr8 nL%sϱ>恡߾5 kO%4 V!#a7Lb-m ֛9Aݯ{ ^߽\7m~#d‡rq%ds J i:aɷEQ#j M}gBЎ_/./.Yjx{@b'Z<{:v_k;gz'ku[wJpMz/vA{؈Ǵ{rr:G1`MQMd&S#LD.!qE }-8U׶fhh%_ =R=j),tj[;0ե1kOo(+3&5MR0¢&5Ϸ~գK=U5IqUJr_n(rG3ZKЈxq4zP 2hvosH ,w~ XYKo.XV:mۖnFy?` 2 `;Bt{lG%t.j2NV%ϧ4Juu>6:1Ia$7%{bs[v{&}vj.hnͩ]JD JI q?p endstream endobj 1651 0 obj << /Length 2058 /Filter /FlateDecode >> stream xڥYs۸~_KN 7mgMnQdG:.(m?ow u-R*"}FjPaXoyQQ8Ʃ$S67&۬ w- Wr% i6z*n~^W_*n !c@ZB_H.e{wǽp0<!'Լpm%c ]Q%_TNoccS ng E,yw١rq$_*&SG۬d~:%hנI/eMwn]STw=>ngq8?~ ֶDfL7=-4h+4YY |@Y?nŶ09H#3MZ$0yd p-3 Ӑ0ހ5Zo[C ¼]iŜK]sy! 0K%"NRjC0dmE5nuԂe[CC J'#~21srBPl2&_Y7E e{|u'FX cHPttMp+AES|t~M?o# b teESLXτE*f Ƕ4 J0c=6aVuG Hh;2%3$.&g Z?d(_Ӱw/{QCʹf}> |ߘ6x0!AqJ;1}1M jηH0Zcgai?uyW&acCSNdij`L4n X R p*e?\:#R`ImZR>.TADƧPc[^c#2J-N 0@=ZHo9C ʶ59?AFbq5A^-gqiH–'TT0=KkFQ:Ak-3[nSՒPd*P.gc[WߗǬw[VO=.GWKXa;+ڕ+u 44`S0͘M%ksNsX[1`7O(LXPjv<X+pn93 Ehل.V8F r.c;]Uo;b`ݷhtK[^,(M dqП7 (#-8 ㊹F{sz(-C-J(sCN-0(9lRE`dܱ[E[ժK!zJޗoP2 1eI,wQNi^8ʪ͜ck" ~ ~.zfn?ǘ(E [b%|<[@Na :,O(Mm=ȊsZy)$Vr)3~^^|#jSCOuC<\ᖭPtK2Z(ٯ3i ]p-]1o+  TsEYt;1\B 0oꖃmx=d[;xNT߿t̎+[gmMv޵;Ew3&Hdqy@9wqaO$vmٓzgc&}2\߰nͮw{Ѓ~ endstream endobj 1686 0 obj << /Length 1697 /Filter /FlateDecode >> stream xYKo8W=@̊C$E-$n Kt-~"%KN"H9|q˱>>zBzijF ;̳|GCkXv2]Q~x?GA9P/O2Wm9m23-xpGEg :MHy0inI%Xͻ'aƪM~XyVP;z] +z̾pLg\q+X2D:[D,pLе "{O> Jbz ~ wrswlTjqn|;Aܦ.Rk4|=g/ˇDά9|/.c^`fwoaM0  ͒k_gyV̿^ l۲x |RFM؅nv;r~l{OMڼ —shnߠ"=hbn/b3|vTPXITc5^M3=굒Lo}7C4]%>p8VیyGB3cl$P9em-̺1'rå7q Fyc%"Sun1Hm3z7;Pbtﯘ:Mᥑ ~Qkr"̵V {y0B,d(ͷX6R[o@tf̲Oxuİ9y]}Ȕٮn㡝A%Vi&~x]ض5JM!t)M΅PC/];D ꊕ5 Z#zƞLD b)"s]^ /qېө2D`q3 蜬{m%_dý%1dDq[sB@ʣY0ipcd@G?1v" endstream endobj 1722 0 obj << /Length 1771 /Filter /FlateDecode >> stream xY[o6~ϯ02X()62+xC;D'd6;Hle!E:$Q |j~&19rB0F>㓐x2&-{+a#|̚lq#V/"2 _eqI:fUR ;Wʍʥҁ\ "O8K쮁a u' QԊӻҊu.H:Bh`x!'_5IR) "Iր"SF%KQV m& Z磆~ˢ!6'.We{s jt!Fk1\#L]-vp+KOm 9ӷ]$wc||ޥS/p1oy>Rc K] 6H'G 0e7X1*O>or#I¯DG DlUz۱gQ_=bדC<"XǠIw4ЈjZ݈${/$wpx}ay+Ec͎n޶sϐeGߘ9{Ã^{  > stream xZmo7_w_( 9$H C;]itH$鿿g(_ƷJ h>ҧZ3>j9 PM, kKYv0ؓ!jBPrS6K@"$b,b2M(pJĿE2K! _"ȵgɤVlRmTvIe)HT;Db)2[ɲ1̭lhb`"ްkAfhQdũy λ`5\LqYՔd],)Xj3ENTfPD.bMQlNpX "M+3̠nRhs$b+M4Vw1 B6yw&# l(W/d[TqS`?X w,JmΫUk=yd<\.Wۓն~:_dhu]N<伻ޚ޳SI6Z54(=4Ʌ|z2/篖vvdsMg?,| FSM X 4?NxPBrxJlն{2yR$$cz9v=_< 8`2ߗKFp"։ٶe3(;!=~t\|浽^L71mðͮ>97_VE8fs0\(('`5QFgF{pɳrێ K3oI?@@NH`J$$s'֫a&ɋ\Vgӟ ` kHdfu6=[7Oޙ!@Mט-65`ᖊ 퉬+Q{"8%A)r9(砜r98_dI-8Ed|!\#ͰL|%^QUJ6!%,aƘr X@o"U40EZ^8 ?bP2tLTd!q.Ob{efW BiQ/E7]$4b̰ S8 hpV7'W]ME,(J2Y~="m._ێ+d"]8 pRrtuQ]C p" R`8^Q7A2U)KI=vtc prCZ_~9]yFڔHi0%<Tha:͑ Si? >d tj38JQD6' V5D ձa֠47删@) E1K客VuUgݪ/cEEiDZ,KiDZ,p9nDz%gh(.m hb%& ?EF:nY' _ e@pPPEx lv=in=fTIґɈHX>ywmonL${$T%[^$_z|tP!+_㨐Y :y>#}8?}t4%XA8:JbQ>v󿷇/=|~V~V~VVguYVgeʙ3+gVάY9rfʙsQE9\1(p| V GTdTaH;01zXs<}~U LU}ЎѮbIDyeB%wkCIqppcSuC oVU>qFBb: -]a|FrF>lD [-#_jojojojojo{rvOx%Q R")`%+gr+gmV#5T(s0rTbtI#MwWN_^Sdj/ə>;5) endstream endobj 1737 0 obj << /Length 2219 /Filter /FlateDecode >> stream xڽYKs6W*B$Aز7)')KɁCB3cBߧ bHRIl6^~~M W?]>^Ʋ'ݽQ0dȼ◛[ՖFV{͖DAd )W=ϫ 扌Y&W4W_`(K3"8_dW{W~Os7D byn9^.rtoZ8szi0d.FWe9e>\ەE׶*gWI}J9%d).j?5[)KRZ}Sd%iF}gͲB@ҦozvY!yD|ݛg,}1}OofN6A<^ c*= <#,4aO1"&xOm3H托sgUht1TocgM:=Uޡ8oFљ? $\~!=]? ĢHp0C`϶[R=O {&"oh$vS Vs%@b!΅)䲀h #\4sH:!cLHX83i rÛVgN0]rK`m2eNjS[b=Ph\0xg}z*-U>zEK2{fa/!vWyѓ>@U-xiA/ЅKU)ĞfZ+K`;kC5.k{~y29ݙLRa{Lai[L=)\>jj̧MQ3X(9wco)CBKG BM٫.<"`X~Pc%jo"HS5llJ#x1? ;,9£mkVPM+;xdhfjnBUئ19a YvLV$@)7>pqIthiGgѐ#fQ06mXs0HZ[d Ri`bNh,:ƭJonekI,Z!RԶƣϝ|OC4+YthJO@`pykXj9~SLYeYawB)kBԀ5׃Xv $~20Orw5VL&j,s14atnn0kɬ!A'p]2qOm5E6cI^kS >:ؐJuo>AMx}y%LFǧ<6,+вK>#B Q?|q^ endstream endobj 1771 0 obj << /Length 2230 /Filter /FlateDecode >> stream xYo۶_aIjN"{HdP[m}-:֝,i&dV;- E!ngWoo^}w),fqz.2nK)+؏Y.UҪr-= !"mCf mRLUsfM"T$܋vFw#Z)l,J?]&+3jo꺬i[$lYhe5* .NNn#[^̍Z'bXIx9 sA"+n5H\ښ>Ej-z;$UY,c} ڔz OVùo>)e/؋>pTvb˚͔*s5hVh m(|z# =da[`V< H;jk ke.ý~Gv$!Šsc|l .Tjޮ!.ZÒY&?d'}mUusY4nSz=a C ;1\t0hof:+u>9)ҤQz2JPr;7:`$|N ;dZiKO}nlA/tMԱ uNy#ȋ ,AvYǤ>珇7XAŠ8*o 4.AmVQ~MZbȁfEz HeG'1>@nQd3i(d2g[b$_ bhh3UB.`a,GǠH#ELrGfϷޘK|QŸ,j3dgU*L3Zv/1ZaB{Zb3"Lu>Alw~6ŀvPR2 r`)q׋܄}dKʉ%j(t" Whik`wxAr$$4@=&BZ>% !C4:McRekKk/XcL=$16*"5 lqKV ,<~a ahӽ9îS2Eȸ0 Go6զ, c`M|i @Ҋ!pGSC[?`38k[A7"SgӕҏF5 I&E`5;I!R5d0rvRZۜp?.ډ1-+iF:YTE!M5*k ߩRp| `d[Jҗe6ɜC~3Bk B+`$N1.6ߖ(bMȊB]L2U@.+- FprPN@ew |7.< t1 ;H> stream xW[OH~ϯgE6Fʊ-mZ}ؓ+_džj+Uy<:\+BQ@+^X+tֽx5/KbB 2I6Zv[OHwf~eCŀqzrIE9 %TJr<15ʒ'?dz7YOO*9֤G/z}z$/5qB9S |1uEZ>mq0|i-(1zLf6և_r9s[z7M6Yz^}vK$+s`Y=͛~`XU\ooB,ozʚ5+CjV-̼Ӂq $LpBx?7G;e+Ā2τBԻ *8$<+ӮN~yY}=wx@BW:l:DiHGxe~rècgFEhV /eU3+%M&CjP3xESgyQi_~ <]:AX=|CCpaF}!Szo(B8h[?LwT^7$svRӂj ~G~Js^$PJ{^u2TDzԞ<*+Acn1 Xv1Y1Yo.Q4uV.ͣlXVg|fhˈqmh Q,Y.,zb3O?x-* endstream endobj 1728 0 obj << /Type /ObjStm /N 100 /First 995 /Length 2212 /Filter /FlateDecode >> stream xZ[o[7~ o@P n.%ȃbuwo(Qv79r!sC$ Œ bXsFt@&d6YX_!$$u]49` MǤ$s]A U 6L^ oב`8ݍa ydY)cK. c^I'Zv%=Se(=*GuRRzkK='#FDAO7w`H䰁/F2)Ywř(`e&88IDL\WmzD&$ewkHY)gS2Q1b1E] t7p _F ew{+SB1X@RIl+"d ҧ#1ٓRR9(RGJS\ILʿ0B);e<+_2"+2+ʗ=vbGBc v'ee,8Uuꅨ;)x?tbrRySp :N?*e@e,rd=WN<9~0z{2y.W9=[_/feb5Շp59U%DJb< .cS䉙]7Wk3;5:^<_V\b^^7?:*b PqhO߿VWWtp{!) NpFq8ϯvQ(گX,09|;׭'5{,,zpr'Eӡ9 \%tpy1%0Pl7/{ %8 ۯ?\U'Ԩo< tyz\cXR3W&K*#pqzejX2cy9VWW)SWt-kơ| ]:[W)S.Vn";|ߠ1!j$8}p·Քp6%k&RVď6oJ0a\`MF,;Fib̑lFxR:\ xO6-geˡt"iXM踅2B̶@^~&:'=)-p]ͯNF_gAsvpF%Ygl\Wʕ3䥌.;C6 I?ep5 w$f/חof/OakB_NffZW8{۬o/.kuX,L\)ZvlqMOpx L.G"#g -ZKU;κOi`$5Tbŗbrl8|5U'Ӏ "peSgC-M0H<8xu£U&)6F {l'ǹhlR &zGZq5bI6IyWG'qfv99P/Bslauĥs6f"!d 1_sۿw}Oi{ɧ7DX~;a m۠wi]WͫCy(F94ʡQrhc(F96ʱQrlc2 nAk['X L̵&Ѳ6!qiy\->hK)C>=[K0x~rKNt {gke &";t (%#kM1dGnѴ8c#aP$-)Ez K+kv`9bieq4G{=P#hpZ`q{ ϾG(=bg 2|ArPQ,44e@sʾG0=f#rACz}p# m zk "rAO]8:~BV?mكx̱*7<"x$ɇF9)4ovesꜭI~d9;ZT2npG%uF 9hl}/mv3 ⵦ9k`7DC3ʎ?)*VɭSZYN) 4>m쫳֏`c8)diqw 4LY(fRJलsY ʏ]2[e,]BG(8ߨպ?c>J_R/!Ms`ksǃ0 endstream endobj 1811 0 obj << /Length 2495 /Filter /FlateDecode >> stream xڽYoܸ_y)#@^rHW>\ZiKJuwCj]yN"%p>3Wp˛o~(U'* C&dFKDV2\/?}ńRĜs,MSmuک oBw 1y^&ꋺ1/cJOⱜOYVQ?E21gg YTv;eQOu((S: bhzwSu\XDnpf~{uehS G\~IRoԑGKҋX.%O\NcSBJC3Du->G(#]AnAKfnVѰlTiX}J2DOl\\?v4$ nZbEiy{`QGՒ*G6fa3١pIzFW6]Ǩwn.xtҗ`D?ގooۮ0I1/7 q#,\8M2&e6 Z(k1XG4/4LɈ.3'U)gl6 +l<}<94-'Q@XB&ak?/SI4POZGw5܉*C6䉌B?vOVSDefXcZҀx\SBXqr \]x8ےwJ! "%@˳9f\W tа O]Q$Nz_1dCzp"bdPt[BY4z)!^'!?) ]P|T^Ns$ TATFO  ZC(%8kG"_?Z\BVL(a-8v Z'bSpD'8AW^PS9Yu>/T$)(a$+۷0dor B*[. c`pY ; >ɡ[}*hNDqit)CHhLQPE:.| %Gܩ¢5 yP䉘$d ]gQ|WY+Kmـph?͔#F$q qUL3xYJ7|d0r-'b9uM$?a˰}DJ!:YVʘ٘gp$&mb76*7A~)ai%*0 d{oM|w Ϻ"t1F4bG-jZ&EbmȜD L?xtS-$Rss<`iJ9:_P)JW;d_L6C1f\n^e,Ύh~9sd v11-طΛǛwKq|(uS!:qj3C@[XM \|i|剆/;;lLe\(;> endstream endobj 1848 0 obj << /Length 1408 /Filter /FlateDecode >> stream xX[o6~ϯXRnƊ"`4vdvɒ'ʹ,يkm L9<߹|<`ca`|r #%97&N< y%O_\QV0A: yHQ0%aZ.LJB iicܽ<`O.XB>:΅See=<4)Z.yj[\ ǃw< TsgIǏMCMc: Q_!m^)<{T(M׹XY䀦D9.M\$QiS[c)*5~ϤaF{>>[< _CjrD(; "@b=UjEtyGBf&_1jjʣ42vXJ r5Ig- 0xnɀVΝ[`doCT|J5mn"IU4|CRe1Uv?warz"+Vpa_li0H!"pqKqZw-R" Teal>4["AjDҖl-"~QU7(;Iz:j2ZbRDk<#s2m8 }_ۢ:4jy#IR R^boU+ t{X%8N%\.aJT<,ꄊ3ZagAUKˌ}G8}wYG[jxAQj'G endstream endobj 1888 0 obj << /Length 2012 /Filter /FlateDecode >> stream xڽ[o6ݿB ĜD8`ivknɒ+ksx(YR\'N0x;<xk/^ξ{ O1ػ]yaH^,w>"@FQHY޽/?\/M75^؏tD ^}3pG*>YЭ'H^0abzQFWM3La';_pP0踜BΑ1N r)ʼnW|U9 6W(HH bkMt<[Ԏ"Xk{3>{7o嶫LdЯn͒w_N) ߎ-G  4RqNg%G!țf!cz9z1K2%c"FZh 4W'o7zmZQ0@5ˋBٍNyqwi`$plVC8Z-A=O#.(uCcm}]G I..?`꯲ h_(=Јp|ʇuw$xꇯN`ӂ96Gr'>^_ c2'eڻ aG u)G%6W|%>%7. K㴓5Ol_@$ HR̥p jVauq X^`+x=%A1":F)I]묵fQ"Y[5\K TK M1s"L .D[qҁF];]mV`SD.ѢIoI]o;G SbĢYѨi8d${Xϥ{6*Ed2_ipEw{dRa;#9jp5'oIoD +.sw>zNFMp:Kmؙ*udg?+lf;m6վXP,j¢N>궴;#iq%mjJ ;ܘ(٦\h֭@\jV;5en]@Rь6sXp=NF+AwcY]k+Ѡ ]za꺪Hje%_RSب0`PkF0Y܏5.8:l"ǂhq8t%νnv&OL q)` .Rĸ*Ha+M8JsA3_@ûi/˾]Ж|a_ش6DAB>y`p }ݾB@;4ӅYמn1BBʚ&M[]GhGrAK0%@H荌i&ϰ͐ڌg{7JnkY㍬n۲ l!s6v}V;x]>\MZVkSZv,s?8Brɷ¸y,K)*/4+L %ÍC%y(&^ -c\, ~B4y>B3D1O P6Tqq:ܸo75(pvmkB[jS&慮V y ˅cr ΤpP.'D#%!TbbMf൅yhdO2M5 iB+&qW;"L#dl5*HPY;~Ou@*K?e|tRUa"W+^)U!hZ1%'|s ˫:Gڔγ3S`٫%b-UuX$J@|rɧi ) & Ӟ)س(>]U[(r26u=q,nZRxxA|?†> stream xXKo8WCmf$zдMbi\!́hGYrE9iΐ,9lX(j87v:G%gNL|xKHbg:tׄ㬾O?DDRge1v~xGw=F]\v7Y a%~&R'փ./$Adu2;Z|ߖuV̫Iq]HejQv^mRo+Z.4Ly.ݦT*[-)ѝv,E-3Y JjyՊ}s}Wa_7W鐾{(9Nh@8nHb Zy:#g7ɽ\ "g=/ ~NV>a\>ټ׍ yi4&̧1A"~b_'|x Џyo?Gb(.V + /leR[ls36B¼fu'*^.&:]:cSo 1L#$2p> |IG cC6862Dn^Z^p w(梒Hmw9VjMKj0lWa8a~ԏB99CB@-\N8 J+)>5_?> stream xZKo9W{Ȫ H,fb rvFHN+J-u2m琘.~,֛9ƧL!<{X@LQIĐtLvuM <0儏9[g FQt:YV!\"a(:X 8qYp:e/7bCu^CB:/C!o(QP6ŰWdvΆXH`2b}bU 8T&OuFe1I}+Y;Q1! tIQҕZH*%U`Fel@Ae-/2FA B)EN&RETVCFobD#6UuƧL0x]oL&QlRLXLvc.mt [ݮM;fk}+k9hr+"/eS\U(Ą93:bWYA%F%yR:Sqj#hCp#~cUtoTRq j=Y݅*;؞wU Q:kqJ0T\Qɺ=r%={v4ziˆ#̌+b`D,ofwG?'sd1_got+g'0MlƵ7 nKel>[f3z}\To>}b;cn^[-nj o&GVgXj*Z iC|>_ۍS5N\76͋͡,zD?;ͷ=!RO*=9ŞT"I!bD)X/5 ~Ǐ5-*eduq'Pj114rkK!';[@ٙA(n`>M'`I[$)ڂ0Wi7 rXQ 嗋ŀX|ڹfS#)(ףX^4 (\ځA%ak7 5]/ҶVק `:y`6[4%CyaA)U^#`ޓVSW>'!0F$rO8C_jRk̽x"w}h=-;-zh VVVVVVVVVV95ΩqNsjS895Ωq΍sns8A[$Ќ ᜴d ճԠ-ph;jȶoZ0k70x}Xwhj-Cn"o!t:`6VPlEQf0-2H57`MBC>x3^Jڡ@A՗ 6uĐʢ\pq2o7'z ``vV{uk~#SvJ`Y;~ Bg!hb  xLEUC*}JzĦdQh!:e$ ʲ }m_J V:QQ-֒g1?JYoT|/0'!:"-);sm5k[$(r^P/nx ݤ-$ATQwS/J& @eAF,l翽mTZ6Mim4eۦ) za2;xRg¥<|5jCKcLE* ޛvVBDk.6C5 endstream endobj 1920 0 obj << /Length 1400 /Filter /FlateDecode >> stream xWMo6Wi2s)QGE&-zh=t{e&VQ$-;[S`E97o :Z G9ɓ(MRd!IX>G<5M:+'91k?1 TQiQ aw2RȬ=Îl4 sЙ^O0 kYBU,M;)ֲ_$h0qHY͵]M9JJ7jk!>4j.Jk,e%UUBZmDDCtHXι,8 ,( |Xj^jI\ QF4~Q ʍ< ymdi*1jb6O[0^j ŦxkQ%O8ymgYTD+}%&eo J%LqE]U ^n\uT~rl?$5;HEFN}^ɥ┰yÕp`gR:(K['|X*n,CxL@}ݡt?P⠙| &-g^" @ iB~&$cQd_U PvSngbPѻha,7bL!(@Pjg;8.˵\a=,"Ih yBչ{VE#fXkhܢMH6(;EpnDeF8ec QԥYq t`_6p0^5 1i !gk Kax0J\?Cs~yfz+;9~>~ *6ہ|2X nf/Shk2 GF>{xWLxA6OW\}D6AuЅ,5b;_VLh&lZq!^ln #eq Ѧr\,|x&1x30_̿fdnw/Pi:z*_ehqn> &qwӳ+t endstream endobj 1935 0 obj << /Length 1889 /Filter /FlateDecode >> stream xڥXK6WTeă/o0#T6)"THʳsh"5eSS5F6m+d,ElvC&U$Xf,۲7U.26?z/ 9KR`jD,B'{!hck(rEk$K5Y9/C8YSfpٛ2tpgZ]7{eߛa{՝yY5ROFthMNu1rt7}m}mwş '€AFA~X|- x LΒqM aP]̀2BFY1 J&>?4ZDqZg ]=C%XS\D%ԷؗM=l k..hElԯϴw'˦tGSnSӏT /&9Ѥ_%+/*A.Tu8JD;"}4 5 * ̪ӡƵZ꺠hrwOi hΚ_Pj-tX9qͩ*˱5;ӺK6O_& \\,oZ]c 5Hdq>jр|Q2b^` RERNߚ}¿q;X _uukƘ7RQdnto`{RgDa 48_,KpwxpJ;kMjkl8>Wx,Y$Q;s Ad$CZd,Tia :ݷyo,e׷V v\\?OMO~vإK*\>;U=nv*1rܕ&ye(x ēPB>LFfDf"?dڼtdb?mӎLr  v5ʄsj꩎@o̡"UsGh71LT 4tDwѡ`dOayFŲ^v_ޯb)VZ~-ɹ038zOmg1 h׌L\tKV Siin beAv%. 2ϦjZ򾉬]@JiI e_fS[y$ a:%w\zpˍo+S<{>םS&0޹zN=a8ߘ\U^^K(:z{eNjyl݀HR/R̊-I뻽qֶU iTҴGPʫf`_j@w,!uQhPq9頠wP\1C^~z3B2)T֦@\Dل~! {+ulsWU 5E|% d'+3T4EQ=1ctיAR)8Yv YT`]z-sU0i=eE5""ܷQzs86nHvN#%98PfCfFvf?,Rys8v,Nq:Ve{C'l:$J\$Lة;[k+gНf_)ޘr3}3_*6T uVU9qrQX:+,`cZO8LS s?uCd6m<.,DRVee5\o(~9pǩ.7À22jp} WH3 % I G;e*NI!X_D yG4&#|6mB$ endstream endobj 1948 0 obj << /Length 2046 /Filter /FlateDecode >> stream xXK8W}h3$"IdEڕ%$~X$-ɲIQw}$l&|7_y% 'DpMo9Ƕ Xē`#J_ z>J3?tVT=~<ٕ_y3 PG Y GJ%<=n's!""dR*UIE_ O#R ֹ*2a})W.i7<}q %A,; ժݾWqu3?hzU3L3ݡi'KE#oy2IjtGCb3O7*ۆXO?+CݚZ_9ͫl. ởgBwqPw4Ҩ.lhẪi8SmK@J&ktS7?2$DsAG"*nl wQ)!iP YѺ0`HULԠHfuehœIRY\蔬F}IglA -+bfWՆwcmVBYS{<9 4;tʺ.TZ:Xؑv{;F}g } ^@p^Of ɤ:@]d Cd*.5(cqN߂>őStS{>2l$6zݘ<nxF|!6C՟ _qq&>4W|- xX=G^dExbDs-$ήb,P,4rF&ݘX0y&&IUc4JYWY'.&0㩻ԐmU` &GgU.냽f .-4셪qsMܑZ:eSFO73xKR6$-б,uR ^ sZk<eWtz~U{K?γga9~l=Z P2//˜G>;uت) RQ ^mX =Rny#}y_BÝ6|'}A[-KHj7vMpIךё a7Y endstream endobj 1976 0 obj << /Length 1755 /Filter /FlateDecode >> stream xY[SF~Wxyo+mH:44ഝI2^:j=gWdCmhA{=󝳆{/z IB?EP$ɛ~/J1L ~y*=2@\"}Z6ȋހGpSϜORRU|p.4TEQVr[{\n$.L*JSRV}-]HyC"s:zquǸڠ#wj!U_#m+7?EnF}Neya5`yH6cTZf3\@0Ws,_u,aYŘeY쮦5.fyni/r;TW&=]; Bd7l¹L9lBPu1 xmػ^eʋ(KeF74'2It\_,yE'o^慲;-,!oQDY_ZѼ?C;(NqZi[ zp {`\ \Ke4RqBDsĽl6SGm1A |՛&E$Hj;_l3m D!܉74Lx7Mq2ôtpEFѰx*sˏ'ۈ," ?q" '0&/q}Ԡ>NYdT&’P~qhX!A{E7 X3aVPB}fe]ߛT9T2=f1 ]ux向:!.iC[p9e|[GOHj7`FM th8LabahJSʴr'˄+ Pmxh&u@Uu6Dkmg7{Wj6vAc,mtL bn%Pǔ=Uдi%c-1bx7L)v͆=?8*,zvYyQIK =7{-4m6M:5ƞnS韕xN l {`PɈXbbO4bmS =5ߕ"TEh#eCL[E߾>{S~A/]\ٸ.4R,x*XUO|5Nny#\t)KpO`> owBvڍ2$hm\$g~r'j'"g9S[u~'\݁?˧>>YHhM3|XJx?ԥL'?o,|?x?o}/FȨ=RAGCSэx-Kb2].y&yUi[ܯi9k󾪠0?u>ο? ZVxrykbVR?hN5WOB#MyVɣ#:I苣9x?zQLMmS]/7ww^<gQ`4I2 fkO%> stream xXKo8W9@Hf"EE/ EmmpE:nΐ#r7v @HF3y{7g/gE,x,yL>D, &/q)byY5Y-ryۙ[Q t)[ޤ31(ʹ>0;^8?<((ּbW'Gr&~r)ٜ[fTn,lF\>C7f"vsܮ^I$? sw^P3Ygog¡6b"!0^]+7l>OPq̵sۥ]HE.,Nz_c,gI8:qϽEI+9*UE$UzJW¢0m=3ݺVvFjQJAG\g]kL |6f7b-ɥ[9{Y BR|ضZ^2 Sjȑ3\"ahER[0[!Aon'$OGI0!@} $\ F <Ƒ{lNWKp}>Y$?֛N-F6=!aM\ o3(LMA= 8s~Kcr[dcKTyF{Caۂцe[U[ ,@QOOsH :m I|X 4JϜGULX%ļd{dR>V܏{J{^l0OǞ2{BՕO)XJ=#;}.?jl(bA[R5:]7e?qYĂ1ށWɚGzp723btD!?hFXOd塀QUV2zC_tذmS'-x@3 <P˶޴87`Xk" {!يMux2*G7N=(/)`'z V'b#l3},J? q}"`Ihrsv(}(1x 1q궣#Ġ\PDlˍVj%TXl* -|=zBi@*ОeX߶0TWa=08QIQ՛JǗxk* M8nz]΋Ӡuew޷P6/ 뫾 heUZ%c y/yrȨ)}A칄䞫7x,R{2vbHx,;#il0f)gr#B,+ݬM¤II aRtEu4:9mg&l_9 iUeA=h1v81͡7G 4V+wor< nweUY8!h"F*+ ,a l"+3&>@shk!FM+J,я*HTv$c)6p@]`Jy%9̧QPvMp%J endstream endobj 2002 0 obj << /Length 1536 /Filter /FlateDecode >> stream xڭXr6)8!L H[L&! E GoHN4a,Dkz/^/x$Y7^@) y qz_{YGD$ DaYP'xbWyx}#C3JAX榼o+Sͺ.]F4߼X"J}]{_>b!IA Y׽'kQ7 H T6ߴ;v盻>G$MXEe+h0k+'`N~hJc&$bm}t& Y3ᱠg8;y{9's~2 #<=KяΝMtZD8$7GSByDg,Mݚyh^ZVM)e+Ee5d[;)ȖlǭLʑ~c>#UHyCX }#}\ILmpŒFUʼeD2b6 άF?~xLf|-5*HweڇKH .J<˶RˬrhEhtBEOesOsUt>d -!3'⮖ )~q:nxԮ1Sr[Gjc+@_WJ>Z:3g,NV-h8;vn1`HrrH"*͑Df3\ݾThcޏS_pAu+a!1t~r6*ufR!G p3غg {v'^> IpќkEt0"I< GNx2vf@ԙ<ʔBǭu~]7 3  0 4v! $n-ܥwx`r[,{)yE ;l 웮nM}&@OjΡoT$Ubt3U=m=HtޚFߨzkVʦQTV9תR6w 'a_7MqU]ξpv\T-@W o8vJ8HW!Gq4+(J(n-|I5.$t}YX(E P-M]].\)}/kpޚ.Lt)I<}=4Rz0nwQMJ"jЮz!O[Sˆ(9Γ jc'@BnubV6J) I\ZdD[8Wuq<1!Ȕa<^i5D'~*^oUcDtUfˈתttk}/ 3Gop50f1 JHt 0e":,$_z3QA:$`Mp=@mvu2Yom`ǔY0v6ع# _9yaL{9. Ɍ(&*G7"v~|+:+G@z_~c#ƕr {E @,.lDt!qZub&cF7 endstream endobj 1913 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2386 /Filter /FlateDecode >> stream xZR#G}WԣR]Uu  K7<v݉yX뙿ߓ%Zx#<<ղ)'eM9+KQ.;E6+&+Xq ;ߐBP, "hwrŪ#Зe:V_V '>r)+:QZ0  4dH6fc YE嬑.)hʱ9zkxT"\r~@N< &#}ƢL+/^SBαeU RDf\e|]^#s)R6Y^-+_x8pY9lZx&7It$H}PeV6냗Xl`w}&qO*(6S8(Y1A> LIvb7@⌬QXE ' h18UAlDܛ R(ɋ%Z.I%[Vɨʪe\r1$؀ɔH^z<m.F];2_5/a VD\=b!Z.995Fb4ȳb7x2H lJsGRU>xPʃAssd4'gӠy;]o>6kwl0h@E5-kM!TsSo/'x: ?}n^F .d-e"Q$oM'hM'b8]yG]oL$ζ@8[! @}:8Vͯ7C=:2?>*`)!{P̺I6Q v"-tōגݤ%-MFQN'7(]PJW4ttIExjN/ nĽD,ғj zvΗ\{{1~Q%z"2pѼ=XK<ɮ,>&htc. H m46dz#%"Vic ^]="NTE Y!>^P Z4ɎƎ>uZ`uw|vg0)2{yjzX.jA.l]>sӦ{7ktx6nKk9Z)-c6eg4(-$eQ-<6_bdȘt'$X> vuBMOȨ#iBlW h5 t|}xqBB6 t: Z"+3َlG,ARrGL IrutPP(&]V&LKi5ȶXFGuBMh'd_E!)yk(pu2/= P m:]|,cBE9 k`84q3Dk]LdIk,Pv,W_(cN@z.yl$19QB(' P+ f09BQмe:} t)=uLubLubLuMk::::f9_Xm_rd)/_&H2|:l_}P`45\6dZ4XA4}B!u }t/6Jhq-7O V w+8!ĸF# uӅp=d(쭓I1sG8yazD^ӑ󛦙/x>^5\s78o}6ZyIlr^(IyJvihKLOe@z]y7<( !u͠l|Wiu(?&Xv#A9iN =Aǜ`Ufϫr= endstream endobj 2013 0 obj << /Length 1502 /Filter /FlateDecode >> stream xڥXo6_!l/20" li ]t@[MQ~w6vg•e&<~|QnxB$d<pNA0|VY4j/lާUt{ /I}S9zrr< E8TSq$@9/$w{@iǬvu .5a\Jh3x=[b=V (ʁBd,W~ػ]@njCQDUʸ0P&`:R5QHs1Z(, т =biuY؜uWi杂i!ɓ !wXB("'{y*R 'c1|W90_\\ሦ|w5`gxߓ$Li"e ,/Hۦ6[+d =N6W̏p/S Y?Xs k.+#Si 1cw`mڨ;Wpם)H oZ'U].f3,پÇ\dKv_|'E@ł,uFt S:7OOa Щ$=LFi/Jo7jfQir~ݯ2nI6/` G1¶boښ^'ȍ`I6dOރc6Iih*LĖΆuc%q6 nl&rgQJX兂 <:pJts¬Qll P@OO?:Y1'SO5A,{1bk17 HO]<z.bٶ)pΖZvYպ5$@$>}Us)W"RE}8v!9٦?ܨWhO&K#k٤>.'/2|9JEkj3ȷ )=!)ctk endstream endobj 2024 0 obj << /Length 1366 /Filter /FlateDecode >> stream xڭXn6}W~D IQmb m7ާMQ %.;98v`Qpfxfxf<: !ENLԙeZL7Qf3/.{MV2LPZ$"RCW7AĎOc Vj`a|E'OuJ?tTxSeܓ4E#˾S>>I i>vkQMsTD1\T^ Qz> q7BR,ڼ*U>QhimrfVKlWfBiB,͂oD?}aMC˭5 fz{?OVs7s"2+R:|\?dx!y@"q9b4E%g"SF]^H:|?|+n[),L]y4)9T.hEUtRO-xQ̄ĬG-Fhe1=- Q/ @ gҲ9M۞[Dߔ?PQ %Teգ|iCQrisz7Zv~x4nE5~1=;$y )q1>lngT/%:Ġeb+R'Y2)pPg@ y[/ G; |{;p.arDQN[5z3C?v:'(YdXi5UfzyqS֢]UYs~d̓StY[4x>ӬƦ LqԴS臞Aq  <{4<1Ȳs:rĂ>ԥ TM.4HpT$ܮv )F2wD khsdcc4 ص^ 1bx'l>w5j6386$'Iϛ"_䭪X0 a'." -*dN)= V.U+AhwQXܿ*a |lKes|jQ7Ig% ,$_d>hKs뼙.礌me IѼn>ЭgځG0͇0Bw@0O6foieW=ӱ:q endstream endobj 2035 0 obj << /Length 1620 /Filter /FlateDecode >> stream xڭXoH_rzTuNڸOmUaX;08 4`뤧HaYf73;c}vqE2gr92:z^@!4}N n̅:s;BysIG>EyФ=Bܹ;|jK([B0b>qX"C-4q"NZޕmYɔؽoܙe]g"'^*=6*lsUw"ǝGr>hu/Df:+{ˇ!)@QY^)#<7.3+j!W&>ߺ>gB$kM\L=ŝ= ûk]Aevsn?]E) )* cHY\J Qb cnTbf*Y,_(ړP.Kt P*RnRk116àn!c 8)Wim*yZY>"(H_q3k u}]-BD2L*Oſ49ރ d+mufpIcAf-p(DpZVS#Zly[a!Cܑk]~>vGQv)]~jZ|H-U(=sC Zab|D!2e \MrH(ŨKvG>\ʳ|(eXѪ̷X {̛Mgr@ ]"n"C ꋗ#8^ƨ:ո) ==ʻLooӓ"֢jYެX?##8AXs<D( ٙ@8Q0L}M}n6":@zY/s[i4,i6~{ *f6 ߒlUK 0f>FFSSHMuζ1vGWUE5I Ӷl:[fyV&,u C%͗뱀|']Ɍ"ˌ_5(.>;hۺVD9"{.Gj6(V{?!0Z4`0t=?z-9K8OQOn?uKQ5!-Gu ~~|Q-VpwTzKavqe]]aL2;"rp/%0qy3YhZWfi)z ٵI[;syAk3en"b݂htOpIu: `T߶lv޼:7.F|z~X ْ,_kX_*m' ~GLfU#pDCр©`?ؑ,zs5mYRz>/)ݶu˪5ϼ}oM7 'зQ#?gl3 endstream endobj 2044 0 obj << /Length 1417 /Filter /FlateDecode >> stream xڝW[O6~_DƎ$} T]!*`xbWU&0isr8};>6uoWܳ" &ƢK<.R"Z֝lkcNWEٮkH^?C;>XqW#{86#5rHw.uP| % 4#{’$4E춉l8 iQÛM7wP+⼓'R4 n|&/}dI'rSn6oFP,ep C;PBAI $M/%{kp~J?Rhzxwk>t闙(` ͵L3#>͈.s~rq3'-7x˓9S>J8813Zˈ7 9Nhdr͌҈< Kơ*OW{v[eCѧēR YL(RWl-%U%%qʣ#f=Csx `a?vkwF6 blWݠTrkw=A7DGUFُX͛ >H1"Ø% NWj> stream xڥX[۶~_#1KԭAibhm^JNe%pHYus`xrn̐~zu{kI@pΤJT@R8ML5\Dђ YDĊ)\!z#g±qb fSLz';-oLa.H)O(/እe{=}}x>@l#^ԇTIXPq#u-_whR?tM{s fz=N}럴N~|Ч[tU!DVKFY҈|eQF)pڍvWعng7vg&7$1ÏeA?i$2'3 s 6V4x/N,Vn?: =P)G{ Ȩn&J.X CBDG[;Ǣ{83cDQ/z9_~ ,Q]Բ^RƢז^>ѿˉ.{bSI4-Zzre£X.#N:FqCT>8hsv U^!2$PF{LGp``g;S:Q[*h`C;bF*?ʹsB`OkMX&!6M'Ԧ&Z{O bD;nqeI68fCKu0MeN0 2`uA;ф|')D$ e(t /g1z5:G+?лh%b<"hٵ-XLUZ&vM ^#v9;ާseW_%uд~_X CS#H$O fSi>oe_IpI ~R&\BM~]MEB^@n#V'!,|"<ƞ  plU#.bAmNM]RH7a`H8go]aU q'jk;Cl+?uM!GV &%V}=F!sƳԳSKa* D,  EfM@dFDP.VE2( 5Y͑8a[PwDhfN#Ǔ@QvB.Gt)f KW?NuoL$$3!Ţr]X ~N D#9E b>4R>`RyK/J /Qk,Vb@U|5}m[(hTd:V4U4=W4B%h$sEE ^UVЗB=5;)R5O?OTf'1usW6G^o]eCb}R AP>͍repˏm <.@cݾ)#/:*ĽZxZm@kyvmY M/hd>QSǩ"4R^c]l-E'7X7K>vv`D6Ҿ AλSmn}{C_2駆ތd )Vȇ-j7kAK1|*!]oE?w.{)Ek^cWDn>a{hꜥHC~9t5iR΂i_y^*0BPwtc=7xfBSʜԊ%-jVlh8 endstream endobj 2069 0 obj << /Length 1434 /Filter /FlateDecode >> stream xXo6_!x)+]$fXD'\e}HR-.b/{xb:׎sb(pK.py|ɂpAr.Ɵ{%]H)_ \kBO,j3"/dΨZr"%a .q'~ux5}=}17|>WԐX o XOwO^]U#vh"iF֏ ՙ*? WAVӂ&CXB0~Y̥%o(7TicNjp |ma.856;t2y pzc^Ɛk"$u3$/Ԑ%״Kī׆gƊ.,{YJj0. uM{d/Z%\=& b1<{؄~X>%ݞa  _[ آ 2 ťƋrɖ]h.gi+'5d}O;`UēJ:u@îJᇡ^q{  xo>3盩uУadtڅ u?xrBO"rgԙ`$bglOG܇lOjPoyxIeI]e}&6EP!M4-G}̖%+[}kTV3uLST}|~x.,'9$EιJ!m::2k}ʭ$ާ?#Yi#prej1zj\V ڲbj9zkv8]1lIO&|p;]fB(t'I?9ős_fkgrTMw*CZӝr"Aa ֤Î0qtMt5IZ1yX?ʳlA1rGۊ Y?TTC=! d`|>SI3[vjԸjD 3WJ11GwcG ;32x* /倪qjқ endstream endobj 2079 0 obj << /Length 1978 /Filter /FlateDecode >> stream xڭX[o6~ϯ0Y5CX,4˿9<$-9JC"\s1"\xxNFH݂!QH9gK$˿ֿzID3}N}-W][uso%agt{njqX4ur0`'rwW"a1OUap3tOE8DBBdۍ厦u|H8biG=)/SCaTyj hmmҴ('Yv4;BVA3gFMYxV4 f:fdtdȃw V% -a7M<]W7y'؄O UE`;iXJ\閛b'Ds4cwO8;ϵ* QrgZ4=(rULc;:S[?gpK2M1Ǽ2qx!`L42>"Psh D9Р?Nd7L[@UwUƾbOc@i {b10&cN1{?) ## -ЍdGɄ,Lдzht[ Y)hMM"Fp>ø vg"9'kgGv|nاo{5׭uǿ*ݛ+7')R5'v46rS.y}e^p=W5NwCM uhoe1T@r/" ^ײ׳=9D࠭jup6;:C;Q%гRXd稙%"s"#y`sl۩;3h`iYQLYnj k{xC'm:nv+H *9_]>qG` gDG~R"%R%xs$o@GDKI{w@kgYz6n v,ԡ'xhlTQ 's}Vc~c =$$mK95X.PK.gv}Q; endstream endobj 2089 0 obj << /Length 409 /Filter /FlateDecode >> stream xT]O0}W4as'3I}(бF6RH܋>{ۜ{[e+a:6-`#[~:|NҜei}z#lԘS`V-z#NLհX3b˒(ИϰL$(r AW*VO9Y!k2bQpiE{*"$Tf/2)Ԋ.a9 h"amV;YZM61^ hS$HsTn*FUI8Kr\崰Ҙpr$ɢJ=Č&JTnJ,l#!{ꍯ`?$Mr#p0j;޿pբ`hO)_GW>i endstream endobj 2009 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1739 /Filter /FlateDecode >> stream xY[oSG~e;] U*DiD `Fl4Nr@9{3;YSk5@@lrK!TB)R -X l%QjFhZPTWR_S7OBc'L}Q iRq ,P$#2` %+TV38} 8 )WPK;!kSk?DuɮK snd5̀L]RC.pq+ۤA즩BBaJD8|7j ,L\%M2,~RL8|ƜxH ,>~pZzڨYjA2$L9r©Jprٿc E "9`IN:USA\"NUw#Pw?{ J =CϚ FbK+0Z2y8ikO K)%n*-`d!  Ƶmha|X'_by:]Hr ux>MD(Sj0> a|yfO_~>>׳7w#}H[dMu?׈:Mr6{U)ə< ~# wUGi^^ :Z!3C4 ]R tVEG04qx1_wc{VzqO$mc1$1zʖ?`O:ENNGGnQ{tu^QOCΫ%N+0eyy` '\(Hdz!0[ #b',EQah65hTu^Rh@4YEp63c&A1`ۊ|.\o> stream x][o6~c,xٷ6{؀vb;mŶ,(Hcxx9\gg/Q# 2Žm' L(ei?}~a2̿w/SH-JzWDz,P(J?|bǏ4%R?>TO0A kdEn1$)qlVʘBiI떊5eIXS7yन۬}נag#T޼|tVG#';DU0O]zR]ڵdŇ,:D%!|ExYҪI%ig¨TazYY6q,=}mj n>Ő` ްozgoS-քxn򒃄w_%h~;‚h_e󹑴q0iKk5yuOtL (`=bF1Ixio%1 4](Dx+nh>ϩ `60 {ᷝvLl˫Hn@6m7jҕ7ѵ^,;WRDl2׾h:Wⅲvc'TD9e(fԁ9kyhm GX[Q&fx(x'^?DW=uЇ ڡ́06H+ɠM)R;pʵZT$,U[mb~ ;w8H~'Uu?˳|X8Û?Gŷ1Tj#K̜6oDbjU8:\O'|Pt ^4H JgN"hǕjl1?@NX/iCE@e0pL| ƨgTw(hy6˖4úYYU8;it e$`#a*FME cP!NEjbv,ʴu)з$4s Z|UѿƾW]Ju=&C&Q~ԾIJNۊj0UûU+l8׊m7!ΚMeV"e-dS,|5jLjdx|Cf{[TH"C1@J#A)o5d.B ,<g\Zuœp "V%ƶ9OlCU#,p 6`y@hފUäkͺgx]]{,#'Ө{OJ}"T"H> stream xڽM+xL.ͪ  c/#d29s|$ {roiZjoY=JYo`RJo`{kd[-X.)H`uOފ5 i/[9 IV JRV xTsR$z9},Yk!'rAL!6!7ϕP46ktb){CI+J)5ub\v)oP%JZs5{oBt>}h Ůn9bB]45lE-8Uj ޯO^1#>i>cJLƜDI2fŻb_oVo>.>tLaM2z{!>Ǵ͗nO+izo)i[cZ|/9WKs\,޲x{6״EoH{y _/O__$j<=>2^k~NO.D=]-Ks4FiF5z9PF#4 JrD9Q(G#rDYPeAYPeAYPeEYQVeEYQVeEP6 eCP6 eCP6 rB9PN(' rF9Q(g3rF\P.( rA\P(W+rE\Q(W e0a0`# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *                                                                                                O_|K>=???=O/>t/}}?돟{˷o/uyǾ ޅo?~1<) oQֶI9nsߠl}{l8 MdQ=v_)g&l`&$mxaBUƃ# Vimh&H0b!BmDg&R^O8wG˟FriOƹ1SKѨ"#dS  C {J \y `yZ`,Wh> stream xڽM%WL6%'HYލQE>oqn|}eix>LB LxXi9d!oX0SoP>-P2tE k6oI\{KʁjN޲![>:eoyZ`>s&ѴqR0@LxPq J?j\z$S*s0a!1|,AY|<99~Ԥ+A~5hm>/(K ̟3p*> |ѐ9 {? eOJԜ^j0+2fC^$Ç)<חk|O_~ק_?&(C㯏=?>5|D/?| ~ߟ"7߼ Mkf(Tb z03 $m5cbq%h섨9Z}m = 0}~B7OQNHx#'BT/@F1uSq@_hwD?it)k(NV&WƱ[UAhD,OIX)aY*߿..@lJ)o dC[:` 9/@Y3\V@L #+ rCVKS9W&t ]p iߪO|!/w[MoRkz;_=q̾z2NyǞj9 *f S&e^3ؚ 8NnzbTA%*zbg%6ń/M ykHP:tɰA.IO)vJv"z2I,V;%V"3-_ +OK^Oy˿- t_7flk/^j>!zF0!#p"'}cYP9ǍaiW [aX%1nbX%DaW[]bX%aX%PdYqsbX%D/ V0 j./!f^q endstream endobj 2507 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1851 /Filter /FlateDecode >> stream xڽn7 ~ -Qui j %(q}CozxÖ}4oqRCJ=bAܫ$Hj:(A cBOE=P:=`De7s=ds?Bt1Mx*\ކէ_pux_ $pPA1-d( ę Q3u N.gC@Ƚ{ :e"#A!Xn GF@8OUB!:whx 9anpO#e 4Y҃`^q qlBplcq$z'|eP+F^Bo2tF>qBC} !rU`(+pB0; $p֙(w2ŕbFmGAwriL ?]h_Fq.VVAnK$N+$\xb:C;l(#N"\8"DE72vE[ˋW b1_x[k0p!0 W!\eQTi;ʂ݀V4ZAdנ3, ⑮ !`FF;VzFFMA93Ƅ@-EMYY#۱4Z?oY%9>K$HJ[$BȆpyBXw,n =eq,BaY܅ؐōǰƄxz3 Y?,>ΞmC7ZYY m}}[Qou}v"Xc~ƭAƭUԸ ָu터ƭ q;!qA터ƭ q;!qBoNkz 9nExn9n'Yݺ 5$mHEpi3io&mP7l`[!P\Θ 9Å-9Çd3NY껿[]&KB6 LDJei &KY)KA֟<9> stream xڽKo5^㻥R X*\"ڪ* =8n8sHMs{m'A.Ft"75s#;B+7s6Sݍ8B).Qhg<ĭʭVq q:}k.~0Ji3 5na3B*.Qc> ]*m.zh\oy6G|5A9bGэ*Xm7JQ໣67enia VVޔx y`r u AMah } ZDyV)DZhb6*6 9XڴhLtô"MuӴPls l9fm 3c RCR"~|rpyozx. 3_.?\~|懇Ov!>4T{|t7;_|D_WπO0#IgH )zXb3YbHg2)ЁlVd̰r *ݧOhݷ_&Wn[;vpVBl+a` 0o"5Se@!K^o)un/7R*]*C,Cd{!YB a)-w;Rk*o@R v@ZR4SE%B_!/K%UKI%B_ځ23%eh-93- % ,83^",^a "!>f | 3aY DqKKh 4wI@櫬2Khdb1 O 0_S $>5˳!BOT!Nħ@H|94|yۦ1p@eCVؙ8n@*[ De'lQ*D<BT lAXJ"(V۵x KC0MًG_mW"f2:b9fX'e*ð?( L%0l#2TF tebL L8pC-=.ԃt2zؗ J a*fV Uul_7$KAنX%\8q#!V !o7:(܈oquT:Z?kSXeh[Ͱ*oV!l xC- x3- rzBBZ:%[ECe07dTJg!--"U|@b Hl![$[$6tT?:%ԭHlB{AHTl) "5Su+J Db*D [c=[. ߯wzeD@'A1 2Bcʈ~ endstream endobj 2934 0 obj << /Length 2357 /Filter /FlateDecode >> stream x]Ks6W &rkN$M촙i:٢6Jt$J)$A,,8v<>珞S2ί(#B@ q"O޼|}zLևi"rGq1vG`ӉGrp#YDhi$OoQT(4XS0T@GcrSҟ}Y3\sDFL ī.~_Lo<}YCF21KJ8Æ2L i)+'FE"bά>TDmn:Ռh$x].ׂq"Nw[&4U x1LkzZA"tF?żOObB*Y}c2k3n$n=$Ci ^? 0 N8@ !ϵiN!]MTx-]g,\E1q`! p+v\W~cg^DWCJ]x##Eӑ83PBl2&;x`J&PJj]JUuQϊ̗D p<`B1LvD)S}}jgL؏=~KPC+ X;T.]ߧ졥vƄk<iVC cDIφp]CyR&׈xCkDc)mj|&֦G-mrl NdhRgNv5´R'TW7?CUQr v pzƥz Q9Ige`kWl] $JLCf6UhU|(#o0 W=;x060ZtG2 endstream endobj 2509 0 obj << /Type /ObjStm /N 100 /First 1038 /Length 3016 /Filter /FlateDecode >> stream xڽK%F+rio @60XZf!Kb4;Nh^T5Lܫ_~'Q5*mBi\ j(fB:zM "5dB%Qk&R M[HC3~nE#\e hQ%og>#NDgTB1k]xԂ>n-![%C>u1Si,SۍT4Vk.P<{gˌgK[yfZykYzklV6>⭕ܧJyxk̿2" VZ}jIZom[h^ηIAjxx疒yk5g~뭵 znm2G:7O>=%r4=x9u꺽ܽgynzk*[~=]w~no61oL1'Ig˼9ҷqs=1|^?݅߿xs/}{s>M^1һ?˷yps>XT1̕[~իpu7],n,4yy4N4!%z= =фjL3/1ag}pM'ܘY&jWOեny g^(ד&׶YR]?|YS>}}7n|:~s}Koǟ焹~v|n<|_֫Si$?\6N?۴F{s A||S*A#BF@[rA\P.( rE\Q(W+rEPn(7 rCPn(w;rGQ(w;ʂ,( ʂ,( ʂ(+ʊ(+ʊ(+ʆl(ʆl(ʆ>W^2 JL>e;>^ƃz܃0ۣ ʃ]PvGZy *ęUXDKў'Vj[Cqn&N,[Ä8.&N|Ty8sĉO\"q-WS=1c rxK 킂Vs+iYA`j4!Q.&r ę ۣ\bb/KWK!r+xri-(Kr ʄ n(K>f||ߟ:ggoo-O-Jvͱ7ӳS{3=4|J ݫ是>8Wg9y a+K,ʃ><'2KgMKg"88yB4QN}R(ՋUgpq暮裉K{FZ/K>e_ԕge$Χ^ GZm6<~2saR2qޏñ4qEN|R0k5sxDq>*>O/Z)a\9̟8 )Wt~0?ACIәMdߚY(g|}|g`mI$(' 4ʩ"">g9~|So]mh/pp}'񇉇ZpA<,KgPqq؏#&z:d7q R Fz~jF ׷.7aT}z~Rf{{X3biኄc0}a}.-s}ľ\>smB}&ęxħI^Zk7>ΞUB'̞fϵ  ʥ Xbb=& EM0?\}&}.=r#>ϵrsm0?\6bɘrGDnrAC\Z %(+=_P.1A\_LriB?.lU}XUA: endstream endobj 2936 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1834 /Filter /FlateDecode >> stream xڽK\7+L6jJ '$U"B6YZR{cW/aPOߖ>-ꉹe\̭8ި. q7h.Gk r6khܴQ'2ISڪQH^GQXbˆ, L1H_f텀Q_Z0t4t$z] Y;(S8WDd5$ cČ@T7(G?+.qRj:ZR-*.I]Q218#Mrrfq4g 1Mubץ0-C:#L$X#+Gc%bt!F^g/l`ÄdCF̾[^B-}we !x#7 2m3čk@ jfBʩleT6BanW430!xPIgA4S-T.(WbR$;K-P*b&$O!Cyv UP- weڨT/xAAO.-KDVؙAI; v2C!rb1C"RA$He#-$,vc(ЈtG^n¾'yY!rG^n}!xkͱ=|]0̵ Q1C!NrNMLvOMa,ϝPMLrQMiL9`&T')z)%.=oj`,2q>J|(2 [(2MQd"bE&/2-Qd!diA" ؍"ӂE&"/2-kf8a찉Дq8pu& [73W7{(4uWLv i,tl0 Gg"n LCg2C7vZôs&C=b(o_GQks1]ŐNCYJٚr2̛a1b ᄥ R',儘҄8a)'ĴK9!4!NX 1,pRF,LpW䱞rA\MpT.*MU.i+-ߊrB,_iBrALciB~c :,ô&D_uYbT4Zydq!p8!fц8Pu\hC:.Qu!TĨ:aTmU16 'Q*vTDv; ᄓIҷ !l endstream endobj 2937 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1926 /Filter /FlateDecode >> stream xڽM )|L..K`X$rm!/Cek.*]0Svٿd=\G )p5P:hx:!/#L[JV7`aA*H(o,MK:jʘ@j#P/:R10X#p):^-m |9O<,5HwKN|4B8m)drJ9乼.9 ڜWy-˜׃8)Iw)H &nKsBG.8c"F5ar 9glѳ')Qu_PӘ#=$C 56!->O-tUt^Ņu=v+E?yɡi|FJ =uD0milG˴GMivˆCLk#$9j5]~:d8bQEpt']00QG?MMcIg6ޜToFnڴ ( 6ׅ 4Cg Jt# =KE8Mu4\x؍!v>4i&,C}v?} ?u~}7_~ǧ?&(C?~o?FC-T[̺8n"y߇p¯~??E)}??SC >Ã!Ǯ4I?s}#U[ئ96BUDKM >j5DU5&9"_ffCpBl{yApBl84; "#64{;tC8j@q&q;b#: a M,PiQ`F oQ T*.TY /}"Q!Z{DOQKJ!Gd\(6 EBB1wFh @5;eBP-ANctOb ´҅byA҅jK҃('Nyt뮴>ˁa6<҆AXp!Ɓa6Z.rN>d|_\ V p1.ÉRBN.cʋ29ei;ըO6P~Ml`(`) (=Qpq=Qp!‚([s' @5;s~Woy-N|mQsAܓp"yeOH4Sl@ V|%ʟa ԃؚ@-o@,h^{W.弶Ns]םe2"H a4L1wyI{Xxz ;{+< Ӆ8Ч3.ā>݂t!ĽO2pߧ[ W·}q|O > @5| ޳r1Z\ɥ!' L.]z@./%.D? arAl>KexɃ%+@CEe%^of$0>]B 8z@0!kTU^|%ݲŰ1,5 ¬B<̈ˇ5D$>s;R*@к_R9/}֟ʝuS-}0κNnY}מp˝u]ejiQ:`j(kʺ k.c>C9 wIЩة<27v†0T e1dT/f؛bT%wtRR+*l1 endstream endobj 2938 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1889 /Filter /FlateDecode >> stream xڽ͎\',m %'HYYYgE<,9)w͂ےe3c>ΝT{ 1%P&mԐ$kDcҵAvF =em@8V)08V TU@h?z+F[T0Qn:aB9u )%D)~"Q:/ sʇG?Lב QG? ejZ`|D[=p/BU_N{TCYg_XKJ%cJѯ"1 EOc(]71S 4s,0!2v%H-5Hk-Ԙ4v aiV-l>|%,mẂAkdxzkkV>fT>@6MߡU~BkU~~HAUY$tzɺ6ˈG:7lOI1q;J~j" )k6HXG*28){"F*H٨h60i1zDR1fK4RD)Ôx0و*RJhbE!;kGzx||pyLJ˛8w<\yӇp[_<\~~cxRžJƵ%w9 z&\9\ _ԯëW!Ue##|Rn0 ,`9*.Ge)rC!w⡵{ Lt|# k3<tpJlu$عqGġu/*bޯ cr~@pJN+DCKB6Bd r!vJDIb>( +S`jmS](:Qe˅ؙ1^Ӳ^^LEBQ*j8`QQ7 v*UũW L-]_. c_.ɥ !rA\u\.Kv\ &.C=!-F8U$QG0dvf%!]fe0Y.# fa[Y0 g>bA|>C#.D}A! >q4Q[ZO1}A'^ŲI>=a/AM;خJ%;HbQ!U]PX^[ύ,%: /wKtU:->wTaJAl3q1u. y[~f Œ !1s s y[0O,4mdҝU1$0>9+ #|@a#eh'c0 v?ZB{Z&?k2D=A-c8C-c :A- ҃H4SKOĵ_p>OʖPM)abN}b0rR.?ߙ v8pٙ vqDOLyJ^pkƌt=xq)o}q QhK1[3eH_Li(wzsiVbV&w- oB$m2`׋Ky`O]g>P?B_-i|-i\O[gKC0xЯ;=r1LG21LG"r!LG1  [ W.(]oW.(=?|r1|r.wjG8'ܲǰZUU O( pw cvrDi>_Ba0@bz5v>)7!MBF$pA}Z c endstream endobj 2968 0 obj << /Length 678 /Filter /FlateDecode >> stream xWn@}WcfG *B>l"%vpRU=[wfmPŊvfΞ3gKODh2s,)@̅BRE]i60 Xs{lB9c{uia{,s7QlSǫ{gX[p% OqTJb%*6)e8[&" |ibt(.b#i VuBT.$WCAJ)L/bsԔY~8_iA}0(@T00~uZBAJZZ`,qlAce1JxZΧ+B3Ɯ= *5rFy:~pZ{ZldU܁|!u ^F`e(^oVnw$]24T*̘CG3J-rd(#U{I^5*VcK=hWTp;pT{><1vZ@ 4e1tp? F?2΅kztڗ.6ߡ(8E.\E`-Nv[|vy:=U68RXbavoչ6B@QѼ2ln&]j /ɇf&#. endstream endobj 2939 0 obj << /Type /ObjStm /N 100 /First 961 /Length 1916 /Filter /FlateDecode >> stream xZM7rf&8 ̀Hb4^x~Ϲխz6UT"lm~薹uK%qH$=!dB{)ɝCTN[4IQ$JA$D$ #%FTBF V11R!##T@a.s D#9LYZ@f <9_){8__oow8~uwUA_CzΆ$FY4")rLOt]:>MO?_g^sRgĬ=)ц :gD-GҢ9<ۂ!Ġob T,}!Q0K-ڳ/t4iB0nከ Q9@\a!Q4[6RO{)=k `i%\wq 13 ԝjjdm I㬕f 3NOcBZzАA0lZ"2(qrgbpΰ5 Ev *% K ""8*%!%,q,ըkD@0rUr`AaӘow)7d\EH3 nAg d öD @J00k۷>~ %6kZ.iy1*M1,>/g/|4W̴B ޸ ظ7*k`ҌcW ?SVOQxq}/7cۇIXkzꙠ>~(E/_Bewo^=?}/O=ǯ]tSeb߿9;wX~~d''NG:>}'N6~W^ _)CcD A0ұtc-mhنfmhنfmhهf}hϚo ҈F!S B]2uY P U [ ءPro#1H"\Nl\DEтtK_J!g riN9H} sfU+iQSS1brĖBU@ɑDELLزY._^Ln Hv՝,1 1*߲RU:[TXq.UĐ?U`Unþe.k渴^s \mV% 7Q28ypl 0x*%70?C$BkFjSi6ѾWG HdxCbYv95 $1|((LG lO-yYAI+j.XB6 foh4iT;²\ť[2/}B,sUiU#Ii"&`(R-W1l8sC( Zʪ!WAQU,r G(ݺW7ٞ .Lbf^lNه=:eЖf7Cۇվ/) endstream endobj 2981 0 obj << /Length1 2910 /Length2 25761 /Length3 0 /Length 27178 /Filter /FlateDecode >> stream xڜTK-L=. q6Np.At>IUkDI^(a rgf`HmAֆNl*@3gkCxB?i!Ph-lA<: 1C'3h0sX9g067ZT vfNM->4FX5 l&pc6˰(NU;I?xyU֔_%rMqăB9Iс.+wqUh0G{!0PmReevs7u̮?ֹ@SPIbSc9Le:]Nt6>6kwI~?;>9jY2\iJ>ΜOqIXNJ(fTWyNF*t Iә$C )Q~A?𾮽}3Rn7t0i4([vU,k.e+YkT} JiU'յ6UM .R}˒@Tsn ~#d<{ 4* ݇=.'uVsco(([_N!9ep`U.4)|i4fIw@&chublQ8EJTbcB.$u"+^(J)'DyrM!6'MyOT /\#MrGʟyJ'׋(8\j X ٞőh>;@| f~1 :?:nyk-=ws%Vnh| u Ó2yt HL*L2D[{} dlCBD W*sevƧ~괒 kxz'}X[#ל,_Gtqȝc(-ܰ/+]K04!ؼ%B-P(g9Tm曹CneQH5z3?hEngȯ.R:yOZ$oX0TӅA װ=Q$Llwb4'X"shG6օc9{^˖XمL|)sjx}iB[jŮ)DXÒJkdkuRP#dAo8йt`էv%{ǽҸ|56wS"@OS@^2oNyK= Ҙ.Xַ؁ϊrȊMOUT+Rdki 511vEL )7{|eAH80 Rooɍk,Jhfgb㓶O+nΧ5cϜ_i{7oJB >,%HN"ỉ:CPG+QLhɯkW#IP7|Xy 4B%dCLih(!y::#zaTe9uO]r(o\^_Sr4{*z:tÀàmlnT &W0j4,a_QSOz[OM~i{7p1SB Yx*+^vvˌIR 5#*=}jg-Q2-t[8FYTGov+%q7 , 3w^}S'=ulhsb kΟŭwG?ilXkjȡoŃ0iV?( Y;PͣEQS#D7iC~%*4.Z\aF_O!Pvqo9[}Еds *:Vש'} A;dz|w^laE ˣHYCyS!5 $oLגkLjo0e)Ҳ}BS,cF amÄGK!]caB`jwj]sE H {0 [2qšS!AӭؐLirnmr7/fIt/vHݽҸ$}L_ή"fL0kqkGꦽO"/qȡ˖gcuD̙VSW;eE\Ĉl'̛hTZ=TeW䚉aʆUqL(au,SRΘzޱS|OTk0H5tηb=?;l|`gZLGܻ3ݱT"!ԡtq:}!wԕ }>Ui'V+qj8XX&[8q85\M6~V5l34͆ˁ;_vyPY@֞VOgtrܵs+Ċ)_?8W*odq|>#0IYV]b#r߹ |mK8[h*}aJnw(jr$DIyvVsqAPF@!Yx)ɀ51CkE;F;HPkstMSLxȮ 'C4}t$KMpAo? }< .#!rVG 3rovXY@;`ɑe㞋wRfh)N>!^"4U.m oh| b"L*w z"6q[23ltw3[R@H= zH6_Vt.|CP9GyzZ` /a[JB@) 7͙qzZOAlv[,ע|ނfWI1Gv aPԦH |eԈKŖN 18 =Zv oID aDT_r(/:冸SfqVO{|%Nn](=cv330SF0b%cԩsjo<ώލn) M 2 Jw`LD9SNѸso'psiD+6'b*t-]1i}<9dgm}HƷO\!e+8αԳ3ntp'".+ڣ2K}bOy>5rxS],,XpDiDQSK|_yg(Tg45E)G^tf#ŊVXhٿzEhO{ri썱V EY]9ӡxGuZT\Pzf] `m+! )$qz9,V|wЅZ[˃3$rSrNۉ_\ׂ85xe!(|nC)kXC6w:_Sp/'V(7eaQW5 Q;h!艹 ȷ:D^()<[*t3ۂ**X $~Or XsNU =FDj$}F4r,Q%jsCf,7Inh > _+ۗ>^͵"lǥNV?s+^d?}'\IEapB>u:{|˽IҷlvaB)We('4٫`X4'x?cF?C\2gB١K}TU"MsP8()fDDllPV7',qic,J"'~]ȫ<_ÄZUAg} U7fx7[XwRיxk]yqYwݛ]tˊNpvFfFǵ1iio~&ܹ:5Cz6\ZZBPUJ.ʀly;0mb&wFakOOn أ_ Muk@S_y@"!(%PkIE-)Eҁ3a裮ʑ'í )]&a怙vH:20&&UA{8O !'tKj-ck?vL3~DP3n:xcǡLu$cYC`:DkhN鎭{kcVFc Г•SNtm>-$uOʭZyuxnpOA]Z Ga !uw).Bg~㨧_[y&p YGgh="*7+gZ+F $'d OSO,LT;^Nf%[4L?OsUH 3,k_C<=Xk۾U *mQw+d˙[5oT /eQ[-?0ϱR.e2vI DdiG2|F^׎YʶB*OcD@KltzޯB #`,f ktq~IdZ_% ?ΰ=37E?og.dfaUG0 m lEP/ʆ:CYQxqox롪)qs+B m(I!-Êwkzq+v!. Lwj͛%3[^qq]ځj=a${G^}(eq`Inl!-FA2ЌtƧ~ ,#f 9%y.XQ0t\D,忈MYZWؙs.:賳Bb(O;w'4_O_$g*'ƞR:Bik Y)<3×CV`4~lSV`&YBC(t#i:IV+{"oQ ٧fĜ\\pؤh ,'˳Wha䬒X( H&⢮ 72Ɇܿhp"jRs΅>2dzgK0gB ÏVnJ}}KL״DoR/Le8'X`Eu\5.q& qo+i).U(ek\)ň+[`^PG?:Lwb{UreHZ' W`U2 i0PRFZ DtNY?:Egfq]0Y!B&=?دl_M8wzd'ij5fCH2XtW>T%E+̾dd@_r\@8:\FY PCsq״ػ+~ed%cV8S?׃>gC{Z70XaQ$;Mgxl[Oٿ{UOOa䠑|eT>oDVLM_6A٘rA>2Wߖ4Z㑹 SH8ZR^R:7b6,YIƨۗkg/Io0֨n G.Qs:>TfB⾣\\rwU[~|㝃 il=j>=}fke❾Tв%E~FI0h~r"4)ШD''g)ֶ(D8ʚ;N9#ڙ䄳Q@%e`L^{;s;YnV*SR!q1&<mW+> h7*:V)I[UrCi%@'F=yB"Bwl:,8Zy59* l+eWpxƻ.UYN!3LuFr~\At@XSb5> }yb @yhw"~nd?E`gT1#lŲЯK\O:(;08( :|$J\_B^Z)IsG|hE1EEw Ls|,g B6>HUt r0aj[ju4s-ʬw =$#x%xKPk=r69?~=n=JE_L  ojc撊IC~n;NZN8˸_^24Mcsq)o9\i7θk+$W6wd )-,6Dz*.c˅ޅ#D@EX*Yi ;մO:$qܥp鴾PZio`s}x)a.2g6W|΃{DAVsfeSjc1_'_&ngg|PO#YY]Ywf{T}^~ 5TY.F9h?4FSBQ*C;~BU|Qw'h颣g+,-bJhg2k&u^(F:''v%uq0RyjOO`"` H |us6l_wD"YMG }n;AuGRᙾ1׮نS2Ya~.{(8V4=@x+C[^I5λ S5n= 4rFnMsHkQC'If9Q?Ŀ]4?EMUYCWY)>ގדh >lD'k\~&kvfKdGC.{t6(}ulcԘX'#nG+8BrT4W=9}ccJ>o@gPLx6F>[ֺ6tzI %8K~ޤ(ݨB>v5NB^Ԯpl1ӡVe/.'OZ?F̐>U.̙$ae)Za9_&aZ" 7ZoA(qͷYg%6 |%$8ek9b%B)[9Dz<}m U[hA^dg&'Jje{{9!*O ݂!bWYd凞 0h]QTf M=Tn^""Cx2$CbkJ BTF,aUKnXʶ`w5tMO3G| ,]yJ 7,ronZKYv[($(1ULb } "B Vyy M⚚:Q^9}SOo2pr; ,`E8z V-޷2\'2vNMJW7*Der)#a+cudA;`|[ڎjz>X_-Y2ß5*AU"m!Aӓ?0:5xBt ZtP3֤|=* yK YTCʔ T;x}:O|lgIiCyH3cS Kx'j7(9 ̨g*>SQGK2;X$Ne" >W=kNgR河^ݮk@u`d~T B?Ȓݿy~NhR\gi @2wv߅&ƏߎEvf.U)-eɴ<>;u`|Q!ƢwAypc:ZWj8 ga^VIܙm,鸀149^˘Yo5<Ń6PļDD #$0'~ECsǑ@ul9D1JA'Ķ٩+ntNʢ_CL~z&#\w:wQKZ,*{a9~cuhE޻P87], ndR+/O Fm D]v ?\?Uy`zO"mP=7弍ocq]2F!nБBCQٻg'G6~M$"hPHD3Ѡ>[XDf6DTa/ 1^a%Cuޢ4ƪM)ag]~"ca4 _.&/=V-C9$i^Av&G^a{ӷAޱGʔ5r~o3bXl,,+Uɐ6&Ir2BQϮ+R<& B4v̯SI\}YGVNlD`5ZO\йƲ 0й {UmW0|ZP@CbAFG#x¨Ӂ׉:Mu@-l`A"RAn:~T˃_OfTi59]bHL_-t^7׀Yq [ձn;Gn `!vZ',F47` R8I&MN23S#__ kHQDPUx|X_ +굪:& ]z`f8Fcmp6wCt^76 9{ 1Se؟u:ooSGG<PnQ7XN+>7,~v5NÐ7!$< ڹ/ ?7D{McqQj뇰;_-ea1BhJ.NSxD$5ɑ mTy2Z}j[|Y U&̷Ό c`8Ki'LcU(V:g!v_$ Vh-Km,3`(Q7&'Wf#v |_Tcc A'[2T2v U): 4G_L2DcZgPyL~yJTK/03& 6 ~S2_3aIz͵(Q0%)N$1gYmJ;+9A/ /"+g46Ϋ|_ꑖޑB,' vvg!d`B^3UBݩFM3"|[.X9n$dsӹBDY6OɳRe8gQ9vnI7yRDPVKIR`L ƄYK)}L !+ {]{)kwɞ{3A 5Bԡ*®tfi9/riҊxׂ[.$}!vꅠc.Sv/683>5H,iZR]xX7[Fkkrzո`  y,"މaNmW5<}K.{O_햓[]uf+!DXkܺ(͈u*֟~ E\%jMFLڊ4g< ̇_#s[>~y]q֟q1e|Ywzsz?Ձ&R/,_sχdv;;W2H0SsxS1z} *%O-.:JVgC,TH1p045=MoD@Y,xé KbH[>:zrt-?? ]M,&E1E4ݱ`aĺk0q?mP5N7Z@1XGS*A[UTa0i_s1: \ȱa5،Ʒ2"9Ӌ'QǼx(+_k}IRH{n-|jċwNhV8CobpaRU=UÐY/z(F -NJFDWA 1Il絔yCm :SEBLdk9M攄bLAG8DDqƥR4Lɑyk f\rx>-@|v,`^ QZ2Y|dowFN)FRS}/ϡ6:L`6b@!`a ʗ>Zʄ1"u%-HĦ1e_E$hU]^3hbX4(MF.b?IRP h6-DKs? I!"Y.!¶%KO n{Ʋo*v]B v$& Ҵ%_0KN~++yYn$4;@i xyǹt% )Y~kWm& J$UD..eܲOab :x6_Ls4W gNfz~jLVtS_B:OQ}N51D id7C[jff%X8 "7:sD(dKoǍdfWq;~pܕ%ՕWًCh1MhiOFY_]Mت8pDW|s*I5hL:"mŚgʕEh\^#lsیW(RYRO/iW? ѺCjm:"?j5MPSBDFبWTz}$`\༬ahRJY)r<: tVRp} QPj[iOD7#|0L;}fG$V<}v3T@WU\U8u`S4(A! Q)]0 +}^4KH2{kG@?T6=fk-$ l U)oDlIEcjyVZs[,v1`wݑU낈uKܺM6ײ@6kRDOJLCG"]eU@sc1T->x7v2s $FQѻt!`2:C:xQ1k_I"IfHsZU%t wxij$~qr~2az6UC^G(X2gR._iHr;l;D{Yu&*U+5R*d`lnvII蹝*RdE&Xb(mp"V'8e\f3?-xLBM̪H|';Ut܏a'=#&=&c}>ֽʖ[3Z%[jI Tczuᢤ[ą Vr"h0dU>S Ӡ9ԧqݘ (ې+8RUlf!IQƀ [{9r8 [ 3=L %zq |pǠpAu09Ju[WP>I7KN$[,ד׿iuK"צ̨j=6ۍ݅[dIhi6rV7+Io7~QPK]0K5 V}=hjM- x>i*b& oEi':0D0iuFNFL#1f}i%fn{1.?G=\.§Uf5gf P*4Ei,vZ^9FDN>?*E%uNFlji1ZKWZ730Aki%_RIEÎEU!{je{?.5o:WF}IcɓseqwV%S<Y2+*>O: M]f=%_!=;.K`#"*ڛ;͠ϭ-P!,lJȣ?g]5S_wyG>V+x4G &-Tѻ H;/vjt0wGv5U+Ouse[: 8ǼmPI! SrmK7QVכ@ÿ}N5Sk*[P`͚I"}#1[Gmt6AzxR/=Ќv ӳbmf=5,<|S3wH\<=pl C:ܖH7Ըma%5N`kqQrB('=\'J(`mѧO2#S[/+DD:.Éi t 4Bf!Aո5!@H;O 8y>r/P/q貸 d7 "F'O>ܞ\3v4RH^N1 -!g'h=^I-&j%9CqT9ehI 6̝GaV@\gjƚzbu9)1gBo(-tM1iw9u|l'㪇b~FSaԈՎ?v X{0≓Yܔ/;CQ'fCߥԠ[fͲ^%a 8j^; 颌m!%#/pvul*Kt$UwBbK`Q lAX 98i/uSZZgbiZ pm=13Qc}ˬ6+i^:?xɪ>ê@2Or vZT !Y|ѶC6PLJ|^ʿ!$DY%(2mEڗ6RН:u;<>w :#T7l>| ɍjAyKCF9Y@2;ypZgk" V(Ƹ#- zӨI9DUkrrFQ,vCPOAc,`ɺp!Nk[[^ Y-"i'K y?<=r򎧏Ijұfِێ'JpSl]5]:W&sf˾tus~NkLg>:H1;mG 悱f]q-0x~.Rv%eGg6?֨`AR|-(7x#mfC}8y[0'е"ʵ R{j@ ֓QzoΛ&*,H`̵bvAb}@Ʌ_nlk{J/ 6:`r:Lz MuH]&3w_ոPT,%߸ӮAм s!ᓓ%A0ԫ*w [/0f QSֳm]4O]L 2$V 2*z?.þGW{kբ8ħƝ{>"<ě\wsnoNc跫YVdž d_[iIg7Ӥc6VŲQ%A9W"\Ո%BŤB4hMIuW|{ݴ8Ƃzi'gSCVP$}/&bJ><١t\}jb}޽H,‘ Çr۫d\xt xk!gQ**SPDQ|azfׂCu*;\yzQ?~YbwnE?i+:#h&nA5zKJFuñ!_MhOP(Y6{蝄os$Xb ^zYVQ S*rpZq$OEId_xb:P!;of"庬owgEcظ |R+P Uu*%7IH#iC~2YǶ Tm7jB8=ӗr9Պl',%@E\be.)v)7֖9/_(f>9K}FWT3x +S28&&>d~vb =aXzfS#jZ"@6mTj?lDSLWAܸ)"V>Fevm3}X0 eBߙ-zYs8z@qS!X6)*9")I1ͺ@Yw%ԃfoIj?$(Wڴj'\ޗy)pgM=>+>٢+AUZ7Y$Iۘ/FN(~/4. rzq=&U[> /T71}h;/oYwWTF*.?j;m0IrW݌r4!p["֬#F]Pxxh_t{(~S 5Ĩi';$=ň5\L2j7n"aFEchM}cYX"/)kUh ޔeOS[~`b#Pw>⑕JH; ǛwK=,T+Qoh$_}sR)I/eJ5lu$nԎgloX+Ȱx?X&-GfY;@ Ng})ǒ`Pk$.{p^h.|؅2.=E[t7ugu;)aӘ¢8c))zCbگԳ2vJ/V~KX,V=vn|9&HE.`\8#tFs`@ULv1W%6B/= 7gOj6r_>1vŠ6\1ڽ%FG|T߅C% QҊXDm'.xJIܦu 2,{a/ٗ eCgǼ(Tt#U׬dk暬 6Sv*nD 3Ԙ6b6W wRsH-yL:h?e"HW>-%0ևlp YuŒ1F# )e+C0֦U{s[jzJlj\]LG]'Dߗv ]˴ 4L 1TE+c&$Ng26{h:VjSS`"Aw=tM7 ¸3,u樮 },#gGt\,]XqYN0|r4d'AEGw+€rk ! 9#͵~XE'*z.2=.n5\{+_X)g"oG9kۂɍMA1m0 Rj*a [B1/fA,V0C ,R觱.@G'')W]B/ U;#ũیtrD7Fw7Gň߃s14 Ԕ2?rp>qkqƵRԑP]*l+:=ZpXĵAgH$PbX9WEqǼy ϧ]W4jXp>o\; 4{smSf6Nx-+`)qfS-ch̡Y/}rf)b`2GjJlD7Ebdq?IvbH'+,@'6Szcx+ 'nͿ'F@2*h|hEI% %˩8 Xꭓh'D>--`BzsN|x~v!o8aNoo v|5언TfX,0a/b8I0_;:H{eST w ^3OXqCSGuӐ54X_ot>Y&`دr" 7.Nbd4AOV+Uu7!9Xmt|"!ߋ&Sɕ$O]S=9=N"a /@PY.\WWgqS9qCm2j~'{Lc 1ބoYE\ĭe#Ch/ "H 0p8 mr"3jٷT^q VUQYny (ˤ7ȹhpƱ?-_z&FEP&I7me0RAo ah o?^8:6DO5q1kJ7Snѯ\5¹<=|g=dQqfקi)B'Fc/7*64Ã%dDG/pZbлZS7-upfu2fAV.FEa|~DfS$T_r#2Wuj b)7D ˒aְ]`J5&h Q]"WG|}j9n>~ ZMY#Hq'2[г/&_8Y;|nI /)M߷.ڂ:#~&3'X#)Eb |1_ pӄ7#ϩiv"UT:GI+tm*a垼W rh`$gZJ 0HMZ  N@u&9- oX*]<8a ǵqBz ?,I+yo@$$֩;>O r\I,?a:bhVY8y> stream xuSyQa"AXHx\dDg"B+1+|&WY#]AĆ#t rt&TA>Z4s:¢gBvP#X4L,SB ]3i̜!>@͝[q?,fδ6Ptw'alPXp+c62@gH4Lx`Ѹp;џb B;E`B !@5|SGa5 V ku^(o>H0fn_T06x)"o1WB;Blľ  îWALd3Ep?5wO-47˝dq\xӽsiiWsYw! 10uL 2)5,fμ87 `px.1"`P @7C0sN0aB0 Q̯4xf.=eςAp+P/AIg'ϐc0nYXm,Zn+t^fD6r)m`9o9L{c" j湥i0=gCT~Ф5EkcϝWFWO;T&#񺓛Qz|%1͏(u#%[҅S.x^Ѡ[ꨂJvU}E*&6޼d(۴dzt̬]ӣ뫻5S^ّX}Dkm60dx0t~zli^Kɚv󶞆{k'֩#%ILf=?x$6wjVurhu(237k<]iu4Mтָ'" ^&?S^PZo#fn=q-ޞ'IS 6Ɖg'v5+:+E-%F#/7삯O$1w_H\W8PAݓҨ@BT9>2hZJ?U7[qf*L&\꺪#oXl-Aih\Fѹw)}ʭDءx5{b 2+: M%w:~uxe[ؤ=j*/ާ z:V]q[e"Y)sa@&YDtd[~Lwp[:eMY1uX|ƹڪ~9qluL,a$+o[{$mr>[4|x~p7>Qi\XZT< 0\8e@<2}llDUޭ\Q=D-)p#1ve9k|U\3)J)}AؾގWuЉ<گ4kli3[}!FW7=81&A[%E R9etI犓%?Hd)g֍{}:drވ>~s@ҞhReQ? {#nq69WxKKԇn7r겜p=*VmI.xu$ #c|?M>ՙe:Y`{Yt2C eͺiۍ{6i8U捞5 K֭^]%+ ڍ#VE\~E"Pk~%lLs+ęyoj UVHF`iͶ8QO 6kKZ$M sSC] ąhv~B1Ja:`:>LcKRa-4&w([nR(UK}5*a㧬'R4>o R:`4V̷(2語rnxjo \s͓T҅ اPPhy`#qRãvEjA fR[SiNuC%eNy՝թsG9޷h{cdE>!Gm,)hi|-M7Q21dՈDZêhEm 쩒\h endstream endobj 2985 0 obj << /Length1 1626 /Length2 12972 /Length3 0 /Length 13813 /Filter /FlateDecode >> stream xڭueT.NpkNpww iqi A /{9Νgk}oSTUS1ٛL,|%=" xs"QQ; {; c0 4HMllV^^^$* Pդc`O_&Լ{:,_6@;{[  @\YE[VI@+m*.&6 Sh ;lۙ*͙=34L>N go`dl~3q1 o@N`*`gS'UEB8r;{wK3{SJ[] 69@7_L3{`Na8, hadftv~Noo  1gBbe{i ~mCbkVd,8+53t lf@s$f%{{Je-[#_9oKZF}qcG~g bl q9&hmU' 6~o;-,L,@n@3`nlޯvf@'׿[ `dea%/8ڙ+wϬ(#&?׿ Uއ?JQ7_a\<Fv{?;?ߊ`'@nֿ?_F쯱QۙO R89Wgt"-ٛX%&+2F$t:Xs~ٷ$l=2Ռ69tд'ϲ>u\nfc6GM>֌Nk.;⮴, TUک%TP^ܛ***B. Cޮ;MTڿPpVny$愾k'5ⓨ_^[)= ,mTv:4LbĆ,$wg }ffqC\zn`tXxzhH`Ã9pbpRie񵻩?KRZ3V( zCm>+9dx <(0Y;5esL,WSH-:u=Wo%)rˢl}5I E:ح?*sgV *{U=& =AωsT;l%qp [y!6˥V *@)ƇmPtS>4wkZ穳}Iv݊ VnƜ E⑩( <,jtM回y +]]7>!Xl [4eØ69 ?rZ:1#Θ=ĩ̑ŊnϜCe|1vAehnQ[isY! \6^X]HSZ8@_GJA׾'gp(mk1CJnGXT:\+- @v>Vrb\a@fJP:nRrGyЭ=@EH2, %bM|CKKL(%D5XrJÈ₉S ΔV7Uw!˷߿~d @ZyuP%:I,UMEϤZY _xp_×T^8zxMx{cI; oHlj!"JM'2W]'eOY $Ha^}3ʹEZBKdc|$G9웍ܾz毁0?gkiVM;)v7=mg{7Q ł*Zws?K, .ZiI寻ˠ`#> A-U)yٗ.߇x>2]߼P`/ "⡡Q8R1Ko1P~,K/A9rm6A'!b?v@-2Zfd@H{9W` 6.Vl&ߜd&25'ҿAs=ԟ4ְ7GIa eV?70Zv߹ +Jxdp`^P=G+̚`Y}ښ &SsB` ڿB^d K|?#m',d jxoJ-xɚY =DVR?nKM7u)"[y6Ï=e$?4V wV;=w'?W-2kʒ lRsD9;EGvK^ߺp=йRxY(YP-\2 c:rZigcLIcPsQ?3 96$ Lo\kd%>67+ӯ 6d۟`fRr%|q*_,ڈqҌ*V?P*}fxTл- ȉ 7_D-졕kiB{5{A]nϞBnEz~=&pg`\VGA \JQ}w)93ZoR5NL`dogMu}9ġtL XyKI*Rsss ]K}vn }y`5KnM۸ d&'HGZb$JN*hҎ(~ʝq{˘q32?A(Kڄ,($Z7epDkr~@hM[IQ݁uC BNrlvO*LMϳ2m(bhefwZ~鰼gָ}$Ll't#GvZ箣g¨6,3D& Tq4)kk N|jWaCqy=^'7I{yv>F-Op] .Fhgы+bbt6(` ,@nK-92NH(N۷H1E{DF8hH+dӚM?E3>ٻ'p+HuC7\{m ipd7bW'A$GM`o1۪2 A4>ɧքnfZ8R ggCWrF:Iu*6auH\>էw{& '孻%t? {R7V$TnI*o#nYczrr= m\ܦ"qS+HjM(Ԟ0,+_m[/cjY2F-U{DjmNĭdD@ W/ <;?tF5PT\#իL rB4<]er zR Fn@]m\O3N?[߁/bCx?V;$)Ϫ6_~l6*tB&t8|6+M{LlyYq/("Iz|NC [ZklwSR8> ob0ޡ-7Lkhac-,l(#Iu 몦a5f1M9Qa<(+I:,0&'K==)PuRb9s۫[hUcAfC@ih4_~7[Nbc1-1o`ݾi3vxT_Ѣa˦iXP- ) UWhQ4dQG3틹G*tW.w}8R:%0Wjg()`c,'41:+k2f_>.aUY~J!^jcL\o3`WSI2I^Up&T[3x )86P{lMP2ہ)!ʏtnph}.Tٻ*.ݡ4-)54>/#8y(D%B/$BZ Lh MB}]4^by$^>~nmU:YԒlV?iڕiFqYy`rjEa$^;WSTGOHX4c[U-:IHKCoͪ֎`z1m<5Y?\^ X3Bj\nmV:$ʠIϠaT+`>qt+LǷ ٻQw-  ady$q7(pɵ5ms eM:i4"6[tU٘ jQV}U|Rsik6gԮeR;1Wh>^RM K{U=21 u_6D?jw6kKɑB\xTzfҘTL?":IK^?:EꛨQ Mr lFyى-hI@ͽXnS&bGZ-0QR.qId.5+ro]M #E_Uyz^yF(ϕ%Q5Lي3g^QO[}jMS59 k^/Q\_8p7D$6=JmOƷbm4_iAY!>BF /y&z,5)#Ml$4NxgJ\_ ( OڗkCFnA2jgXD,ٚ ѣz;-׫L-cP' eM1nLp lyQH9TߙZHΏbr1Z*0O2ŗs'&0x$Wq\8<*Z`QCf)"x -E׆~Ї8djSZo壥B ZVpOQ6^;#WL*kEkxi1U˼J]5cpp0 |Vc#""xHM!f9J_zi1?jwh;OT6NTJ㝮vfQAEGTVvHͣXŇk᭓UB<AJ;"Myԓ=?6;1Hkuy9c;1m-@@H qm53~ϊľOg&j`d1w/WBF}+?Ľ/P}qC## ßr x\+VAn/E5]Qg 혱wс! yع"n1ZI0LEv0E%ʋC]bTW1:La<^O:d`T9L'*;hCޱ:obu7Bc\ [p@aGv"P~wb+rUBE3$zU1y"o.'ɰ@scRN03@WQ$?k?k(Oj*n&Gę+{[fJ\Z 5 ICFC.?vZD:J%"5bAē[efU~FE&6{O2SWnU8)!:! a+oc/^9 dL!zmi;(S]&DR)4f]ꖗ J$).CM`xE%!BD^?KrA7e,-i$Ʃ،$^ޜ[M-eSn"K8˦Lܟ(+B4cքPzRpDajz{*o [8txǂg 痮dQtj q_\Q 7[=}iۯс8Y44/0bwx5UfÂ?عb?ga %h*xCT>'`dbZ= k;7IFlk^1MƊJ1͟?h}BgZd$."tB5he_{k]r(ˆ0QE+>/ImCr|g iV \|n>)s'3ٯJgkY3(3#lKsJk@%[D:Y㟯:P6^l_N7 MRHs5?,=#V%p24!N9c|(/gdNE}j·"2.%|ÎL\lJO eԉ_ ͞GuqeInqT%UL. k}.ݍ:Ήf%ÐAOڈOa:VC Iol<# RHˎ79WX=#]s1IxG?g^J&GPӹW޲H晳:TYb\3'AP؝_v /@t!ȶ1̇k(zsJM Dn%!:\Օ"-z<8M13qvh҅*ʱr"+1.xu݊ C6PEtnF&K:' } CڬKٔܯVWAsHEmRkUr8^g#DkXJp<DȌ[-0E crh kpD᷃rTF;2ʪzUklڥf--Y\( [Sriunr=R]!\ďM-U EbwGA>9D *n$:;ђѠ3Ie+#R>O(-lO7L4t/:S@8ʵ|R)HŅ5|׷h$"&4|\^mE@q6VcDL|$%Zׄkᣪpx2ZGsAbbi):l$f Q"$j鐩Ii>W?pGUhsDC+WBztjb`.TnsRdI?Z~f,  Tu5[_SWk'Lo_ʥ.#:#'v+Tg KE] 3V>h=)OkiT0Fy2ʋiAUZ4!Vo؆6ST>#E~jmc;ܮE.יWG[wj޵ZC.n:Bav㦖 UxMP4ϟkXfNCh2#J_ɤqi Fo`dalxXzs&P<袄R6{3INǟG E+wxAbFXq/pM-;D Tk:SkҘ B(xaI-%:2{L=бU=6>8[ogE%vh]X8#G7Y+dW`>5%1Qcn{ZL08 PUXB+<~P-کvO`M]Kf0FS&(, O߬:rrlSĎަ=11HƄuf9,t'>fvԟHQ50U߷[s'\ԔuduCـg |\Z/7-ސZʳm>Qx$dO4D 9R.)ƇCFW EXPry6_i;!;ËIᮮsKLnQ!ut1*-s|0Ɖ}? LSyxa&(xٕu(<"NQfrҰBQ0̔ߊOg+gWҪILKݕcj<~MCnz璹n&IEcfk.[VIT:&&CSx\LwWa ٸmtƳGBf6X%qsE.djBEuE rCt<廊QɵNjq<&T+st0h8qO!0bY{J-*,2]o Z7yFHxKi%EGB9<#XTgJ(kx+XG 2)rly$_- N9jA֗2TmE_g iGTu%ى|fҳ8w!4Z>>w=6Y8LMFD ~猟O}yo@Q(HnT}4 ʵ6t/gGTtA$}?=!7{ g}Ddew>(%<sl{k&} l? NLRfl-n.ԥG!D˽y`AU ޣT<6\ʊE[ 8A&I0CaOD;RFiwwə0t=Zؕp5>-GC#Hvq"@/PT["jl Zf^k Nr88OvX9rێk|#6/eP7g%~/v$CK=KY1@^9 _QBpC{6pޫcEh o6*SAHB4]0nܭ 31 dY?On3YQK5w79{g#nn[ECZSiɐXk`P/NPTR8ΐG}[$mZ{d )BziêM g]G3ۂRn2YKa6FgV%.) q~뷦<\ Q+|ޑtuC*V=Q6.w>rTϊlwrXʫoU)}HQ(g.G/oU_Ž[RQe/ΩySK+π;<4ea@lUnT| E9peEρ_MuFf6G FEg ,EmЛk[/?m( Cg(}01e SA96*LTȾkPUE\ꈇH^PNc4wyvAZ\z9<3թ+"e~UISXmgE1WgԽw~.f@.w4VS᧒F:ܰ7L;1Kݲ2Ny"u]M!)"lo Zb3 6>dJppy3Єc9c'*1ჩ4 &1Z("|%5x9dOoA!d(1R'zz\֓ȵ2K&2PqIcNdZ;p':hHZM JGwwSH,=jpEyFJis 3<Fa~C%Qk>{+sav Awaa aҬ%pԳB.L¨4#>>g1E-6&*|Zs4.P|x 蕭񢰈O/w5 8'G*E% AT} @6%yv')zOx n7wfLcf>zKt 9[ܠ:ʄѮ'HTKd99JyHؑ;Kc!^bZy<܄WBz_C 2bWaNB%av#@{94[}D4B2}\>zp-`Puz/ ^uњ_ Mx,?ϕP endstream endobj 2987 0 obj << /Length1 1630 /Length2 18758 /Length3 0 /Length 19594 /Filter /FlateDecode >> stream xڬctem&vvl;mbsǶ*m۶mTl'tkuO\׼ދDQAT 5rqReP65wsQP8:[E My&QSc++ bghin VS֠/?&#t4(ۚB_;-Lf6E-)y @hhhPt14ZLifv;&K `p75fnlj`ohk`0w4:큳hlbOfvJ__0E;'g'cGK{gߨ?,vf-M])_0Ά@'?L&N6cwW.N@ʀhjnhbc/?:K6`djc7@8fE hf`a7\M fo&v@ߐ;Hz/>whqyCۿo;w @Ϣ1tZx鿥r6!_jMh$nnjhll03۳Հ&6@ӿfS4CǿL&t+&uMQ9QE͂ApVۿW#gg`^ ,VnoB<>b;ߺYU?uo0b@c;FGhwS/ZnmΘ/*-3ݹ;wdJ@ H}ijQ]_Z.OGmc v3Ciڣ>,ӫ|2-N.@&Rs(EmNf)%e(™N6Gg2 '{$_ԆX.&³sOTC#ýt9|ؾg$I \Z5jP<ߗ]cvY/و̿@beܮBǰ%O̪Jw-Kr_4YgX7E.KqlAUZo"̍}OB)R"iO8Zه{Hj`}"wKphcôZV?iϣߔcၥl5a WL[U͏AB 5tֺ\PᆢJn6FIR{'ID\0=h)كhђ)发eO>DZ4nj[g?C8%7s?0t͎O*2=i!fMzQɜTFשì%?B,huOczZL,m3>5s)./젛h3إ+[W}c+TFJEq F (4R4~{lҤ,F7]o Y氟dClh5-m2z'u'W { E6!E@ σ&(eK5):d%2~pξ I/D[SC^;Inž%qaoETd؟/䯆9 ѹo;=/](N#ї'͈U;5a!ۆ]X5?ޖd): hh#{ }0֬\Em.\ (A|= u 32b$?ak|d[޴BgV-t G3h =[o+mmk^׸mErexbWD*:`zc=l}8{-xW͞|byta݃E .f|"S&L=qgK_8IW^B1m,Į_)1} A6޳z. >qQN F/Z%Yg;1'Ħf^$q\LZYhX ^y6\f *UN,W~/-Hq%є[GڒfUnx}Ie^<_-_>ڋHs JѦq;6?IR^nqu%l¾HGsN[3چnaU3X"`*5Ҽ@{ᣐ, P X2\p<uZЇk<[sRV2rk^jFf8fs9}2K?GTW`f=w3/!t4V i ͦh )N?r@Ei~ljFe|[}!! Bԩ QZhI҅\gUC* 0VEFYudSK/ZRcqpЛSw5AV|rڃ'?]L\OOɇkJ@r}i)01=a*ֽKQȏ{Pp'id ,ٵhNA`o+xxzfԔR+wh%kCK-{.=[H88oD?qnқJ(-j1:%FA$n-_dφ><)]@&j&ɎEfWG2f6?o^<~Eu=pcua{kпQ~HG嫂; yal[m"8˧YDPΕ9,NNSމ޶76~q>=r^:28Ƣ Q.YXDSWߑ/ krw7+/'E |,Fb1lXd8IB_ I$*>WSJzqL(驊Xճ[Uh(W6\\rXP$\woy4"!ɫK@Aqi 8B1n:$5M:sԯx,Tf_kgZ ѡ) ᫚eAG:*SzM]Ihs=Qg :cht{(?1E%f(569b~hW|tAY޹rVA0 Z_d{*-aNr(L*&Dfʲl R}{˥_0}.pq+Ɵ)/ D45EKb₎z*L!l& #y&,rٳDŽ>}vQE dDzGY%oyD4wG^s,wГ6}M-=XW囇ףFmtpjqW]{u$(sv66h0bp7vQt?缇ÞSOuq'/PNk}*d%oxY)_po2aw9(̸QP$6pSH![ߢv>2_&RL‘L?shnI\yGȡ/mlKH) \+~df5wHCwZ"ۘT?׶~ vʳ"31QVxSu)BcÒ?MdQo J>=WÇA+7bo2?F 5* ~E;G#^u;X9 9וn>B|/wJO䃳kj&Y"e_zN C<یbV,~P,2]ʏMwV xs.#sSu0$ꈝ0TKJPR᭳-8n\"6D_*Am[ [HV\v=d/&bxV  cҪ6׍ddC2Aoc0̗fӭY=|5qbD,3D"з{Wx;$ՋwNfՋ'*y1G G."rX]=Jl1wyjnvI2b'qBKީ@HY'V+PStr!0S+飝DP$u/Rfgݭ9TcRjbNt]AR.sސ^>^ě5De^xڟF۴O=j˫k6/ نce74rH12+N%l}*@RaÁd2oR OaΣs*b( ƚAPV\I [ Q Z {_&2P\jݢvSt22t(Vwŧ;ٴSZ!F{ +=Ȱ^i];-\a&i5Q]KhU&FF-6iԌ !s0b;yQ#;Oiw\=1pL}F Q2 aZNcw_]|mk*nd/: ~nƟ=R~!u+Fb*33pfŽJ^8A116)g^*H ^h~MZ^H"ݗ .(^Z4-VAA%ƟҪdM5O%IC@ beaJ#R]5В=8!y>;y˦CHa Kՠ>pƖmJ/g)MOZ1aS ^i{psB.U\[]zΤ=jZ֐nЯ Pə0(i]}Gl4{?ol}Ծxw{dт-[ *lb^_P2FJq5D G >S{ػ?eH7J%/ZEu?, IE-0m𠛊#TsR%)KJ eo^pw2lHfp¾<"7MQq2!G ͯU/$V+DkF ^u?;^PM~V1Ԃj5?ViTfO&L^FPL;>3?h٠tTUqfY9)ziwrQ~dN:05U)@|p5!A&u@B2`}0UTV$]6Dv;-'q'`'b˃˪W}}hMw"WA¯]6h.K2iW$J2v>$U2iMU`S@zrc`V G7AWʧI(vCD89MU~In+YV%jf]8h8nvgFtHC,fYwfO,NY 4Tr]WOtUW::EnDO4JDSt,[=OC'e껈n{qE)hI2~[Z7AJX (ڤۓ#Up:kȞ/vv(ѲuA ~TMgFl[b9+V m)XL&ZmT)f2UH _$>Hyn I38"75$7vAzJvP/dP=%WSn|2k%hp 5aAݝCU/Q@"(~.Q%ƒBrOaMn\6Nc]U9p$jdo QrfOKNW@l/z)R rg4#?B-?bvПPAu2re!f/X5O: 77{5=S+d3\|1H7d99|9qD0c8)t _D3 )^у]Sˆk܆ }'~@4%8AYMAX1Y 4S[3 "*e~2 IN/LmD$P~T'(VxXJ9{ |7@"(yD1QwXUOZF5f'CHic/"p`0B};`6>L Lvw3M7wqHJr%8qҹ`EЯ' Z8ܳ/YO_-Z}MÛ ˭R4\Lsܿ'ea`'$ O6ޔj<ϧU'^i'٨!qj#47rv<:)ϯ߷8U4?/xAW( YF Y3~lBp rƵ1&(FxU x%p Thalc0ŗbS& d{l!RuMh*bO- qy.ŦXqþ2oI|p%=%D4j k،rjOc dz3xY{(1=TdԲcMLyx 툯:t}Uw}=SAtrpJk$x.zjM.Q2Ef3y@kp;Tb3) HVX-9DfgHrPŸiѯZa˒ׄzr O`6PHaʝB(E{xIڥwוͦ|)6?xq Lv&\lކxZ-ȱr\@|)ú*8ƫ>1eS8 wY\TFpDt'^h,]T] eg60.|Rc=k rI=|"e |9vDKѝrp_\Ψ>\ 3mdu>;HU *;JtgdI!b`/R(;b&o\5X1/J!:0VPX`6H GGLl2q $! `Ňl$]*;%WvA+~ Nț˵Hk CS"T~V!/ޣNQrضDBFLr?;=@ i69c4 )g| ݇2 nqRSG R@nuGbv]7\b{V5NShL\K(:{MwEe?+?X/O!u>^lm)tAjf},45( 5uz1d|WA`PihVhMG}e ZﲐĩBl.m~;C=FX] )Ù9T8u4K*jgxlFl bԪ:Cj}1=3+4]'ͩEqJ\)@}= 6T[lΗp [,ܪ?C=+ޱ}-+w ׅBBHٲg(oT㝘_WAѦ٤xc E'L6i:]sJLk ^pL㋭2O`UJW6ڶf "&CR>yJzH~'<[ª% u1 +|JCТ8{J90IrDv7IR 훙B:)G=bL"G1'3>뫂*.K@PeТr$8"ƱÜzSo>?vFo_&z=A): :e_W{$qlWiX]'7M&B (`Lsx :F"W&X5feɒu$.1Se؏HȨLfȂp߳6Ћ#,͟ ݥ\n<- Lpl%83آq[j+hrAM!3vO'(k]SG9F5rxqP$>S R$웥}4@8 Wj1Cl%>AAmIBWz)XUEb=,BhT:<.2y^|<PZaݺ8ztƢ["[o_ulRkvS[f[@i쎖'TȎ,\ykJo`t^0_UT^^[h%\ w6: 0_,`p~8 [7X\Vw 1 ngU$$G/;ݓe '*"B ܸBٹoة3nsz]yۏp}ܻ)q36 O.]udAP0 *U D?g8Ӯp0N{Wy NBP.#.8 N[Y 1堪xOok V  W]3Y.P5)>JLHa(SFBbB1vNrDS)OXV`2Ѣߪ#wrt;܏CV"Y!JY#^HpV㏈9q&F>eRDe|r`B60О.dD ]Bi\=cdې!q jʡU^ꊫ5vwY'2,Kh-KšU".,6yC:J,mg @m7[ni ?dL Ũ̳VP9d ) 9o[!ZQg'8Vm8rS1GGZXoqZ`@tp3ULlAHWǭSdQimF 4'Kv+g*y?&ib~~oEQcgZٴӮٚ%IW,3L!QI,h<]{/:!P Mj/ z8\D7 ELj<)oV0Ќ=Lrћ9ci 5\=Y3*ڳ(2hC˸$!'L g >g .!2h6ӧ#ž7ǘPLb Ə&(`< XyK9ƜLqV*Vu;ߎ+FܪUlXdN#֑t5Y99Y|I~hA(q-Y#?$ޞ[+|.UN;*׌eKe'6SOwC*܇]bW?yd Ɍ l/fnE7n3)m~Cv)c gAJ}j^pBP9&csd h}sm,]z}^%bցN/V: P=4|ʨzE^D}mgPEph wbӦ('?tɁ3<ijG..fyY=Z ӳJ`N`-:dNNh;:A+b_}53ŵI7M~aꏁ|̝";Ev~}zAwiB1lLy1J*6;u5%/Bapdcs˱ zt8!8[߉ y𯽿/z:thpF*s,A!C rT_v; (ھ7mWMs Qvc> ߧK8)5\wхlras1}WL{/+{ ~c\"r~3~Cgȩt7TPc3qM&(eDz;0l}98Өn;~mRV3;(| l❌h_: \Y}ĩ%?`~0NUadsskk}${\*p:4 sέ؎ GHz~pߩuU.o<rײ ~^Bdor8[9lkt!kin A5,,tfmL>Fl)d}b,U/:"9d<΢m.RO:O%ZL+K(4oZAt!ǸK-hoy?Md]9T ɹU^WW=}NӈHYT^LAP 7tV;Xh9+N`-'4bk7& wY}:J3%ѷ7a?0X]#%;*XT8(md&0I>X\!/CϱWC } jrk_biW5 {uE`Oݛo򼡈 h|AJ%?1!` K4K _. ӌT`uc4ɬA|VZ%WѠ |7-0 q=6ûsS5[S$}҅q1zB.U'@!jZWc9:\!M ۷EY#'e: 1KSP:5,4pqL*2(Bkػ=i5-Dn:qf͛dսr&#Gy $?}4^:mȵ$#+ˎhl2Z)nT%VF Z<'cbveQ6FH)s9삞XsN$vg5I_Xum H>XçvѸ{(Ʋ;)܇WvnmPNî oi h q輳^h ssW<nSXDxw'@-xs()j)Cg!G-R.e9`% M9X@*mz/LC1v/b+'#m .Mʂ@S7qW|LaOMh 6.vn+%nQkn."f[||XǸQmIXpɬֱSp^:B3| 5̏\}wH\ֽ̂͟$gĈmBp쥻 q/l mƀrJ_?Uď4$A=@ͺE^|o'.팩Xo9~4< & 7FTKB0&Py\V xʸK,3b*i]U*d\)9n+JeU]eE2Mtc۷5rHb-kubt75oyq'R<]$ڗoC^ Z6{*RN9λ6x^̺!{F"f:fE4%d 6\{0^4ɍKȿ(9,c鶥9 .sWYSjpCmSpK$犠fDjAM8A\t,/716I=TV(jg3]4[/ x)zOI+55߲󶶸*Juΐ-s 9ad [lp^ỻpe!^|ظġDm֫fo&^w4X|? =* C`4R)d+r0ErJ3>؊k?鿀v:܂c7o3vH)g<ͬVDR\ђ}:0*j/ ZzSUygf7$n+̭ }KW4i6/@ڲO-ü?xtVuZ(Zq15akv*#7kBAGmG2˧8G',e)J,ugeC=G~RpQʸg-?+h=Q1Š}){/.eQs›K]NLQMG=^V[/%w" ` *_i@ߤp,{+qPg늴@!zee?ȑ) .#Uٓ9ި&=X3T"* Yd9yy FBecj96W4 ĥИIl )@pEߥ=CE J"^5j: %x7*4ث YBjNofGʅ Bl$^=6u4DJ0#]CY>>,0@E/LmvcY،@u>r#>^Vʔѕ}_ac?bsgy 0F[6|Dϊwpzph#g, ct),W7s=5JD Y2,^5"kW&}QSlb-Uf<ӱ-FOޒYnmV$Z]Zc]”0'b $Ȅ:ϪMѿ#,CuhQ, ԯd!dnFHʈo $As<V Y%=M8:<6R'P՘yӤahEأrt;!bQldHKhW 2|ĝ6%)pbTxf8IT=K2Ș{@̊]?. 0w9t:m-0  Q)kwD•%HZW&p/cfJ=':ut9XqKݕz@uPfN'}z\-a.5h>fp T:*<3&@uAv$YL+n߉5ηAsiH 0EKN+?>0P0\&HGZ؛%J_{ /~PK3>حsܩL!CHx2/4WJ2m7!1tIdգXB+us+,KBs&=g!_#,7$q~(Κ:6}-ۘz6-^wk c%Y5*PkL2fy Y!}RvX-q؞݆5%`; =R-HDFvSGP/w4jT4-iw79pb`OQ6&VE\`6 aﭗ(!Jxor 65goosS]ҧj/fY\_g> fJHOn-LØ@<\xowD: H1w. @lueR9xqaB;q`J ﭽ9xP*.)szղVz͆ո[jJIoGHxmn2gg!"jDy{b:S+2c `(/xw_@ɕP8<{-~o!Kb}|*%坯 G 1eGhC= Gߑ4tD?ƵpH]Y~G]k;uq!?^y=?ݲM^z!9 `^4R84%L-Kꁆf Q&tV8|lL>]#FAB & ry%Zݽ}97Y&+ LJ/0ʗdrx-?Z9ߦ endstream endobj 2989 0 obj << /Length1 1644 /Length2 13618 /Length3 0 /Length 14477 /Filter /FlateDecode >> stream xڭeX]%{5]hqw, =ߜ3יo̜_}ZVɪ]ME$f6~;21@fn.j`{%0 aBp@~6 4`G/g+VSM?-\yOdpځ׎@ *JZi%M4ljPq3@@  `vS  4}=́@G=rX9:~ 9۹Y7?23UE˿t6u' -?nZ)_j rp=]eX\L>b9: ?3`8L-..4t?/՛::y[hgɌ#YuXmps;_ gf>0;y,H,J`׏;DoEy/=W/nvvJX2=PhL7S{;G[>ace7rZ\ͭv}]lr~XY a 2uGC@ZŇdELVYUG_Lvfoprxڊ`8C(.0qy>^Gj|~?EgESWg'@_b`_h C_#.Bm23]ǾI A97kց2"wM^Ø[f;'hӀD~tE< ,F娙1>W 0zܬZTՌ^g9)܋q(ӛq{0Z ΩOiF&F2#R z86>,ka&kzx,R`e^pXg]6Gc/If$Ӑ3jY=_^$̟aB>j^Π(zԢY ObTՊl,B%%-8Y+ZkG Q1ܘ{4&fe;udյ ?V ق'^5cS}l^$5CrȘ} )l>ՍMQ{~o_W0]1] yD8T7EіFjœ.(l'fajg-ڏ,I;c+VS:&@^4eca=Tn VTJFAc45>{RBA~-.~/[@O*$BcsƜ;\zZuyv $ƌpjagֽB4@# _+mAQ3 T+Yea^a袅qvW!hD(~%džAZAY(t_')3>I\r:p;x8wcļ׭mb],r%T2;U3!8<ޫ_ [Tꤓ@5a$gˌW0,>` Bbuz%;) _r6s|a WK5./@E;j Ηܴ厗YBt\!aY!{f$5S\ˮ-P{M9C\FLq2s< V/&Є2p!r|[n,B4  vV2?tfvO.bt۩ iqFsfB0<3𜈈b9V19d?9B|1iĄߕi%zlpm2!FK!B)3Fi;5{7X)W8:|!X1E>ՠEˆ%KZ9o=i޸(zfH3xsrAզ,X]m%őq4LJ)$[s?_UMȺE@zQ>=_=nFԏl"ƂM>7{n38Z0h+w1 ]2$ݍ cP X~xGV!e#<We`Z9J6Km:]=]bFX-{fQw휨ho+ѵzη &23Vwg]~5%I[|h.TcCV#$sM5=VKpiGe.>ʳ4lw) 3 *nr xuK3,6e=‰ј0=\A"Q¯Y+8EVp5Ʋ>fT vƵ#wy=p/,8q^L>H*g K3/|9S d>@^{xr55ݣUC4%kGcW kRX`zvc*Uh <`ՈD5Ŏrf676"%n3報I6IBxH{Rb2.71]a2?J]*y% D"؏,ΠDH*Nqzp8%J@{+MXq}\i h֫SU+bR/|0"CSV}W;+W}`푨$BK7fETź5.`[& ke2oXfpR&.kEeo5IpȪoRP 'NPra\RvS8,)2N`#||(mTEȸLUvE*՟6zsVK:OB@%8 d}8/͹ZdӢP(J#LVGK\ T_g\,6NN&qұ@A|p=K>\\0 s)TZk޲#%'2\*s!C)ぜú[hz v}Pcix) ԌB+`Q[H: buTS<_Ӯumv1c:$xdl^56OVdu̫[=߫|v0Sc!GXԨD[ջ+8S4"t[\ }o8w /DMr0hn43cp[dlr'aaX 윝颫1Y%u|T}הDh^ۗ[}u̟ApmPi]o;-?7 v"X1Qxk V(E|9_%vĂl&|M8ChB+ qԫbCJJ+*z(ܯ;8ȡ#gύmfs| OT.4"6eka ȶz2(6ygs%aHJm'=cn6)ғ}5Y;G5=$o~g%CPԮbKif ߶UKk1OE's1, Y&5iQxi%ٶcd.13 (X`_/O i iufv% UIu!ILV QOVR8poaᜡ~ Y:.])X5u7v;xR o Gi&_GTa8 HVv V2yEc 32m.}wQg0qóUKwM獐/ 3jJ]LפrQo׾4FШ)7V{wN|$R~8Jؔ3E3X. o M ؄!C(Z)6piUST'u߯KR| XyHD](>]J7hfW-+'qywS"HHmpXO{0s8UB;FOwUo|="SXBGRj7{]҃}⭁?m=~(mUB9FȨוE/E(,ęNL&°Z&cfK(<&8k|C3U5=fWѻ.|dPjŻnW\$UKro_苎g`n}l]LB;M(J~} f0#+i@~(@H19ߓTJYKNƣy)]S%taxlq&w#vOn ezM֘e rirsB2$QLqdLK6&veq% |se aRtf>e Y pZP4\- W}pQ.;kmHTŞqX OL ڃk4+5iN,P  x|ˆH! HƁI^Ln|\N,f&Xth[Ѕ:QŞjƎFo뺋jf NU*y1TmWhEencBFvQ OjXX#$oՑs|ZӒI&VUJv*;@7@hu#l4LhJv%_NjtbyehQNuoYTȮbR3& 'do!H~ԍ/ %zwC 7$Ē點/ۆj5l2JBcP}n[r":[v,dכCkYꗥh Z +cgj'qK_n4{9d|"bdHx;&)uꑝn)tUvIRQ^5ҫ#\VK\y8q@e9nş=`7oh$f^Z.*!Th3C"~i^4|d˄ׄ 5x܇;VOLU`S+cq Oĸ鯥W\Aeckq|˷%^.xiPNyn4]{u1y{W6 gK/gTi/rYvhFjd_y=Zgn} >qAJnGasP<_b vLc١ .|d6"M?wP/ZgfJ]+ C.7A1WK*KKtӣ2I g4):1x&Jbnyφc`Ō/ qD+]$nҦ◺fz=mCNNmD+ngɄMݹ~y9퇬u?yī`/fy6=RifjxC v5#N{O[;i[B$/B;-BIӊŐJSX8frD1a}(Fnxi?{uV!/ o´EA4>8H6>V"W*npF86 }nDa /K&)[ rs+{0WlgôBs *\6s@f\C?2qs̉`_)Oa K>V*fp;Cf'3{\a]3 =''4߲Yn8Tifx]t7XvQJxi91nLgO&tp\"J<kvA"0XܲNmQgۤXasP+4ZU1,6 g*t?[՝) 1+ZzHlȇ@hs1Oj`݉j40J0]F"  (ـo!-MK1:T4o0*ȷ ZrdbNk9kqڢCI?p =gm(f?6+S<:$5œ"<@)'>p<[_U A7g89ߔ|m-f>4bm74FYW:Hփ_ӻ?r" Gk3Q'BN:kdW}n 'hOCHU }./I\?([=.,?l 3OܤB`sIc1: ᧷%kg=`H2HOoۃe+.4:`Nj%Rڌ.>3ud|K㪷m,% Ժ߮:Ҟ;`A)1]gsh'(Oô- J95L^|X;&;` ?U@D`& L`Z1P:-+^[EV=Thv@VLȘ ?ybk1c K㹯HV= /(%09 Ff\ }'Logڎ6=(q:nD1ezN}ne1C׳rQJH1%i IHD[yufP="7Tj!uA !]NYcY<.)Crm\CB/ \ 6o?r+Pp\/>#b XՆ5-<2%}oq|tGܻJ@V -t2Mwn;Z[.2Cщ#1]f .KqT-zsc]PԙN 58BN{wc ̮&ԑ zyT#k>pAF! _:-89D0asjXZ[vloP|&jdw=}-r\0e؛a lF0[w.B>𯿿F),z',{7${@|AEh0TNY ^:''ׇnC%aʣ7k%`A[-= at-L&g!VRGWvwg Oa[y>2}) /’0X.Yۭ-QZgkQb;lʂKpC'5AQ;K[ `&y T|G4N}e\}f,՝B!V68S;ȧz 6f" ̹_Bt[S>nDN}:_R7x)Ӻ/,,W]fDh܄=ѕ -"eO; k٭GMyqf(RSŝF%óYq*ϭ[7XqwfLMhz4/$]$&77Ļq4-kmh _Ka0{K3Uf:)!rw߽_v+bMǀ QR1;/pqpۨ_BK?PIbfM%hH_(~U3Q&}ēFvyZ Hsy % ȑ}3T&ee"2jqj[tAM8} v4耭eSPE':$g<hM.ݚQzY#@6gqݟ0T -kj frUWͳ9n`DeWV[XKik ✆àR{߯EεI4TYJLc&I&x{oſ52dwM5wؽIt̎.P6aNd8ɒLx]?Ds9O2D2ӻ&!qc u6QM{s3^s!R[R-PqNA/L_s!]uɾdC #KMtycoHkӣt]?vمL+M,EŔ,jq ~{>Zqy3'CuNnYo_ܽ_PXzZ&آMCo;xF-kc nޒL)cR? Hefŭz]zO'$]\V {@s]Ao8սe!!Y8K9> 7{rןؿƱDYbJ(Cc  ZnFh6f7*%҅1=h򉇏b/OwӶwg 鎦Lq&Baʭj6(]^AN_aLoq&֏3/M(ΆuH~|/jgi#ϲa~P; tp/Wpd\A#^/sŚZ(^5pN=y4!y3lQ*9]aduUOۻUUZ}ODt9DeĜ:>*Ό$N%29G߅6`tE)HX)p׫q oBn=͑F2&tH!&8nu 6KEo@ !A)Z=^/JndO̒3xn.??{~<$g8z4p^Ώ3MRL簿ڝ 8燣Q0Q?.pk(ogppdٺ&D+Bflݟ E]}O$I,:2?Y8g~Ę6/LFKYNJ| (yT9##.' })D<>2ۜ s+f>@=ӄhՓw=憤4]J9Ҩ VWj`;gMdFX}f7۹~k ޡOL=3h~a7}BI% Jxn qc6{:gj'+8Z-R~`?s6 3TOuxZȋ5}ܱ>do&tMlb91 A!ci?BJѮw3-dnl.毑0OgXg0i'<riv+-QIͧߕ%ǰU)RQ|Dvk,T.B0WQ0H=1nC"Q>#AȪW5;_ۭqΚpyg- 6\s{܅ RluYo-3*z 餹]NS+=,\+朩GQo:R" ȢSΗ__ش g:E=C,__.?9κ߸BUwE $*"vF]T"z#$)B'yBjN-QW:O&Iu+W6?GH*Ty>=u Am:иfk]8sig,SP31Bٽ "ֳtoKa7#5!5#|J5~1tZ.(* 瓉yx@qQ`FVxI}aN[?Ac"I-|͐:sӾͫXmmInmؗ͠D}OO l~ž C(NmMuAËa"TS kT̺,WPCbT7tZ}?.J*U_/~xLjS&>>탷Ƌm2ͥ l ͰVs+\qY6PʼnVleobNT;8-| [:5t'nӽ*u}3DBٗ]yIli[/T3O h%![7h-Xg`A*A}Q[}8%窬~ [s2|N|.v`+|AVA P%N\C{>j>8${`Xv`z;= gOńęū഼V3Es8XDm$`y_\ʟg~ݲK ԤEJ|I[XM9S8ׁF ]R<Ät#j)%](B?9 akWCXZ~x#]L(5'˃2oNV8ّAB8ejOCZ5coUx7F]?_%% yQX&G?B_qհ1!>)tjP˼PY0 &zߜl_ (/9Mr(z^XrNz}z3E]P&r|xf:;>Yu ;59AY:Kug yjWggc[qK5ǵo{ʝw:[0@_w|YG/ew]D-9tVGgqCjRkN܍fB#!˞yD FHlwcƁM`ƯaNvٰ46NguWwg2^V򘴣v@eB<0o`9_Ƨ{(d|Y6LdWHc[\`NtDХE__lF*> stream xڭeX\]&;Cpw . 44|9s?3^%wU)HUM팁v ,< c'e;vr @sig#k_#dg+f hMb@++ jg2pP)khz:m?\v6@[׎*@ 0Y Z%Ԓ@["]A&9 H0sX05S_,a'ht7m@NN ';plM]LI_ ; hdw(&<-ؙ43q:l@wb '{k#;?38͍MNNabs;Y'_v_9f,c8mE`_m, gh&adjgk0!0}s@2 Bm_BKX[73w,k#G? dq5Y{YOwa[ 1p0r[ rMA&3#뿗/)d K3ѩZLla*/oIN^IMCme+U=쁀ICsx1|0r2ƿ_@,y7rvtYIؙۚG*F[ Q8:e_oq@E;` Cb:}=,C!%EUv~o! < 2#=Tݩ|2 vN@&3hy-(o;J?`'ᮞh\ 1Q|M:Pk O(Fo{r)xp|SNI= M>_\9]ݐ02]lIDk=gYK&uEҜW,=-Da!o5d&ר}_ R6d2;]5S%2ϥo44-y%VUE\0sLJcd{mũ_a Fݎ~zNYS{&x9!}Z(ؘ몟; /{ o8-88SKAprei_-"} GZ!H,F0uqط&x kpM|Qi;c C"FV^-}v2)3ISf!a}o ?֙;[h<T-_b 9.FwCƃ~+SBoTY~ҌJzLNS/ rEXQŜT6Ԉv7bɓ'ts1F?vsb"&݀v5rPW,G%ˁr6'j>uC[I_ P><! b+פX9Naw$KsӭZ]YS O ƶKH T(fJ(,&mI@KBk A<(oԒ 0VV࿺G#;> gl\@GU"@:/cOGTW!WZIxD\&3{oeg )?~KR} i  =nY _f oXXՓ,iBL+S$g:&Vi`W ߤh4!豔;7\4=:Ԥ^\4S|:5jg◖&39 >J1 hox#ן+2YOƩ+y`yk[Y)\n&!6N%*Ϊ-!&7Fs?:{c]$1_QYlZ^.V{@8j 1:᫢Ь.o0x;>?r[twՊHDY{sb| cMEFm!TD4U"+BRBP^ 9FHf}K懳;eTSPGHlF EV5+@28[T-T 6\DClYrBc6gSdlm?QYmIsxP9_hj`3XnjjmiFkqjLjR!^ ۰HC18bkS<eRljH~YcF4'`Y؂14ܾ]mQ[Jn8-ˣy$N&yY/EO]Wcf"nFIi&VٌsdNL:u7JOa-27MI |.0t:01 5I*|RgCtRr4 뫩 ikǺǂ7LEcGF"̩89QvNhKdkfD M鷛*%}Z[X3pvgΝ"*?G63,ؼ}|k8]UT, x w 4靘#ԉ`6;C h(\MqPw;Ȋ v0h:l\qez[uMz yCJw?:*|NjɈcQXvɦi59AsH^70[%Z(CH3є+qy\wJS/)".rٶ̀C."jaʩy'$yԝBSx,LbL?Z>K.ϛ!rgZcQXRI(ep킾**̤b"y-r4|I0I2NPhf~=ުڕ9o$\ve ÇG]u 6N}z8˾c ;6ZܬY=l[w -PPo!'WBwٵFBK֩yҖ`nxlc,a_U-x,#DI'B-N+z%F4 ՞%Xh% :{O p]r`CcIͱ O1JRNߓUdY ?fm@S,?/6l ]j.6NJj.0&oc&pMx^'9}Ń"Afu !HuCg3 'lcQ3] |pEՒ,¥yh"D|e4'6CDr5$ᇆ~p`1z4H*E%o G+m5Yƴf1( 'l">א1s^V>k|XыE.{\$CBk_ۯi1Hlscc1o]cSgwhtD}%2hVǞB]lxڍe7MQn,M6 R9n҅>.qE!c[wu~$:_i TS I5{٠<у W1I᫊d I2+O(<$R:G$!drΙaBJYS'"籐5zKg0j-AڃaOjk ISx'( AQwvZk~QS'1Z j⭼tq;W]5cw^ ;$c5|!?|4l?Ч %Ծ) pch-\*6&M7A3*hvᵝ2+450:gJc/$kT%O^ `6=H5 ZXnV~q(|4hi(ɶ&A~raѲJe5;PnP0 磗/X؅X?[~C=LK]]pw `9WhjPd8g JA07v1 /9E( (`v8َHiPW< Rtdz '3E=DDQN&$m5 J}!(PUHJa7fEfj YzX_/9<_$@%혗2CR-":iُ݇5hLlmvCZ5-7kM|fkT'_B ]HcвS5RPR @r!{ZH8̥cgd Ia{luS7]"<]}ţf^=/Irte"l꽃ւ4_] ݡ*nl8m5?MTFDɿRgQ%>; >洏EfGJ D;mZ! Oyr>>W&NT3TP[=RTp@G2\5qbNL;.g-!浡ڱR,k.teLp3CǾ>cLjpĿI4b(3%сt  4[}&`̒E؜CYy hyAN)򄂾jueUz͢t=[g5 s;KQ4[wNj"L' ` &D}t|p@n"d,qvLD,BNn}(1ANEN:l7Y 4'!@7`_ɏZ9.alݣ hU!旾j]}Saye|%?RY(R7es/rtBRf6Ct"l@6%pC.ƪSGP.}z^O^.0u_G)_Wsb{l wUX3*@`/N ]yԏo'ֱ̲yLf-̣ہL=F%s&2?eɷh4BэYk R/vZm[_Rg -v+V|B>{K#˄ IH ٝZ4oѴ}A6#jjFq8Z&d$.] 1c({0% ~U&Ǣfo/4.U+.8/4|M27:_@C6+3ɏ5 LW_ߒff_u=68N$c#BnBo~i뿆կaZAx6 U: 5=Q ٚ7sn9nm\Z?$ٺT̢0v[,%}eا<bL\WiKL !DZINm9'NO5bjpH+)gd^""GT`ƕP2<~ y!7驦> ^ڙGbo_HF)"y-tvnGOL=ec~1(ECrҵ6~\Ho f fTC_g6& րWG/!שy^D&GD`UaH=ts07ROyI{1Ʈ>@?=3hiJ ~q.]^n'.^]s刊/x g wKC*<5{"gihpO2p܅"׽PCI@>7 `х&>t|ũ}Ʌ#.)$n`*N,(:i{|KwcP"$}4{$!PN\ }۞oZEKSeS<4Nsq:ɛG ƱthNLĠ ˅Y <9]+L-}>hL8gQ4刘13|nXJzUt ]uisK*p[fdaիku\k&yU*C{߭ttT)do)~ung ^(J\iR#IYܫTPhг\ڷc?pSb7mBEW)\)k76l7^%yScs{|] iY6"NP"3t9SQ[b|&q{xyDNvߋ|#ʵ] ?͜0 Z}!Qʠޭ)YDZ"![9d.'&2X#0c=/Sy 4ҩ R18?;Y:"8Y&2;_t%>1fRj&K/K9|='B@w9q:%"G vGU&9 #mQ(ڎc {udp(KRqL+e,cu5-ÍV/qY/EQIk:OgIAWz|/@UgRKѩ"-euC-!{! =ٴ!] hT ?yUl}x̝'Ca50d[}?D6-7!t.VKLLo0݀< kU쑖:H*'4Nb|ݤ|l^W)-W߂2l trO :C6H87:{(MSenu>eipmm&1(x]z)Yƍl<4uf:3/#UQ\Ѝ':m2{Z&+v_ZkaNQEv>og,n_Qœ2-et4GmI@{%+_`gfeos^z(,۵ids#s> (g@gӭi, ̜MeO| <_V_+'7dRPץkؔvS!iRkO=d INDj5dt7XuD|#sϡmbrtbs#ˉ}i(c?EZd NSw^MgՀY/Sk~)ɈE.w5I7Pwf oԧ,:cmz:uCmn"&KRxCd"ac ֙{/2iNDŽΏ_AAT$aYD1S+e.o0pV!Z܊ Y~b)2 aiX#RH'DgD]66AVkԑf>;"8o>:6X^]KtVL3{.qŪƞ4*8cD[vǷ2<)HʎgUC'pߏlX%%~V*WCuSK"Āy#|qxRfi *\ʱ̮fz UJ(s<E?'D$W#NqD%ݤcvqȑ]$ׂ[3s23?iE,mC-3q bKM."YR]aL)2!OkDH ҵWS;RozQv9<6Ĥ\iB7կ=Ӝ^bI|w֦Ä]u7^Gϼr+g|}ȡ_P{[m1'SO{ub!^["BŌ{7V0m0,:Lj|+8!L%C=ġwQj+ $UAVd9Iڽi Cx\y"ɇ(5F2N1󃃃v QI_#Om̀5ژƧ@eAoNL ڻW 5?AΟxӔVp~)=HxA d<S00 OFqF:re 0'S<|uK;ZKipUo{˜Y?bR6-- PEÇF׿nzZ/S'+ {hK)o %cCT#ܾKoE2ZV@w+*`up_^-G#1{Q2zx?] #}4 a ^Hv4{CR?<"7WkP4Hw馸$GA@B\[Xf#!% PZw H0Rt2Z-ѻ3_!"_?aK.PrQdn Ub8J?M3@E%+>%޳cJ7,. PI>hK6kXq`o)9A|C/h*q* >״#叾v0V cƀ^R كq3EkX=cm5.ciHpPO bV a6Zw!*NPE$b:&+Vd@8R*mKǪOwA^K蒸MOLZd[[ eRf dG\e'xY~qNDOFޠ Nwd>ΛDJ?. T(vc\Z_~MlҤÅ/_> >?]lf,>I 3P  ZO$.\t-&9>@(40zmYN(wphT9iw#M6~cg\AkC/-ō9Ug*2 h ;nt$VtxeW&xTuV"fd&mdfĢT]/{趐̢q& Xfx+qSٰl":W1b!2'c U*3Bu; #~Um_8;dk⨼ɟ_\&PfF cip^L6 mp=͏ (7"kGHc1Lx7[I-Ro&a\*❢|"b֍tKhf붗a1PâF?SkgBZC~;1!Eu` աҞ@-uaA|NMczdtVZ(bI/&Z5zeedKW(Ϛ*ō͈n7;/˙ΎJd | f (6_΂x}-v:򂿐c0ӰI2ik#B9dd+-AdxD@eUqM6 MAė&}'47V]I&5='"[zd-2A">5V{͎oMȰ2s^3RRz`\\OgW>+[~^ Ĥv~ vg^Oj.@" m,4X7V`MC qA.:(1wb5?FQQw \Pk54Or}YvFJiA}wCm,5lt9CCӫez) "_>Xgz4#J*).,M W*ש0w7l7ޥyCڣ){nMɵN6ZEs9%6I܅N!<&U^]P:.4RO,HfnXE!2S{!'u@74ɝ+L.c䅽OtmZM7[`)DB=P]7̍SYJ%í!rԤ f%CAlF $/RM8yZ7%"m9Í PlRoFBr`hߪI\<\8#F]c3'|`HU6f NѿkTD~Yxg+;~kĢ@*J2 #Ք9OȖLGR8 o*N϶5PIUȡrf+9%1@[Ef{zԙQ/)M Ǧ\>mVhj}IQlq;}fpdCr[$@^J[q-\e#Re'4"F͝FAX H;Z*v oz)=)=;IVͽ=p/XFG;ϻXBջ4tp@ڠRD {m;MTC9+@;;䚝-xI7wi!S':v:d5nZ%.MJ~^EK!s6@  SPix amT1~}RfT&wiZWύZ5iY.MHĤ;Hc (z^?c/U;@5^MĐ2n*W2 mG}$Տ֢Vş<ۜ0y !2)$]rUK{0%{2t셑#tTG7WvIfq+&{:~-(i, ]e<!&cT$ ćn`addǘUP[HyOd!-Vq$|T_\~YWv.x(n{3m4XHB}~#gw8kc ]] +ˬ0] 0${bNlzz›ًi’D#bp/&1{Y$dG˺Ы HlGX֧ ܨ\q;TKy\Sx#%c 'x;dWlɵO( !PN). $1Xk`ͦN Ji5ELt~{i1|o`ѿ2^QSQ0ٚH4ر|{ p%(u=zLV\VZ.E>">>m8RgtVUGۣ3&eF|@;4u6ݻ:ʗ:0MZ2/_ s8!QGFQ\y6C0Fr%o!Y7Eim~g{:a2/[1M8Vv rM)~@0 QnҗVweY67Q|j5- BJٍ-ߧ"K'f>XLWqB޶RH/).t]HQx#o_74p Ԛ$e_hGA85+Ii}HH7adV, gniD"U$ ?!fv2ym45%~ qDƳۯ3cc5LifHͯWɻ}B?bCBJ)ESw]ob~U'6U;'ka9lMF,~mKM 5a"aKX*}JA[ay{35>hKlyIxTf+Sfj˩jT u 3@fOt^i(3Whyk̺V1zԓUBޯUL>LbHZbOְ?lRxhem`o`w~|ks[א J$4O|I[y'"QX<`$bJHM;\zO0ׅ5&-Zt a_zqfQ8faєX)XDDb{ z˿cI)!^ڮZ!F0RGpdiȏF?@H)`cMB"ٞT&2mʊ(eȹU«USŷe2W D^|*]1Cdmg#* 3_*JGI=gЁ.pH(V7<9j"'&}Oxc=ITì~/#Ju_ q"YO˯oQ B2:BT>8ߩe;;C*wc @ڌQ aF4;v)ZrOsmߧ?"?){eUZ\ҍ܂}g>^5q߁G|^!G}ax#9~IVAF}|:65vmO=:=J :0+q )3kvP o9tNkCCIA ˩ip}%MҘD\  ܒH.>v4}*Aż biVF>S;%yߖ_N] *#HZUL1kTPB%c! endstream endobj 2970 0 obj << /Type /ObjStm /N 100 /First 945 /Length 3518 /Filter /FlateDecode >> stream x[o7Xp~EI\46]{c*K$icI8;PΒe9RAR=:pg ՠāUGF@©qxTA(,lngACt*ˆAIepd7 ZZi``vJJ-&`(.ct0 T0e`+ 3j0&f XNaH89 LLZr ;yqU u wbF{/`ogQn`J pLV :a?0P#= ɚJ`L0J&;d$0g& A7)G eBZ %@/-h|+,BFqu"P t$?_aGt-0pH4 ` fjN6"Cdk \a>zBG9"~r.JtZ00X'K'+dxro#ЇAÐ#( a_a9&%W@̷{T^ w!q?5d9ЇC1UKte{ G i>q+{ L mz1^> ߣh_97ݽ.x<,q|+و:ҽ x%k+m;^^KH[U"h`-`DI tj`y {n(X@@=҅vb#Ăo%(q K 0D6Q0j71PH4ǦwĤ(`]eCxضJ &ڨXO.9ʸlo[{>Q;BDJ+1ʗ,ؽ-O*/yBS:SиʎX^7M^7 GɒЪRj@_%c$}SE*M8wSVsi*񎔛,|Z6iM̘n7}|p2Ļtߛ:+?.F8i{x=خwpyZnVv\=O/3nVܽ0J#zC-||}@lv?(-w_lyçDX}6[K%}|G'#?ȟzu}0B;|͍"ˇ{'7#-P@ rˀ)d8{ƪ52jx%>ƫë{tx h> 1L18$-Av>L`q"$6}# (}Am!c$>=tN!&,6[* H*گ>?t}:Ϗ\:o.s4Reh+ oPPnRݐ(*Uf}jU(1u^\G/pvّU=1vc*)y.BHTQ%E]P EvSa0ʪ8 XBXY D6r w|i'p[H~ޅ|^ՠA)ccgMR)#vip G7G{SHWPRKB]/Ƀceu-uQr Q5K=l_":\&#i 'C|B(ޠM'X0587$~;R|B!-n0jufQl3ٹ+I}`l Ǐf/&|&߳wb5a̳;1^1̃|,sż䮉A#?7;]1v 4T}C`)De*mWm4]a#>dUgq'%y(]_V֞~g ׷R"baS7WhfJ PRU+OPbŬslEZ2nL8`hkL+L }tEi3O-t&@ PE>"@P'@V2 Ȋ"@fdY [L *d }DEl 2O-x& E>"'U,"eXZZL@+X }hEm@'\WOož6}꽹;ox[}7~׭nUmnݶj^[mVgsw٪ɶzln[5V]ꭹ;kX[}5~WjUCmNݴj^[iVGswѪzhnZ5V=Ꝺu;g8[}hY왹e;f v_vٯѳQFcվy6gP˅/|*vo/n!+-,% %pT|Q;{k[x!q[nPJ 5(aT]&Ӵi!*7o(J; 9q/*q‹J"4Y{lS~y^T L8-SkҶmpԶM LƔE%{)E‹J)=֡i__" UX/*΋J%T$VӇyZ8遲%PSD /*QT$RyQevJi(*-֋*-΋J8U S⫘ɶq0Ok> stream xڍ\ے}ẈUQpRe;QEJT~vc.!CpX/qݧi+T`J y1ЇVCLhz1 ZG/;hܠ}@ Q<8x,̓u6E]cC ّ|bY\ <VY5x`Ճw6[3`0ZruX7lJ_aalʐ!xdz! SCHCTl3C5,sCpU9?ĨYu$SҚG!Y \װʫ!Em^)3~ Y+@s?7dCo> 9eK:|4Ea> 3}:"!U`4AbE^(E觐h3F F'i3&@q my(46#aOPAyHڵ MHDv}6g,KڜY`!68ܔ+8 NAgi|D|<͊`X&ma]&m*!ELI[T"EZ$mY`F[čc`{3i1T *}fD ln`m^IJՀi@ |aΝYn}ݾ]bGƺ 1uWQF9NԶa3Yo&5|yڝwT+{jbC|Ӷ]$lYhべiowB;am%?4 [ْ&0/ Mj&vVo@.*J;jzsyr,7񰶍9J53rU(F-t<#ĔKmBtZJ7t@r3.6.^p}f_&׉3r)O~|\~G\'\{:^̙.:J/-:N#D~ RKˠk4 H9F)cJ>t^yƨeSG#S!K mP|`02KudQ[ k3kް0}XfxDX:*7"FHlmKy"DlD9"g :q,?#͖nolXMOacՊ%,cJZ=FĂе6{ ᕖZ%pfRŽՎ܋Z'I*[-ExO2">b+"Biȼs1s͘G.v,z< (8JwHW'@xV"@{{K瀹!tiۉ,k<9,Oi˘[ẽeB'q2AŘic{y˘IN"FKy X踁* 1C7d9< 0c.,ݲu}H/˃G-YTLZ#=wYt\8a:#OA: ֤<]*J؅N:v@ &P_N̔Qr 3!àP4 P4' s_6yMKsry%\{qc2ףK?L)0rig\.̘˥s3[ڹK?2c2]< $ |^Vq \{fa3UOyPÁ.Vq ÀU0`BTVq _töi"J78Q7A¿nRoT2'Xt#fEMogRJ,Dyn5c.sP{/A>DvP xQE!ࣰe.;KQD4 ^Sx/TwoC ^^0R}/pp 0 N <eAAA6K{}bO> Jƻ8@CZ Gx|X`D< {yny<`Q6Q5`Q4x(w`1,Ӵe.o@գ@ԣ@l@ @c\f[N)< < "nT6J;;u}|}'O#OO5Z^]RN6$(?qR060 xt,:峾}>рxkny-x,0,2Y>{WQ[iJ)J|H?VC?9W=D-e-u-Ŧ--$EsCQXz-.B,+N[JL[jJwyO NS2+S2QS2OaEclmĈE8b#8b c%`#^]1]SFp3_~_E_acD*ND(Ng(^x=!#\?Vъ endstream endobj 3119 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.18)/Keywords() /CreationDate (D:20191215095936+01'00') /ModDate (D:20191215095936+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) kpathsea version 6.2.3) >> endobj 3108 0 obj << /Type /ObjStm /N 11 /First 97 /Length 371 /Filter /FlateDecode >> stream xڍj0EY6IfJ>V% bh_)΅<ݑ̙+YM CRBlrYM衠R7{J p )CAHD,m-;LT=SXx@`w͢bY[Ϻf<[/#Yh]]J VUX.AAA)GIc*̀ !!!gGIUɻ&u&'@1b+b+A@ ؘCd5x骯.zG=ő  @y{ :pXUm`l.:f70ϺG?-Y'fjQ3ެSj^omp]/7S K endstream endobj 3120 0 obj << /Type /XRef /Index [0 3121] /Size 3121 /W [1 3 1] /Root 3118 0 R /Info 3119 0 R /ID [<3CBEBCB0BF307785F66278003E0638FE> <3CBEBCB0BF307785F66278003E0638FE>] /Length 7149 /Filter /FlateDecode >> stream xY~z{efxx6e@鮎 9pPRXF "B( A\TsSKGHMPS ZBpD 뷞.W<]jZnڭ?v+B[mm/=οwj{fs,n3˵=j;`SھÌ=Vηui{lsv]#k`|[6zm=lḫvFؤ{67Ö"m_ ۴mC ۚ {ڭgݶ1-`n<_k(6gSL[87lCin0k6^kjo͵]yNjSpz-ݬ30/lӾh]EႶ. /|푶,9ီjL[}2׵6k33x_[8poi N ,i _+țXIA=mSB@Smm=J[8!)^2Ys!h[-䙶? 셶cڂƗ𭶫^iJ[kxn-[ġwЧG֪ЦOB}8ȏ`lZOxRЉAπ;^ x5㵠K׃8xt-6xL= 1SKֲM C7X4ڠHpU>ƍ0kdX -tr֭v8BW@&Ǥ8wLX"Ƣ2pn,c9 8EX'=cj[uı46/O̿''d(0Pue/[!tz _Lօ乷v؆e#Cȩ_~cXǺ=Ɔn50~=q. _XeQceo;7ԁG6+uڰO"X K`), VX `=|`#lQkp[`+lvnC%MԚAw&ko[ x'ץs\jۜL>{B7|gpa8Gs8`FCq8'3a=pwp.E.eW\07܆%|><7k8bZo;?; oOt[7:9'=m-|Of"hX \-\^> bWi+̪.\ͬ`3: [`+lƙ]pDQOS0zCp>cpKp~\07܆;pѨWar: g| _=\Z~9O蜌Z;#HARG:wpA؋ltdF$#;VG6:ёsKt# HG@:R;Z@jZ@j堖Zꐗ/֏jɩW /0PLPUaZjaZja0P C- 0P|ٯOE6j#Cmd lԲQF-"Ppx,j? {Zj9堖Zj9鮍lԆZ^jkkkkkkkkkkk~kQo- ~~~~~~~κu0"X K`i oaVJX٭:ٝ {c `?OS !8 >_DzG*tϏQlZ[p Ng  \pun܄[p]8C{~? >W_7sx! w:} o \}ByӟKDH@"ýUJX 03`f? ~@l a!Lp9.4džˁ De *Q@TӃp8p>| ΃ &9@r0 ` r0 ` D  L0=`z&8MVhO_x766KfAo,O %4RҬHi8o8o8o8o8o8o8oچІ#jj0[&1FTQiDfuprA#4rA#4rA#4rA#47777777777777777777776ghA MpnnFn)\ `!/%VG_ ]+a56\xG6& [@U~yvN~7Џ!́0ywNA9Gі?? 5q8 g`90\/\+puspnc8E;c{&Bm #VGs9 tD(L݁@#BG:vD#jGԎ}kre1, C 3V*X k`-`qnl36sa a] } {a | 鄹CpQBnDѕνĎ$vWM!͵aA-p ]3^Ypa 3O9r>|)SΧO9r>ձLO[LO A{t_A?%~J)96q>|)SΧ4NoEQ/̵|)SOs>|ipN)S̳ 6,/Ɗ f`xxu-l 6 a~;쀝 v(-G& tǎQq8'a4Ypy.p +n^ps{&{6܁%| ܭza<'|epSx/[^AC==!Ct={Vِ!C+ar>|H!`M D %b(Cn*Ci?dxDѿ͜9~ A!C?$~!CgA"!CL2=dz!p!#Q4H|?$~H!C? w-=|t=t'=^ w^hA~6X ܁Z HUZX#a lvp5 `7쁏a/ xƇ06[Á8p Np.ndNp|57߄[pZ`FX1` F݋MsQ{9X[+*bcS쿅O;ڽ M^NIOTz#G|G:qQu$!G|N'=9AOzAzrГ'=~{v%=9AOzaUD^-=~{D#Ģ'={#G|={a?"DnH@Oz"Dtޑ}W±EO,zb +uA/]9腵8rw'j_a/aD'=QAI޻}Vha 'ˣovd^W V'N B'4Nh躓Q_  XݓЋ 'atV'NR'a)GsMx3B'N:!t ' N0?'aW\Nh8q.n m|LnG_I&lMº6)QoIN~1|IX$,u'a ~>k'oRDX5e? `!,Ű2X1 X `5G6& [`+lv. {c > pp 8 4Y8 <\\p57`n- V.| _=!<o)<^·`O0ey 899999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wgoYyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyoooooo~[Q'y柝;G3Y*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9䠒J*9 +y堒J*9䠒J*9䠒J*9䠒J*9䠒J*9 堒ZI72ۆ,^Z޵RVu=ѵdvݯj4鐮]K໖w7E&]n7 zء\w=3 {c j]KY~ n}z&{Q<е~{<M4Y8 |kz[^at]7Ⱥz;.޻t-KZҵT%xkZ)֮^v->t gZڵkkz֮]k\Vv{Z۵2˹,'y>}9sy?Rry>}9sy>0>}$I'Or~_ws ;vU_[<ퟞ^ /C_0/ }a C_0/ }a C_0/ }a C_aAĮn-|6<t?8ky@Yxv$<Xт?65-+тh_ 5'ᑎ[xv)2!<#V!J֊н8L^2G9́g %\VignetteIndexEntry{A Common Database Interface (DBI)} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- This document describes a common interface between the S language (in its R and S-Plus implementations) and database management systems (DBMS). The interface defines a small set of classes and methods similar in spirit to Perl’s DBI, Java’s JDBC, Python’s DB-API, and Microsoft’s ODBC. # Version {#sec:version} This document describes version 0.1-6 of the database interface API (application programming interface). # Introduction {#sec:intro} The database interface (DBI) separates the connectivity to the DBMS into a “front-end” and a “back-end”. Applications use only the exposed “front-end” API. The facilities that communicate with specific DBMS (Oracle, PostgreSQL, etc.) are provided by “device drivers” that get invoked automatically by the S language evaluator. The following example illustrates some of the DBI capabilities: ```R ## Choose the proper DBMS driver and connect to the server drv <- dbDriver("ODBC") con <- dbConnect(drv, "dsn", "usr", "pwd") ## The interface can work at a higher level importing tables ## as data.frames and exporting data.frames as DBMS tables. dbListTables(con) dbListFields(con, "quakes") if(dbExistsTable(con, "new_results")) dbRemoveTable(con, "new_results") dbWriteTable(con, "new_results", new.output) ## The interface allows lower-level interface to the DBMS res <- dbSendQuery(con, paste( "SELECT g.id, g.mirror, g.diam, e.voltage", "FROM geom_table as g, elec_measures as e", "WHERE g.id = e.id and g.mirrortype = 'inside'", "ORDER BY g.diam")) out <- NULL while(!dbHasCompleted(res)){ chunk <- fetch(res, n = 10000) out <- c(out, doit(chunk)) } ## Free up resources dbClearResult(res) dbDisconnect(con) dbUnloadDriver(drv) ``` (only the first 2 expressions are DBMS-specific – all others are independent of the database engine itself). Individual DBI drivers need not implement all the features we list below (we indicate those that are optional). Furthermore, drivers may extend the core DBI facilities, but we suggest to have these extensions clearly indicated and documented. The following are the elements of the DBI: 1. A set of classes and methods (Section [sec:DBIClasses]) that defines what operations are possible and how they are defined, e.g.: - connect/disconnect to the DBMS - create and execute statements in the DBMS - extract results/output from statements - error/exception handling - information (meta-data) from database objects - transaction management (optional) Some things are left explicitly unspecified, e.g., authentication and even the query language, although it is hard to avoid references to SQL and relational database management systems (RDBMS). 2. Drivers Drivers are collection of functions that implement the functionality defined above in the context of specific DBMS, e.g., mSQL, Informix. 3. Data type mappings (Section [sec:data-mappings].) Mappings and conversions between DBMS data types and R/S objects. All drivers should implement the “basic” primitives (see below), but may chose to add user-defined conversion function to handle more generic objects (e.g., factors, ordered factors, time series, arrays, images). 4. Utilities (Section [sec:utilities].) These facilities help with details such as mapping of identifiers between S and DBMS (e.g., `_` is illegal in R/S names, and `.` is used for constructing compound SQL identifiers), etc. # DBI Classes and Methods {#sec:DBIClasses} The following are the main DBI classes. They need to be extended by individual database back-ends (Sybase, Oracle, etc.) Individual drivers need to provide methods for the generic functions listed here (those methods that are optional are so indicated). *Note: Although R releases prior to 1.4 do not have a formal concept of classes, we will use the syntax of the S Version 4 classes and methods (available in R releases 1.4 and later as library `methods`) to convey precisely the DBI class hierarchy, its methods, and intended behavior.* The DBI classes are `DBIObject`, `DBIDriver`, `DBIConnection` and `DBIResult`. All these are *virtual* classes. Drivers define new classes that extend these, e.g., `PgSQLDriver`, `PgSQLConnection`, and so on. ![Class hierarchy for the DBI. The top two layers are comprised of virtual classes and each lower layer represents a set of driver-specific implementation classes that provide the functionality defined by the virtual classes above.](hierarchy.png) `DBIObject`: : Virtual class[^1] that groups all other DBI classes. `DBIDriver`: : Virtual class that groups all DBMS drivers. Each DBMS driver extends this class. Typically generator functions instantiate the actual driver objects, e.g., `PgSQL`, `HDF5`, `BerkeleyDB`. `DBIConnection`: : Virtual class that encapsulates connections to DBMS. `DBIResult`: : Virtual class that describes the result of a DBMS query or statement. [Q: Should we distinguish between a simple result of DBMS statements e.g., as `delete` from DBMS queries (i.e., those that generate data).] The methods `format`, `print`, `show`, `dbGetInfo`, and `summary` are defined (and *implemented* in the `DBI` package) for the `DBIObject` base class, thus available to all implementations; individual drivers, however, are free to override them as they see fit. `format(x, ...)`: : produces a concise character representation (label) for the `DBIObject` `x`. `print(x, ...)`/`show(x)`: : prints a one-line identification of the object `x`. `summary(object, ...)`: : produces a concise description of the object. The default method for `DBIObject` simply invokes `dbGetInfo(dbObj)` and prints the name-value pairs one per line. Individual implementations may tailor this appropriately. `dbGetInfo(dbObj, ...)`: : extracts information (meta-data) relevant for the `DBIObject` `dbObj`. It may return a list of key/value pairs, individual meta-data if supplied in the call, or `NULL` if the requested meta-data is not available. *Hint:* Driver implementations may choose to allow an argument `what` to specify individual meta-data, e.g., `dbGetInfo(drv, what = max.connections)`. In the next few sub-sections we describe in detail each of these classes and their methods. ## Class `DBIObject` {#sec:DBIObject} This class simply groups all DBI classes, and thus all extend it. ## Class `DBIDriver` {#sec:DBIDriver} This class identifies the database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.) The DBI provides the generator `dbDriver(driverName)` which simply invokes the function `driverName`, which in turn instantiates the corresponding driver object. The `DBIDriver` class defines the following methods: `driverName`: : [meth:driverName] initializes the driver code. The name `driverName` refers to the actual generator function for the DBMS, e.g., `RPgSQL`, `RODBC`, `HDF5`. The driver instance object is used with `dbConnect` (see page ) for opening one or possibly more connections to one or more DBMS. `dbListConnections(drv, ...)`: : list of current connections being handled by the `drv` driver. May be `NULL` if there are no open connections. Drivers that do not support multiple connections may return the one open connection. `dbGetInfo(dbObj, ...)`: : returns a list of name-value pairs of information about the driver. *Hint:* Useful entries could include `name`: : the driver name (e.g., `RODBC`, `RPgSQL`); `driver.version`: : version of the driver; `DBI.version`: : the version of the DBI that the driver implements, e.g., `0.1-2`; `client.version`: : of the client DBMS libraries (e.g., version of the `libpq` library in the case of `RPgSQL`); `max.connections`: : maximum number of simultaneous connections; plus any other relevant information about the implementation, for instance, how the driver handles upper/lower case in identifiers. `dbUnloadDriver(driverName)` (optional): : frees all resources (local and remote) used by the driver. Returns a logical to indicate if it succeeded or not. ## Class `DBIConnection` {#sec:DBIConnection} This virtual class encapsulates the connection to a DBMS, and it provides access to dynamic queries, result sets, DBMS session management (transactions), etc. *Note:* Individual drivers are free to implement single or multiple simultaneous connections. The methods defined by the `DBIConnection` class include: `dbConnect(drv, ...)`: : [meth:dbConnect] creates and opens a connection to the database implemented by the driver `drv` (see Section [sec:DBIDriver]). Each driver will define what other arguments are required, e.g., `dbname` or `dsn` for the database name, `user`, and `password`. It returns an object that extends `DBIConnection` in a driver-specific manner (e.g., the MySQL implementation could create an object of class `MySQLConnection` that extends `DBIConnection`). `dbDisconnect(conn, ...)`: : closes the connection, discards all pending work, and frees resources (e.g., memory, sockets). Returns a logical indicating whether it succeeded or not. `dbSendQuery(conn, statement, ...)`: : submits one statement to the DBMS. It returns a `DBIResult` object. This object is needed for fetching data in case the statement generates output (see `fetch` on page ), and it may be used for querying the state of the operation; see `dbGetInfo` and other meta-data methods on page . `dbGetQuery(conn, statement, ...)`: : submit, execute, and extract output in one operation. The resulting object may be a `data.frame` if the `statement` generates output. Otherwise the return value should be a logical indicating whether the query succeeded or not. `dbGetException(conn, ...)`: : returns a list with elements `errNum` and `errMsg` with the status of the last DBMS statement sent on a given connection (this information may also be provided by the `dbGetInfo` meta-data function on the `conn` object. *Hint:* The ANSI SQL-92 defines both a status code and an status message that could be return as members of the list. `dbGetInfo(dbObj, ...)`: : returns a list of name-value pairs describing the state of the connection; it may return one or more meta-data, the actual driver method allows to specify individual pieces of meta-data (e.g., maximum number of open results/cursors). *Hint:* Useful entries could include `dbname`: : the name of the database in use; `db.version`: : the DBMS server version (e.g., “Oracle 8.1.7 on Solaris”; `host`: : host where the database server resides; `user`: : user name; `password`: : password (is this safe?); plus any other arguments related to the connection (e.g., thread id, socket or TCP connection type). `dbListResults(conn, ...)`: : list of `DBIResult` objects currently active on the connection `conn`. May be `NULL` if no result set is active on `conn`. Drivers that implement only one result set per connection could return that one object (no need to wrap it in a list). *Note: The following are convenience methods that simplify the import/export of (mainly) data.frames. The first five methods implement the core methods needed to `attach` remote DBMS to the S search path. (For details, see @data-management:1991 [@database-classes:1999].)* *Hint:* For relational DBMS these methods may be easily implemented using the core DBI methods `dbConnect`, `dbSendQuery`, and `fetch`, due to SQL reflectance (i.e., one easily gets this meta-data by querying the appropriate tables on the RDBMS). `dbListTables(conn, ...)`: : returns a character vector (possibly of zero-length) of object (table) names available on the `conn` connection. `dbReadTable(conn, name, ...)`: : imports the data stored remotely in the table `name` on connection `conn`. Use the field `row.names` as the `row.names` attribute of the output data.frame. Returns a `data.frame`. [Q: should we spell out how row.names should be created? E.g., use a field (with unique values) as row.names? Also, should `dbReadTable` reproduce a data.frame exported with `dbWriteTable`?] `dbWriteTable(conn, name, value, ...)`: : write the object `value` (perhaps after coercing it to data.frame) into the remote object `name` in connection `conn`. Returns a logical indicating whether the operation succeeded or not. `dbExistsTable(conn, name, ...)`: : does remote object `name` exist on `conn`? Returns a logical. `dbRemoveTable(conn, name, ...)`: : removes remote object `name` on connection `conn`. Returns a logical indicating whether the operation succeeded or not. `dbListFields(conn, name, ...)`: : returns a character vector listing the field names of the remote table `name` on connection `conn` (see `dbColumnInfo()` for extracting data type on a table). *Note: The following methods deal with transactions and stored procedures. All these functions are optional.* `dbCommit(conn, ...)`(optional): : commits pending transaction on the connection and returns `TRUE` or `FALSE` depending on whether the operation succeeded or not. `dbRollback(conn, ...)`(optional): : undoes current transaction on the connection and returns `TRUE` or `FALSE` depending on whether the operation succeeded or not. `dbCallProc(conn, storedProc, ...)`(optional): : invokes a stored procedure in the DBMS and returns a `DBIResult` object. [Stored procedures are *not* part of the ANSI SQL-92 standard and vary substantially from one RDBMS to another.] **Deprecated since 2014:** The recommended way of calling a stored procedure is now - `dbGetQuery` if a result set is returned and - `dbExecute` for data manipulation and other cases that do not return a result set. ## Class `DBIResult` {#sec:DBIResult} This virtual class describes the result and state of execution of a DBMS statement (any statement, query or non-query). The result set `res` keeps track of whether the statement produces output for R/S, how many rows were affected by the operation, how many rows have been fetched (if statement is a query), whether there are more rows to fetch, etc. *Note: Individual drivers are free to allow single or multiple active results per connection.* [Q: Should we distinguish between results that return no data from those that return data?] The class `DBIResult` defines the following methods: `fetch(res, n, ...)`: : [meth:fetch] fetches the next `n` elements (rows) from the result set `res` and return them as a data.frame. A value of `n=-1` is interpreted as “return all elements/rows”. `dbClearResult(res, ...)`: : flushes any pending data and frees all resources (local and remote) used by the object `res` on both sides of the connection. Returns a logical indicating success or not. `dbGetInfo(dbObj, ...)`: : returns a name-value list with the state of the result set. *Hint:* Useful entries could include `statement`: : a character string representation of the statement being executed; `rows.affected`: : number of affected records (changed, deleted, inserted, or extracted); `row.count`: : number of rows fetched so far; `has.completed`: : has the statement (query) finished? `is.select`: : a logical describing whether or not the statement generates output; plus any other relevant driver-specific meta-data. `dbColumnInfo(res, ...)`: : produces a data.frame that describes the output of a query. The data.frame should have as many rows as there are output fields in the result set, and each column in the data.frame should describe an aspect of the result set field (field name, type, etc.) *Hint:* The data.frame columns could include `field.name`: : DBMS field label; `field.type`: : DBMS field type (implementation-specific); `data.type`: : corresponding R/S data type, e.g., `integer`; `precision`/`scale`: : (as in ODBC terminology), display width and number of decimal digits, respectively; `nullable`: : whether the corresponding field may contain (DBMS) `NULL` values; plus other driver-specific information. `dbSetDataMappings(flds, ...)`(optional): : defines a conversion between internal DBMS data types and R/S classes. We expect the default mappings (see Section [sec:data-mappings]) to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. [This topic needs further discussion.] *Note: The following are convenience methods that extract information from the result object (they may be implemented by invoking `dbGetInfo` with appropriate arguments).* `dbGetStatement(res, ...)`(optional): : returns the DBMS statement (as a character string) associated with the result `res`. `dbGetRowsAffected(res, ...)`(optional): : returns the number of rows affected by the executed statement (number of records deleted, modified, extracted, etc.) `dbHasCompleted(res, ...)`(optional): : returns a logical that indicates whether the operation has been completed (e.g., are there more records to be fetched?). `dbGetRowCount(res, ...)`(optional): : returns the number of rows fetched so far. # Data Type Mappings {#sec:data-mappings} The data types supported by databases are different than the data types in R and S, but the mapping between the “primitive” types is straightforward: Any of the many fixed and varying length character types are mapped to R/S `character`. Fixed-precision (non-IEEE) numbers are mapped into either doubles (`numeric`) or long (`integer`). Notice that many DBMS do not follow the so-called IEEE arithmetic, so there are potential problems with under/overflows and loss of precision, but given the R/S primitive types we cannot do too much but identify these situations and warn the application (how?). By default dates and date-time objects are mapped to character using the appropriate `TO_CHAR` function in the DBMS (which should take care of any locale information). Some RDBMS support the type `CURRENCY` or `MONEY` which should be mapped to `numeric` (again with potential round off errors). Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion (as has been done in other inter-systems packages [^2]). Specifying user-defined conversion functions still needs to be defined. # Utilities {#sec:utilities} The core DBI implementation should make available to all drivers some common basic utilities. For instance: `dbGetDBIVersion`: : returns the version of the currently attached DBI as a string. `dbDataType(dbObj, obj, ...)`: : returns a string with the (approximately) appropriate data type for the R/S object `obj`. The DBI can implement this following the ANSI-92 standard, but individual drivers may want/need to extend it to make use of DBMS-specific types. `make.db.names(dbObj, snames, ...)`: : maps R/S names (identifiers) to SQL identifiers replacing illegal characters (as `.`) by the legal SQL `_`. `SQLKeywords(dbObj, ...)`: : returns a character vector of SQL keywords (reserved words). The default method returns the list of `.SQL92Keywords`, but drivers should update this vector with the DBMS-specific additional reserved words. `isSQLKeyword(dbObj, name, ...)`: : for each element in the character vector `name` determine whether or not it is an SQL keyword, as reported by the generic function `SQLKeywords`. Returns a logical vector parallel to the input object `name`. # Open Issues and Limitations {#sec:open-issues} There are a number of issues and limitations that the current DBI conscientiously does not address on the interest of simplicity. We do list here the most important ones. Non-SQL: : Is it realistic to attempt to encompass non-relational databases, like HDF5, Berkeley DB, etc.? Security: : allowing users to specify their passwords on R/S scripts may be unacceptable for some applications. We need to consider alternatives where users could store authentication on files (perhaps similar to ODBC’s `odbc.ini`) with more stringent permissions. Exceptions: : the exception mechanism is a bit too simple, and it does not provide for information when problems stem from the DBMS interface itself. For instance, under/overflow or loss of precision as we move numeric data from DBMS to the more limited primitives in R/S. Asynchronous communication: : most DBMS support both synchronous and asynchronous communications, allowing applications to submit a query and proceed while the database server process the query. The application is then notified (or it may need to poll the server) when the query has completed. For large computations, this could be very useful, but the DBI would need to specify how to interrupt the server (if necessary) plus other details. Also, some DBMS require applications to use threads to implement asynchronous communication, something that neither R nor S-Plus currently addresses. SQL scripts: : the DBI only defines how to execute one SQL statement at a time, forcing users to split SQL scripts into individual statements. We need a mechanism by which users can submit SQL scripts that could possibly generate multiple result sets; in this case we may need to introduce new methods to loop over multiple results (similar to Python’s `nextResultSet`). BLOBS/CLOBS: : large objects (both character and binary) present some challenges both to R and S-Plus. It is becoming more common to store images, sounds, and other data types as binary objects in DBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects. Transactions: : transaction management is not fully described. Additional methods: : Do we need any additional methods? (e.g., `dbListDatabases(conn)`, `dbListTableIndices(conn, name)`, how do we list all available drivers?) Bind variables: : the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of R/S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement /* SQL */ SELECT * from emp_table where emp_id = :sampleEmployee would take the vector `sampleEmployee` and iterate over each of its elements to get the result. Perhaps the DBI could at some point in the future implement this feature. # Resources {#sec:resources} The idea of a common interface to databases has been successfully implemented in various environments, for instance: Java’s Database Connectivity (JDBC) ([www.javasoft.com](http://www.javasoft.com/products/jdbc/index.html)). In C through the Open Database Connectivity (ODBC) ([www.unixodbc.org](http://www.unixodbc.org/)). Python’s Database Application Programming Interface ([www.python.org](http://www.python.org/topics/database)). Perl’s Database Interface ([dbi.perl.org](http://dbi.perl.org)). [^1]: A virtual class allows us to group classes that share some common characteristics, even if their implementations are radically different. [^2]: Duncan Temple Lang has volunteered to port the data conversion code found in R-Java, R-Perl, and R-Python packages to the DBI DBI/vignettes/hierarchy.png0000644000176200001440000022345512721354656015372 0ustar liggesusersPNG  IHDRJPwFiCCPICC Profile(c``RH,(a``+) rwRR` \\À|/­+JI-N8;1doyId$e @"- v:}¾V dl&]| SR@0$AIjE v/,L(QpTg^)(!?ÓQ B bs$20A20,a`S3d`g`7' j #1!>CI pHYsgR@IDATx |չHH&  hPTIe K [B@?JQ[*P-޲IPH,H s dO&3gY|uf9K<@@@@@<4@ذaǻt `\,/@@D% 7nL6M#8T':^*C@Hzڏ uԑiԨH` 8u D@(Sfgp     $Jݼi    -@l#@@@@@7 QL@@@@@leq    R7`    e (-ۈ3@@@@@Hy<@@@@([DiF    n.@;!    @$J6 @@@@psn4@@@@ QZg     (uy     PҲ8@@@@\Dw0C@@@@Hm     $Jݼi    -@l#@@@@@7 QL@@@@@leq    R7`    e (-ۈ3@@@@@Hy<@@@@([DiF    n.y 6liӦN>}z"    QhqCX~R[xڵR_E@k\__t[Q>G@-GI) M믿[Y&+)IrѶnZZ֯RCO~;i>VsbDZU @@L,@ĝG  sr%=zWn4[lH{*;O~-HlZb™#ẻҩ;^fj#~ [I{9)4E@՛,}#`9nqv\N$%Jbbw 40   ++  PQ$[=[̅$wy!""=.nڟ]f7LSx %ݝrIrL_P-G$*($2%}dOjM,JçΖ-}1Yp XBs˜n 3[S},~5RXğ8+\>(CW4ms5ںrĆ @1Z<ت3IOmeOl=%@,**Y\3om|^T<mX}@d>v}uMD 욾 5Jݻm*a݆^ =KOd\4ٿȽIKWHU[1)*[k>[#z^-[lۏr2ܡeW-'@@"va@@|idL I4r>LJIm6g 7rtUE'=&'SR$99Y\cwѤdLcZ!ٳg:_>}:)+9~IIH5'M}`璚-i22zUx2)fd1v4hGVK^Jt"u#I<{fH$czrG- )e|{\IO=$K/5H=cg"j)}'Y^mGW?ID驒} 39AL+/5ef9*)F_SjIv1Ҕ2e@@{ 3{HY  `mʮ]QF)R.yhOPc&ʢըlY:OF[%YWT,mNY*~mlG}T8Iʙ_8>} ir~Iz>t(jhAg$hWW&eK wA|2$@滄Γ8ԢǞldjppHbMZ.2w+v1Kdͨlc3'vcUewK\I^˼,0c iذL8 v@L'Ru# irW(1sB$UeIfF.'ON*H'r.@!ŮR,?IoTf!3[IRuOƨ׊$$X&.FRH,6Ij$:M$Um_mlZ#taXѩAdn ?P8 @@$JH  @91,cd%D,bsJ55Br̤tNދN brZ <`34ӷe?YuBL-%Sn7FuNۃXumZ$:i\g=VdSEO-#V/F&Wr͔M?ʢkEH\֏3~' 7퓬V/LxBN /|^p̜INd n|  `w۝@SH)'k˙id_ۨƻN#i6Pߚ_Ίs%-\P&%-/iY )!ӈǟ.Z/4hXmW*.LI[o6elհ]ؿΔr-hQH_닋Bnэ4@hf2  @u xo&[/i,и]JZr:zUDTzgȚw^)L"|,F^{Pef-[UnFī  H:Κ@@*+_^l׽̍f>؍*[-! xkzN_R@@ -ؼm$r@@ (u*?# K?X]2SBك)8|D>!ߋ`4i09 @@8s  .&%!Q$θeggKI&J|" TEOUZ@@ q   `OS@@@@@$JMm     QjOMB@@@@S (5e4    SD=5) @@@@L)@ԔF     `OԤ,@@@@0RSvA#    =HS@@@@@$JMm     QjOMB@@@@S (5e4    SD=5) @@@@L)@ԔF     `OԤ,@@@@0RSvA#    =HS@@@@@$JMm     QjOMB@@@@S (5e4    S˞Q O2ydiР $@3g̛7$@@MFq[h  ,;wt@ x{{s=W+8@!@    `RSw#    =HC2@@@@@$JM}     QjE@@@@@S (5u<    CD=)@@@@L-@G W̙3 @ϟ7E !@5(@k׮ɲedРA /xDid[n>9 O,- ^  i$J=i/ Nؽ{e„ BJ8}$%%`ddv]v%66Vڷo/cƌuIvvٛF  P 5ʥH@pT=ztɒ%#G#GJƍ=\ Ç_ۗx\Yj۷Ohӈ Zj٭ B@ (5o9 .'puٰae:A#\:$J]/<%vڵkE%MSRRdС)?N@(FDi1(< otrt͚5jv+=RDGv4Z-ojei @@Z@@ZZXB'HHRݱc4k^UP P-Z^{Mj3<#wyN@pǴ@ ͛urһ׿{ҹsgAA |AQ3fȞ={tTaj~F" @5 0)@wPԺ+WvITT 2DܡyLwrP}7oޔx4GISuʁ #RKZ ].]*AzE{׮P jՒ^z[vvlڴI'M'O,aaaz>}+7@@(-  )?ѣjU~ڣݻwF:*,!111zDZϴ[nRF*O  x7F@\N:9l2=bTm4l0wX H_zZΞ=+k֬I3g~#>>!`J6v@rre-~~~zJlAP  #be״@iiirJ QrfL*BG(K ((H~޽{uҴW^:Q>eVBu@)rBq ͕͛7W_}% .]8:CZQZ?|:i6zGD2Unb cH:ƙZ@(ÇurT m׮DEEM=ԩS283 (5So \~]o߾]z)4ӧKZg 0廈@|QN@FzLWP@ʒMJJ#Fj)@* xyya0׮]7ի7[4Uy #Jݹwi @ /^,ׯ.]ѣdS; 0ԝzKdݺuzzÇ%<<\ϐڵԨQÝJ[@$J @RSShQ3FF)7`IJD)p}ާFFGGEmfO~D @9H@<[ƍa=~2tP=z4$$ijah=v QjD@ǎӣLW\gPDDDi֭U! `7D@78pZfyurtF)8WDs&Pv=j]wUb@Sة@DQS&Mjj}BB4oܕ&6@.fV۟'پ}?{l=%?22Rk@02j\ veݹsQG4]ci.&RAj[i\\t]|١oKr@OgK &8r䈞Z6urԩS" 'Pvm0`]rE֯_/-I&IuҴGRV- @}SO=&-WDyӧjFիW(S5=l\ @HV@\Y:9|r=vec W5b4kÇQWi-O , L ̔kɓ'gO?Tڶm`@JxEf̘!wIP ISgÆ K-@#JH .!)jh^f͚.A @(-ޅgd7orz6m{L'M(wy'v@j`Di5R4 @ :uJ.]oYfIrj@@jUS*i:e IS޸wO )wZZ ++KԚ _222tt2~x]G@ZWg$&&?|/,?//"! P FVK@#g%I7ڥKׯxyvV@+Pn]yٳf3gf#86(jCpYMW@=e˖*!ݻw4n=L@@\M6^zIRRR&P/]!*iڦMrI (6s ܸqC6lؠG۷O;\U`3R 8p@'MW^-M4 Çw]x@(FŠ s%Kbѣ걏sV@0 noܹSk׮Ҿ}{ Txx 9@`D@*pyYbZ55j4oܡqP8Oγf}ZoȥKDm6- `fFpQYQWMiS?SRF @Y(u<"@IzJaF)?$ {(u~ K?~\]ls=zja$ %#pM/Dݫk֬VZ餩|Ӹqc@L 8Xʕ+K7ey|zg$@@=̞=[[:u>>]s &` :@W8uꔨiK,z#FJā&` ;@@ ##C֯_jmv~@.` ` &D'%111zjّ#GFGfXu 5#v$JݮKi+p9QkZJj-S5ҴcǎkB@3 (5So+ @={董j.]]/^^n*|XFP[5<҄F# Q(iA,p=rtŊz(2dSTe (-ۈ3@3RSS2IrQAEFFJppgj@z_8RzGUf?j(U˖-u! AYf/ѣG(_z:~DD1BZnm(@@ 0 t2tҥo>}zY&[GSQ)=M;@^IUV=ܣGѦwu@#HzdhpǏuGUEzÇK@@;46  (Φ `W>Lz!42dԩSec&0@UHJO P1 E54""BoU8p ޻F?P@MARdԨQuViժ [C  TL 00PLoПմ&MX8QD'wUXӧ̘1Cz)g2_w1  {u(;wIST(pWj@zz_=n&uGMmƤ6fRYKi x;ޜ@GWV҃ x 4߿9"@*$ qq2x+Wdڵzj/#GԻ}5H9@@@toooyիgɲeW_}iϞ=VZī Q hA7)jh޽f͚i"&`D:P@;\xQHP#M=*jT T.]P:E  QZy;D78}tuJTTAZ~}7j%MA\SDk Q!PW^-*i6KU[Z۔pã-N} 2YYYb <<\222d/, 4޽* PQp9 .ѫW]y.+!  @ֹsd͚5oӧEe;vZ%\'fN4yl޼Y.]**):p@ }'ܧ6sN N8!R Su HHJJSWX?_ "uP[D@W8tN%5j7>|8\È ` t! @/_֋jjͨQd֭ҪU/ @@8:͜9SvܩOtMtTmZ~}s P#JKp@^^ѣһwoQ=FN@%R{IR @Y[Q[lΝ;뤩 je:/RcZRRRjQZ?gQ s   }۵kdƍ:iF̈^z:]0nݺ%#Gd!uB@!@ԉ PGGi֭s9 zo#\*-+Wp t=~2afXF@@>~'||{Z4,,L?>w!y(>8T믿Sz:uS:X@#Jw `&(>Lz!=5`$V QZ O!@Ξ=D_dԬYS'GyiҤI j@ QJ@qlٲE'Mm&ݺu0;5 M6ѣ{!C(>f@@@j׮-ԷL=tѢE+O?j15\_GDK !!A7o u   @95j$ƍӷSNjkdzMvڕ$NAG 0ԑԅn޼Q;vȀt'0q@Q @  #W#M(ӈiѢ#(Ce2.,/+VH۶mLϗ;ih?   P!ۋ͘1Cvޭ=zߵTtСҰa  `?V%%!6/_?X???ٺulܸQ'JIMW:@IDAT@@p@ΝwߕG믿.jSܐ=tz3'Fx#J=i8yyy7f^zɴiDYF y   `ZjI޽-;;[6mڤGN AXd^A#jѥKJfQ5CÁ #Xԁ `65/&&Fo64hN> f1[giQj"P'pYnNDȑ#}gJ( @@@u֕{NΜ9#k֬ѳΞ=+Æ #F?\ 0 ;wQhnQ5CM@@Y(u<"Q %%EO_r?22RkڦM36p).N>իj:ѣ/ 4e @%HVK@08ѦwuF} @%h\ կz3tYx$$$Ȅ $ !  e ӟȑ#oʷ~+]vuN:>x`DGt3{jN:ѣgwDO@;@ 0ԤG .)#[n Q? {wC??"1?.:tw}5Ex“QIM[R@-=gyuֲgYb <$[:B-&Kl… Eˁ ~ZIIIzeˤ]v2~xٲeܼy5jȎ;EҹsgoAQaNsCƍi&=zT"2d=裏Gi F/e#Jը߾}aÆn@@p dڵzj9zFvҥ ˯~+ pSQ)=M;B 11QL Tm{OHE@c4@5zPu͚5㋙- @m۶+x = ԣK&QxROmjJ߇~וy/R:*Qkv4 g (US T1i$VZz]?/;ȳ>+j:j@>^U;[ѣԨQKy @P̨/ɓoMi f~Ni~5?gΜGꤪ^ˁ 0z8M@MG/ Mh{|wtR}urTX`{*@p{5tΜ9:Q6rR3+8@@9>>>zMR.iiWw QꎽJ*+L8Qݢѫ?Dz}ڵzJ1B?Vq  m۶?0^xQԨ]v7O& B@}@zJ& gZ.7h@V^-+W _w]USyCW/ "/xyyɵk$%%E+X@@p@MJ\@M39sK{=ƲI.]^zIoEI~HZ"q@C''N5T|@@%@YkZҥ;rbۡvTkL0AR@(^@%GH .x@@1Lw3'|"Ndhi;vLN5@<^UVҰaC@@9(u;L@r _~Yӥ$j^ffdM%\@.#$@@B]-0@q_|DEE稍'ԩ7PkJF@i׮׿?  PѣSN%  8Fq ۷O}QַMʽ+m۶ }_=V}&m%a#   (5Fjƍr&/!   YD{@@@@@.ldF A@@@@3 (5s;    ED])@@@@,@̽G     `va@@@@0R3#    ]HڅB@@@@@^*ׯ{3s[@B@}ڴiҤIg 999oKzz+C  .&+"#;op?5h,_~L8i1Pq|w.ޅg@3 X~w#JUcԈ^x"v@ AҥKpו6l+u .$p)Pll+c@ߝY}I     `v@@@@@0Rs#    H"@@@@@$JD    v QjD@@@@@s (5w=    AD)@@@@-@G     `v@@@@@0Rs#    H"@@@@@$JD    v QjD@@@@@s (5w=    AD)@@@@-@G     `v@@@@@0Rs#    H"@@@@@$JD    v QjD@@@@@s (5w=    AD)@@@@-@G     `v@@@@@0'z dIK}ߢ   >xI.A  ,@ԓ{ ۞{e$1kt Y=M@0@, jǘI 7@p@&'k"Hԕ"M[Q2"֟ZD w@N 7[/Jx+iīA3fXع3SSnjkJZ6#vTa|@@ ͒=s]8(ʓ)M?I lIMOyD{:"uRNCipwSicCEN:H)u5CwD/׷/iW[5#1ʩ(4]Ff|2mP\uaҴe ҩK_"9iUDIV@ޛ{RzK6P{-UۢCOwh)rTײTt;29hq?|8~[ϕs'JcsxX9+/c muƏ֟ZlO1  =sy罵b|-/P?5J>Ԭ2oZ%"OϾ"im\#S>h ccn:wM )υ}vwfjr`q| 7O1w \ȕm*sf:F'[,˔59 AUcdev7TC&vR_.22 X T731FFO/{߬)FS%1-`-LTm.??]7Hq](UTP '1XT&SWW?X]@ [ޖY ~m>s,ϭFL>gl8?"wi$JTA9]ڗYrh9v;M7dA̹r׫fE>)1E Wz7?/9U&0r")Q z `V$7j)$$iqVݻxV = _)LUKLp~^7~_i&,׼6oLFI YgA՟q<6oR%Y .g}M;5潯e$gƲ^u?xܼ%}1>clSrD%r..7u̼q燎7xmjԩ6Y㬯/=xn%U+oŻgFl3K.0}sV{=TPq>_U,W-_kIK,?W= Y'68jHWËysms{fI%cQf2bfOUP>U3oSQJkzpNȲZzʚ:[% ٲ7U:53K3xpKs~6٥~ҐM39zRf_{7Wͅsy*;M02bY‹eƭgI2zK6QjM~?hq#L{QƏ/>;Djx7 \h[ Qiͫ4Xt# JpJ/R'H+=:H>crb\7[Y`IA$餹Ѳ;1w?QU?l$ڀ@6hqvX]~emk.l4-npkw%tXk B~ddj&".M;wL2$Ir?{sUJ w,uÓa@ ީ/zwݺ{j$Yk*-:խsg}./rZb *ަŽBFb^* O13Lc^h?nUJ: +t&N{/: zkځ \"U:F3?RvS|6?urE'1OF̿mmӶkf}l;Bհ8ks**-E4 8F{Sڷa}b1k%Ͷg8 1{Q2] ~QfKhqp9?\aW .ezr}9S9{=>To@/3 ~rty#z)Jq2StfM}ߵfzX,Uő\PJզ@ǣZ/O>ykz.hMU{Yð=B؅ 0<׽PJszǾ֣YW[Nx(K vz|xTY3ݕrYcfWVfio:ۼ7W"VLL?;:ߨ5o&1C4LGLy߬8g}{VMPPK|單̥JZ(X̽qsbZ7({4yEz7b؉L<7\5chEҪ …qׯoFҘQϽpTy)v-n^2]e3%#O{^iˆa6<״Eg`^hR6o嫸&3Ov>3,|ǝnYnF7 CߨE4I@ ʏb]LrVO{$[CƝϪ)kR WBjmԤ~x2ڪ__'H^ؚGۗ̇¨O֕{ FYo5'MT7xΕXӚҡڃVI{]]{fP!&v>ЃukDƾ+_B՛FЭi5/;bj$V}KyId_t^J5OOҦczq } tҕwY"=MO:JV3 46aq8"Wn@OFRkz01 Qs@`" A쎦[mPڊ~Mј;jm7?y_Zo. 1uZ%`a%=+OkwͮݥL-> D PNw'ض+ޅtx5w[wH;;0-[5 q޼ܵI=1)Y{o_P{KoܥՎ^'ť %zX+ԃ&9NfV/NM\] Hٽ256iFkP7_LQXs++d\ٗ;BH5ڬ`.Uj)s>,k\Zuik{Lj툡m19kXOd9]9̩\sؽ럜݆<}Fp/-]7*S.awo?j[]nNxu4_=5գJKpZo#WUi;jib/ݝGǓ`SV^zN+eN?UN'WyKWg:? k(m᷂üz}gn)#oMt̓Ua+ֺ$>G5 l` \"k 82qy@`iY>7'x30O+o~PSca4ڻabs2==crѩƃFR+(Cݝ7֙lg~kzcUa]%լ?y OTNr &, 0 "mzz}zUjo]ݷ7uu~|jjMm:7#X]/ا?Lw{,˜%7($( =m^`î pk.tbc|HE8jVOw N.ܡT}g;o)1Js4u-&wk˶9 7ڄ)!vN ya!ɕd 5@W T;YS\ a\Yv0 .p= Z~KwQ=^|.[I3t3?f3kӤ&μnn(7z@}bwbOyKwhϦŶVTrq__q (ҨzK}KC\ln.n:s Ρjowkxm\@` {bp׿#2oS7ڸͷ]]?zYvqU^7ڢwgW7o:i^]'ۤ7p߷ ӏ%oS.J~b=Ъ:9Mڣ8>xh~G*ڛPO>gnMݱiI`xj<ӧNIuǟoj*bpy+^~HNE:sͱQ5L]UoL#jCixpڤ1Մ>+]MyԜ C95Uka[+M/!N/wbǞF\BB{OR%Pϛ@R{.>3o@=o-Y{%B7 {/JY0)S6wkǗ8 %;!ֽٟh{(5Z1=yToӥVȷ9o6xܼhj1VϒBZk߭[ާWGqmey_}{U9m/6Ӧޫ>⵺d|>&cFnjK=TL=NfkђeZ45Ma=u7;e߼Yk=!_ޥ[j=gNJ- h:NY7_ֽ; sYo)>Sm}_nPÏdzʦ7Nי"\yY@ "0 &_eU;жU|[TksG_lWybZiw׻]߱ʼ2)"7O7:K e4Jm\NsV>zݶw+hY?}\qjvR͞+ϢE;j <.gm< |CY, hUx3O)w̵sNUª}Hwo}aLaxjCc>*_ `|iqq8̗gx"+/ÐwwrF-g[$y_xߚ5k'A*%ս?߃Lzu:h.tBy_ =ezSYF_~1ߑRot޻{IűrOmMo룗_1Tp7-쬏r^2xGˢMXZno%uV_YYY#Ap51sؾ78P*\Տ1կ~/px|UվC}eE[;8YY"J-VM 94FW`-"Ʈ1(`lG2[R#-߶ TG쓆C/jS|ˉ߾:{/3o/7x}יSަC1 2 ұV{d/ǻc)Ѓ q0/{x̐^Uc, _ T|G7eÑك  k/G}qX6;d0kvWǒs ZWݨ+bx*pCniZijw/TCMϿ&*TUZQ]s“!̂hNqaz޿QnJ s_W;Osj@#0 Lu #K'l <[ޥklY6^,mW!u+ "3fn}a1Tj3t>l+ Bo t4CM`YjSyUjdƲ,Phn4W-^g?ih-aʁr&GQPp8;=gwr䫤Z:: @սW/c敨ցt{r DzORm19Tu䤺Z'CzTmUV^sf޾:Too_)WX^ ~X-*oSyZrG%mԖQ6YEQz/mORhUaL-kۣP̈́6+0Dˊ#,k"g 0AxOQIѣa||>1zS[mѦ<ya}U|WU;{?d[ y?ϳ-U6 ጼMj>Ra^iZ-kSCGYOO<裏/Ѫs|,δ!(37LkYk}!yԬ31C0p >\O~?~ 8: w歵SL'uŜ9HwFqlљsy+e֬9uWDžV9Ϸi4sv+[,<3r(wwu|1kߴ{rll[,9|+_1giÆ "U HcǼQoΝ4\|yw˪{iWQVL慈(ɚ9Yq͌޽/|4͜1C1[ c2*v:D539+3 jB@`HYZh~hFfգ}UIxNz+#s4v #/01EٹfEsq#`&w mPGbc'`h#    P:E@@@@@@`h( ~@@@@uJGH     ]ď    .@C @@@@@H7l oүJ-_s8    !@Cn~\x1 q@@@@tep     @ 0Gi B@@@@ P0j"B@@@@d4YKt!    @h(M5!    @ P%C@@@@@ a4&@@@@@ Yh(M֒!]     0JFMD     4&kɐ.@@@@H &"@@@@HVJdH    $L҄Q    $ Z2 @@@@&@Ci¨@@@@Ud-҅     4aD    *b%K.??&kI Ξ=/|WrH L:UUUU صk`yveL@` ؟'b|{ŋ'9FƱ@AAF9xgeU, &O{׽$9I d (xv6c    )(SEb@@@@@`$h( UD@@@@1%@C*.    #!@CH&    )JTqX@@@@ JGB0@@@@@`L P:"    H$uC}ݧΑ ^۷o3 j,iDXݫg}6ӓo|Jp&'? g @Dq"D܉UD;q. VOO8/[o8:( <_JgΜ|p}8rB@]gK+b̉( @3    $^ě#    $ IV $@@@@/@Ci͉@@@@L$+    4Ĉ    I&@CiA@@@@ PxsbD@@@@$4     @h(M91"    @ PdBr@@@@@ 4&ޜ@@@@@ h(M!9     xJoN     d4&Y@@@@H 7'F@@@@H2J@H    $^ě#    $ IV $@@@@/@Ci͉@@@@L$+    4Ĉ    I&@CiA@@@@ PxsbD@@@@$4     @h(M91"    @ PdBr@@@@@ 4&ޜ@@@@@ h(M!9     xJoN     d4&Y@@@@H 7'F@@@@H2J@H    $^ě#    $ IV $@@@@/@Ci͉@@@@L$+    4Ę`GyDiii6m7Pff}n@ƣsE} ?&MǬ'@<;B$ q  vttS__}uV@Y4e;o_z I@@@ p³sI5z='J //'R|V/+VD:>@-`9і hُ ΣO"@Ci1k߰o~s@Xn6F<}ҥ@HHh P:%@ #3sLzDa' PİF0|SJ\ $LgQQ PCWӟt>^gBC&@=10:? /s)YJG֗ГD Rz$I @` tMa9bC ;@@ xvNB!I 4D6ZzлgJx@+iRF0&g 'SiP:5V3&D#I//2 6mN8J'\O Zw[  H D'l@NSƚ cH=|3dF.DA 1q  $IS$dh(t{'zN9+ 0yJ'O*#&BG@Ə,h(Wa@zB$ zbL:O}j $" !CM,J'VyOZ=|&Me˖Mx @FN'': #L  02<;+& _Fp>փ+{@/宻:̰@@Ygd.6)#8a#l@IDATz{߫%K$[H 8XzY L'B)H4FRa߸xu @rlذ!9B*@@!<4. EH@@@@@ ^Jz@@@@4"$      r=    yJ|@@@@Wx@@@@Ƽ c    +@Ci\    c^1_d@@@@H7}{z{315c@Ng%@{{~a|dĀ!ӣ}k|^aȥ$RggJ;qիYBm۶h&HG}_o͛7/iDB@H_Wu5hÆ ƐcH?;P:a ԩSd-\0FL'o=b0cM`ҤIz߯%"~7rLv<;߲%gG\      Q!q    JOY@@@@ C2@@@@?4$'     0DJe     0~h(?eIN@@@@@`4@@@@@`P:~ʒ     h("!    t%9A@@@@! P:D8.C@@@@#@C)Kr    Ctp\    GS@@@@(@C @@@@Ə ,      Q!q    JOY@@@@ C2@@@@?4$'     0DJe     0~h(?eIN@@@@@`4@@@@@`P:~ʒ     h("!    H?Y!' 0:.G'mfF@YCmVM3c@@d4J4 0AԴkr[=ʥt>D]ڷvۛӂF=u_69D@`\hUkoJ'sݭW-Pvyp4X @.uӜtI=t9;ÿ-.sNgOwϏXْ}FU@`La%MNQjzSSUOLe Э++;2͖~mٮefyĉC:yF{nvЪ`_#E~q" W@0HvGv̜)=W6-p$|WG)w+m\eUJ˕=I'ЦٮSuI]47\x:̗hWwaQQgap~#lR^oICKZUYzG#—*;Y e5=jOx}}Si(Ļ-/4&m5-PV@F\g~yvVǫzdr2'U]QĞȣ]A~7Q1R[Yxɓ*7j Hy"9}m$ ghg5ui׫C Z6.mϟ졞jnW}}NA? 5fCF^`Q+ɆzxGFR7bmޱ& -CBAı֥9z#izv#nM0%%[>OGC:h@WgD%Tkż5Q%$t}>Lf0,Cx quRs>vo 4JXᆱӿ>lzz]}>u.:{^3s*-MϺVX~>8Y:v07e(7w8_Góh3?/ۼϵG>Ku\8vT˞w'_٤ԹzB7Ohme~q^1]7t_Pev߽9fvK*(|I[WlWOkSN-[*&}!~s:k:gƔκF^9-tE cL쟟(%un PGk)6[9tu/TQ;L3ZKGU+z޲O:]f-[0t17wt}Z_]Buy"k}W]\=R_uٯ:gVG m>{:N/z{L{Q_-X*sw'6MOc/]ۯU,xێwo>ZWO׎뉒.pc^RMKzw3w4>oA!]mjxIo!ХF:كP\;t꼰zTZCf^+ϜNyY?iGw}VyDkb}q{mf e\zJO׺aeNir|-=mzSLby3D-ҐEY~iitF/{U^:+Sr>r]g "@ƞC{vVufO[^jzvެ?ghϭzHE[(A5/AưtR_mm n_E|?YO~\gA#tܬ՞rgz;r]׻;ry(cKۑoh?=>jW#-[+zg.7'tj+]K8\v)?k ׮g¨unP#JWlw\w!GP}h{}N:6#a&xwC=X.[l޽;K|sV,lݺWVV˩C>*wg$z}+qnV8_gyX͆v/[}?rYE+|E^W`˯Ugy|vpsݱRL\8OQ?3uc: ds҂XaۈCb_II+^_qISlS~H1}ՅQ U*EHgabp(ЀI+.73!RGT-kqLK6Ysj5C;5GSZqBהN =YPBқguk=އte>5W5ԇ:AT_f6ugڪOّv3?WWX?/z7PgM X:{άy?~XZLKCFV=W_uTu;)׋ ⫯dnV͎4E3W05;Ljcޡ7FXWt'BW:֮vlj9h q¦&6[ xp=l x޿myvFnR)UO8h]_}~#&)i"(La X?_mOCZvs576*壶9JG?XW'5FMpk]7፤ x ꊾ^s>vFyZkzO{ig55o;ޮ1uV]eAXXf>QPcmd$CK}^2/}mfʃ(H+Jџ]Hj) 4s)K~hmn$5Oa?HZTVc?vP\ tt&ޘ=@#$] 0n[0/7Y_u=c5K4wf&]Tܦg[hvm߰24|yZ+/zL..)׶=q\_H_T,ӋAEaX<]eP,vQi\Յ 9xjy=|5P7=q,{/6=w7zLe*+) ˛wyJ7g_Mv'Jl۶vzպ=7)LoVSviټLJ.rv!W@0Ô`x \H`D`9y3mgϿgHo:{(|*@<#U_W]¦wցѮ /wMg 9>t1e Ѥݴ3Ȫ7p)E>w⮧=E):) {3y(lڧ/2|`z#23$4l}BWj.W+!pOWXgxY?;{Lrc_AA5Up2.㺧 o#_;RYg(.tޓYCKC!eC'COPF{b 0j\i/T͐W#[EwZcܵM-r{H?^󎽣˘z.WPQ7ߍzd0.>3)3/K &sþ)ԑo+?l1Avd,&3lMæB3av)ۧd_uB?wkﷶ I1]_yO^1Zyw f Ǒ##QfU-j9v nXOVt)G9rLb'꺠Sg2k¦q ѡڃΡf]}.QUsZc{ᗛaahʕP)dmt]9Ǟ՘m~`]2 G_k}'g}CaYkaF05K*ř7 [Ҟ [ͮJ[̃?qk]tywBNt N_`/-k x9Dl j,;tRf>O5#%0_Vi邖hTfej`w𷳏ipwpeZC_IW]俛hz;L֡Ǖ+i(M3$LG7+J\o] eۓ2{;]j;+(W~l@CkoGz᯴nn8©gz0p-gjb {4ӳ7ju\ib ޱB?Їl~kFw>%+_~B UV[_юyhV{(Y!ѯMGP_u]0C׏~?K5>Ҳ_ݧtS$Гljԧ?|3y#oi 3:4fvvg)#W lF}-tl )}f;[V |axJj͹t{N6Sڕ;+[|vsg9iZGx2I#hkT#"r"@,tyv4^%^]kk$'2ܺmȽc%QZ;G~oq kۈDD$"܎ W#O70 ' t(h{~ξ B[/;2÷\A;+:tSBu -*d~ի'2+q6y^̇7_?B_o>Lg~~.nSo7/2/r~Gz^UѶ{}3ޙ<i'KdMvc!pq $@K3t=*S[iuݢ[_]8[g.齹.RզپSmghzg]urGj=שɎ&:f~ٶAK+dשƃFRkm^yf^NWWvA+IÃv8뫰:R3iܹVgrr;@'seϳ_{Z*^=?-߿.4 "lRn?}-noE͎|Un7#c|w`c@J$)π&>,X ڝOչ1o[}  Ny ui)Z\eKg+^+o]4hŝfEo;{B=Y {P@вϮ m5-izsGbVOw ϊSrݟ )":Nc|;*5 {{[M7ͽūo~JyQZNթU>0ݞ@` Lv}߼~q?_z c^i F_-?%[6=~Yi|]c ڸYٳI |usm-s9g 2Ž>YUoܣ=4ʭ騞9gt}8ʢLie+\kzOM{:xPwe;֩) B_gk\7 0\<;4P9 sYw&OŚo¹zJ,Ε}ϏqV[Vk l>7lUoW?lD៟0 Cys}Y`t]%4 ~꾕 c P:Oo+ 8KN\4yL'7Yޏv LN}U j vBjJǵk<{6<'mPR4> | >ҶtCm:N'=Ey*ա{tg-0)_8ݤ:jl}Q [M| ᘭiQ}/7=nf/HѶ{o ckAۛjMf? tBZNʙP>9u2#N; mVаOMCK|A{ۥll&o GiI=o-Y{4.;XC "ӡݟsǎj8hqW;VGmg~޻T^u^;M=QwܪzLdP/+ue'uBo.ӻtl-YQa<ywևtG'~Gqme!:#usz3#j :S϶mNשjh^~њӺwhmPn1tbyI2CW쵝ua=W/t4K~f]fqQa=K6{<i/)P;Ny^P7y\%ݪ}O6f1R6[jB'g1a 0xvWDRӺ֤޺W&^KOtL:gNJ-rU7KF_ZFo|JCe9޴x}Eme-ް<-77,kl{ˮy\x82oku_þk *o=V1t&_X|K=k/%v_p Ɓ=>1_7ƛwwrFcш8#[cwٷHw 3<":*ϭIoAWTy)>վ - ;::'} }M-;,/k<./7uf?uu~1ߑh~*sa6W,跭﬏RFd>_[62܂+#y&eC9vD[%<;G֏U>~$U'z|EC|gނP?FFeoluR{ s[4p{@Fٙ Kr t3c[pG>Zrm"xRvmݬ[K2zW +jy=Y˷T8Qeye_Ly{gցvq$}k*mp.tԹ9Lt^z{ٟ-#/c^\TcGu|S @wğP!PsٓOr ^w6o6\j!OCC/1wJ׫81GoD nTv1[\nX<;j/хa|w4;^m ,JZBU1fDWrpgH' bYoi,Tmsڐx`&ݱ=4)&]>mZ5$Бͷ&vM]wTLzmNf;=gwjOJ*)-H %GH@`\ -D$d[<(Cү^mai;#c9jVMQr3nNUJTLOֺ<ۋspjoH_O޾QDMG4ODGΏ]cƹYuu]ޫk&CR[(i(,PmK,ތMj>RhAY߲~VD[$bXr:[jUVo7tm\֛EƝ΃/R9h7xߐsףa_Nz~O}nKL/*V 靗7PzyUYZ ?_{f8fs޴y,C~Ԭhu]~PN7/;Meյ5Y|@#mwa}ÑjP/3j|_B !yN9&[LV7ouqt-7֛yZ'Pcc}$N%IW TFF:ޠ~ޫ5koOH_W4k,mذ!! w$W=j;ըߚ Njrf-:gz=^*?+yY3I+} [SODӯBs23/ic9gzG|5k23}UuruҦ10;.X\2M3gP PH[鸠3fFuw{,ovpqXqO9Lyyiwh~T}sf?jyӪc064A6p(1-qiv>ԤcZLHtĘsnybL!0]j:A3g^٦Qa%!/+{ۀs۾TRHZoff.[W6:N̜\ N+%]Ygb{HzW)5? ff 3/i+󙝕ZfdfدH3㬯Ms| :o&'De5@&0{!!7n,Yb(W5305AP:̠ [󗬏!qDo qN6XC0W( I)HR J &QB%˴xGVyjoӽot덦y!kΙ-|%hو@ W ':@pp/`c P:|B8ݳZU%ֶf9X/8xP_s93Ra:ךv1XܼYEaa$@"Cq#@C)J2ү@JVoc~N ӣ!u߲  @H*d $^{ěcR $}(2Lb&@K{Ή.B@Q*K4! 0q8eMNb`@@@@4NR'         LDJ'bg@@@@pP`@@@@& 3    8h(up    Q҉X@@@@4:8@@@@@(@CD,u    Jl     Dt":yF@@@@ 6@@@@@`" P:K<#    CR     0h(N@@@@@!@C @@@@4NR'         LDJ'bg@@@@p8@ F3gΨX1^i h}{뮻-!SN֭[.iH@K`׮]*//Ɓ¸?;P:{d2?N 0,%%%*(( yf]~!+ƹw]{gkk>o~:qDp OѲ>Mn! SM@@@H.UVK/ >c[ <_O4I+FUQ?03gTff{7    G?ouocXCC *@Ci|^^"lҥ@@@ӧO>ξ-gE"c'LLJܯڈSx    .`=G[u]ɓ'wX$-o1bʬ=    @l'd,/Vmf: J O)V84&qY[N2şB'M"i 1 X]vՓ[/^ nGiL Sj}9}lAp>LJ2?iICINO~Qq@G>OhѢEǵ 0Nh(M₵)4iW5  c]zYaiJCi$! p r-tD '@CiHxbYv1?iICY[o8ު!q,  H X󔦤n(Ƹ I^Vk$O)C@``?^s/V=gaʂ @`%KTc\$/|PmmmIJ @l) -B@/`Mon\B$/=ǂ xpSj=XCX@@^dMsǂD4 @@`2?Q0   BA`q* /I7%@@_ @!`S:eʔO`@@FQQ'jٻ6;__vb\4]'ŢMJS$Ҥĥ !U}i".Ɋۤw}pE(O:bE,[:(--q 6`nTޞIǶ,yHsf9gfPUڤI꧀(@ P@~ 4sC Pr u]7%BR(@ P->>(@ P +J?K/ܹs ,(@ P(0Q:sK P(}cОvo <,(@ P(0&X P&7 | _Yg)@ P(@`Gi3H$@..\l۠2U|G"9x2 Q^u}.Z Wu'OB`LȲ4MW_}^{-,YfJN B}ݗq@iqu P`Xg0zA 0fώ4^{5#<_vHL9YQd!_w}n5Fgi.vnۃe%˅SG_s|+ew.rF\2(@ P OG=ر?!mn@cɂ s1]V\U,CTͣh|+iFV-Mau"m`SDQ.)?}ڃ+I7z'mg~צܹSݻw=A;U,u9EcqzqL |8Fhd?R$+B@r|mIwe=#okL+- d+Pms!r.0ZvsLB*/҇DۦTa$nH:L^Z$yzq0ɧoZ^NC'̥$#`ڼJ4(G]F{5٧H*-`hR(yt{N@fO}`8¾[m0'H-_^JnXԙ/3Sޓp pNy6]z͗xc(j[{̷Goe; !# \" Im5ㅉt tirW;GyʹITv[-V2!&+>YPz޲n :ܖ3*kt;jqc:58N=Y+@@8M1Eh1CMPFSܒ|"h\6SUMc~7#mz[4k]j=ż_mf2AO^g[ۉ"U>Tj.Gy yaw0L&zG[^7[2܄c! s4vvA8x.ۅ'%X4KmzF8 Ѣ(_90ukS%Qvoea&;1O,qR{?u;فNM3`z6iG=:#VӦ',`foeMgOJP-wܦ>MގNͺ];aTw?l//7coNQ^ ŗtpG|)2~&_hLDxFciLg,gm>nL5~8O0p|+rd&Ř\"sx ^fuz6 cc-R4c2aS'WrPve\(0ȳ꥖B}bSmnq#_k q|Nl*)_G֢0Q=vX㘞2%[ڶv9tіg> P Ncslء^cζe]| &ݴ5v)wh+7.z_ jjv`S<onمxaquRWE8x$7ivqv؉,bh.E3Qa3_jș:7HV3]QaCTcNn9kFֻ#qZ5:[Hc`GiԷUsW%^=+V@^MbM6}Smf6oތ|v\P[, گ#3$g}_Zb_Ljr nIJ4\˖݂j%bX'vVˍF 6sLxU{ U6l#&:U'[[ y-k@k @k#.#v=NӸzr](@ L2S8d#eI QnCWjх٫MEw̋Ƽ7&c_k.[9Xs@ls•8Tw.o a zy7yy Տǡ :SRi7.vׯ6εf9dACS+rF9zy4>Y˒^+̻j7."yY6blV^/s3Y7Y{| eza~WF]I-_(0*qieG.. !;r_| ܾrrzA1x'ЪdQ>"BP154w/$ǰ%çb+f4mFzۈkN/ .p5/d+*jR%q$ybecvٷ?^%Y aOj:$ kţkbyT`DZ2s*`dv$?!g5oCbf,ZӪl n,ĖCX3!`BپCϡ+8M^M+Qrd~v, Ǭy xMٍq(ernD⒤XWΧ5jnʹAwYR|ܭ]97RY%ݾr1S5jG>wWAr'{wh4o9I[e l[bW;Kssxqwǩ7dyu9~~u*xdhڴxHO<-v]Fؗ|NSkش>x 5XwY){ufẻn'UqNՎk?>[LH&q+C8>p=n/]?zȑ۝ζ;tvȫë'_(3j>]]P*uȓqJMF|1ɘYgzqR3oU-oÊGȣFПΝY֤'bJuXUؗo2964l]rP{${/S_+H6 /GAgS?}\$|]jkʮg)@ L@ܨ(GRȞΉXy|/;0Ǿf>z~5r:IP h=tSvF1|Ђ+oɹS(ˉ OyJU}T<'4~,Wp֣IYd׵9u(H?oVݽJC?R:Jz`6W%﬏e+rw"EV4dE.S {r D P`&O8xIk5dDnUY~^ Z'݉ w9{21 ,>ԷeVaHD=ؤq;vWm7bF LD{s]y64m_0i~* M =|uŐI~)j3]2 =oc1K#z.;Ion|@^3wћn#ȇ!U h+WoXdO;nXons&D`=YN:|yb,:f1$;W]:g2yA𢡄QTU46?V \rly{3E/xoXOMh_F :4RmzHtM K~S^4{% u J/[r.ٝ oBX7V6&%5Y Pv,h[k%4E`WVi3Uwl]֠TL4˻N][d<~Sult̸sHl*g@ba cK~Z=*:Eh |rU+MlT}߼D^ilZT T/Iª5Ss`.g#oȎe9zȫL3:{|)q5r6SRqk!!rzrO Uq%Jv)z)3 rsi˞"|}e^m*-+}-k\:o3jU峒>sW̫dL]͇FV,Sr$g[fjfl4:I햤>z!HNbs"کlӿik˹Rn{ QWD΢rTVYHSh_fz̋PK8x.7v_-?is E|y^Ś9MX}{vsƴcbdPOq{:K<7LpnCHStʻvxl֋,]*,qq~N33[>N3ǾPҺԞ~KRKǞ]LvrK;YlmY-ZW m3z5JoůuI9{0ԎgcbW-6JM aǣO5E5ط}e,?8v𑫡WOk5~?ULqVG^b N3ᙰU-JGi&G[q0q129 P9E8x.weۆv|U߃ _T?o 1͞fL}x/<{B,܃F_?Şґ벣tuԯ_m-ѫGG_Ol|Q3cg0rͶa6ķ [@>,o P(W{'C=4yj؄)\Fu%wl|Szk ON7cp4}O4V4Ύ E[ky pBޜey_`|8낑Y]@FN{"_!Y-jYuM"Fk[@D !:'!-W}jht 1%bGF@KO͡k˺jqiXvv)ݛ1ymR|*NF+{:0${vlM^5" c+me?[aٿZ!chPn'-p@,꜖ ]aKm2w5zh$ ujS uPW@gaMѧ%1_mzAS &}˟p\]Z)EE_eʃ#,Pt zEG9D Ԛ/-o]S[7W} tDma)#dMc=7c^;6h:DȿI{l$(ԶsV,Ȳ]UW*JŒ..)-?&T _NKe;U뮆]ޣ^^FkI0 ;R6:jc)=1YHymnt5ReOO<<(҄ 49Ro%EE]BGpD{l%)|_ƒx<ܑD9nn@18*'j,M:Цtk-)s22FlNhdG.*,|b*πe'z{M}qR՝U|W;|)'k2:CfgL 휲}d)vHL3Qξ]M<&&k4} RŴ@ĭM$'}}mH))V^+S:4zq:GH v68_| Ig#dy^_l52[[kh,ewCdT9vm" ŷn,fwmg8yy{%ڭ<޼Ɋ/|% kYG' rT5w:C^7/]Q˷Q߁Ez\A}[*h(>RԶ<>'ll!d4g[cGVyicd^nb:4x3442(C2JoP'!_Ry |YPFSjb{K{|d驎 >m/؟Y(@ E8x˺]M<&&"k1D%LǡT1m11a2ٱkg݇//WGzXLҮMܪC5ӯO` >ƗyX 0܊|ojdֿ:> X:|c=cK.f]MIn}7ȧ )ڀc!zZݒbr[ *gҜʕ+Z. slQ]'o'm-ELM(^8-cCaaKwfm 1X+_ܩģh,7=&%$Z<)veG%?ҍD6DgS, T^9M-IG?6W]lӛ %o[wȋ_:2)2;|zpU|AؼYsCErH*XSn7y';rX+J|?8|2&*K~ߚh昨y&Jo;.2˃vq|>b!!O*]A RĶwUhHRpچ> Guqf(0T4/2DgK]!R1'󌃙 d˜G>wCYYt8prN|{Wz3K䞋g\˯l㚥v֯ "cƬYt+$H+wm(KP^ CPX$.+$5w̛?߉Ҏ+Rq\`׮]7ood4RNOfM C! ,i02xQT濸xf]z)S"W!yEa=#Hs(79P?u{F:ҙs1g<6'KQG`?zRN,R-G9'Ud DJyR~ԓŴacb/Nts:S){{ ! Ds`Q(b|Nyn1J#i&lJ\.S*]._YU-roNU|7UXn P9(ByJmFd,XT\l"._$eNU&3^EM2+N}&sS+0YlJ1lw[6OvO%XTa%&LQ6[($So(f(@ P(@ Pgva(@ P(@ P(@q`G0s'(@ P(@ P@> 4F P(@ P(@ ;JDž;(@ P(@ PY|t7 P(@ P(@ P`\Q:. (@ P(@ P((üQ(@ P(@ P"qaN(@ P(@ P(@|`Gi>(@ P(@ Pv 3wB P(@ P(@ ;J0o(@ P(@ Pt\ P(@ P(@ P QGy(@ P(@ PE̝P(@ P(@ P,|>:(@ P(@ P(0.(f(@ P(@ Pgva(@ P(@ P(@q`G0s'(@ P(@ P@> 4F P(@ P(@ ;JDž;(@ P(@ PY|t7 P(@ P(@ P`\Q:. (@ P(@ P((üQ(@ P(@ P"P4.{)a{V*C@q&Vqpbw P`t3ΉkQ`,XgK]n 0]vIu]/~ke P`,Ν;.m P`ap(W3`f Sy%8`GinBS Cq0#KA P[MMMBh"/kQ^^"fXguV 2=(@ P(@ P`o?}(P(-[ .g\vex1G(@Ü 8(@ P(0E֮]$z:Ky;sHr+zrk(@ P(@1#W&ɬY`ۓ(@ P`vķ)@ P(@ P$0|hMړ1J9Q@(Mߌ)(@ P(@ P*pM7%ҥKuJ_(@(MI7(@ P(@ P)p7Cur-֗L P@ VVV𨀋ϢQȩ@^uj%kPP(@ P` h "R as 7X_2(@ P,SOʓ|Y4 P` _JJJ֬Y_(@ LE뮻uI{mŊ֗L P@ hw^'-c̢Q'w)'n3D P"W~#Iꪫ8>i _(@ ?akʻ3 ,(@ ]GiqJ9>in)?(@U:N)'U}D P(@ P ](SI=\ ]:N)'-#Q(@ Pc-qJ9>X} PSr|xg P(@ P 2 (@ 䋀66}C-ܒ/b>(@ P(@ LJ($qJ9>\1(087p8쑻(@ P(PyQ]s`ڵϒQ)X"-1)(@ P(@ +6N__s\f(@ L_ Q\\ G0T+v%_b)(0 ?rRc-0c lذc SY |;z&ΓH1(s!*(ͯP(@ P(@ P @.)@ P(@ P(@`Gi~(@ P(@ PvN:wI P(@ P(@ ;Jx07(@ P(@ PtйK P(@ P(@ P Q_ǃ(@ P(@ P&@]R(@ P(@ P%: (@ P(@ P(0(t(@ P(@ P/v`n(@ P(@ P(@ `Gs(@ P(@ P@~ 4sC P(@ P(@ L;J'(@ P(@ PKu< P(@ P(@ P`Q:%(@ P(@ P(_(ͯP(@ P(@ P @.)@ P(@ P(@`Gi~(@ P(@ PvN:wI P(@ P(@ ;Jx07(@ P(@ PtйK P(@ P(@ P Q_ǃ(@ P(@ P&@]R(@ P(@ P%: (@ P(@ P(0(t(@ P(@ P/sOg{1)%3(@ H`Zgh (@ Pd`Gdv}Usn<عm>"mp8?6g7W)kh voNx#}7)?*xnn4T&sJy]+OG5 x;w.][+BH2Fj*(@ P`r qjܚ{ u/YOBc? QIƴo|[oK*>[{bYOoˠrrKdƑ{v !j]ywT"g_wwQ&}sǃͨTb8\.ڿ?=ǷbsYwFH~6FsjǺ)@ L@!ӏY!>kT{\_c7QYIѶӛmKiݑڑw5(_BNOi_LbukC2Xok8&Öe fqFyb4a3g6rXwкW.O%=/_Ԍ4/iIi٘-h44ufZ޴A@$Nܖfی9x}0PW/]&mo5c%flb ?W(@ P /Jm~ːb[V:+b%l$Q۞4jtb`;6YWmو9A,jof4x\HRH\tRo}#ld*:#@غ<0 (@ Fqm_GzT؝8+܀BI*dYOڬ P`|rt{n|8R'6YZ,{~،<Dko8-CO rm~ zJ*ifGKټ -?*C8}ޢn@_:{_gkދ*f_ws^|v+Yu3w@ANj5w`ebh^y۠\n'*ο+v߆*Fۏx!*^.'{O/p9̽l%,elcM+^k(*Y!HqnoNʼnW T+à|h6[9t'^=Wega駮S;`[}eS/(@(:8n QSOx*zY!b}N ߩf\ua4۰e%rtxסFeb7?7BI#:{}<,= ;j ܿ.^e {ƄWݵp߱3}84~rU47߿s^3 | Uk\ASh~?W¶`-?v hs*qwbXΜ=}qDDŽq{~ļj'^~{msۥ׭$4='wPJRey9d±'U;M&;;(ŠEzHa'x]B\y <2W6JYo>_|( \ˑm;-<g`;ljt,'q;T>.5Įuw'>#6jt8qͿl)R9eObڛIxoVߋXs{i LC+Q~h'Gj}"eH(ӊ?@ֱ6y*_@|6w.q%IDATM/bDESO"ݾ{=yk.r{W[Jŗ[DOmw5VD}z#Vi۷jmxz-~~e-]/߯ XnT6/E(3hK2$p(ɮ6# p`|BSL} b+zmS~&ZaOnuM2@.ʮddrs 0+o%VGkO2lMS@@8Mq.=M [cW({$#P>cXeǔ8XgKnu4 5j|"h%mtF^=~p=٦ ZZ:MAKed}%RMu^ᩮ.KjzGx<^Ѩ5O:d0C%[ĭіWGuj;=#ywz{k!#^l"G:!U|F AcUVδl=BީS-oz{WVi|cSn5e/gXEt[}=c䨍tfKvi8BL6Fm phHlFKS ;CZxᏏ3#|#U!Qtfj㹩cY?@6sfCQ4Hd%Zo7Ωkp0GԹ-7v\"mڒXGvX1FK~p|1ʭL歏|ξ]'xJQkIfL>i7_3hkmЧS>ֿWRNZoϢ}-D:<lK }Fՙ,qdJ^he޳k 9{ L8`n߮]4jѼ؁]U˥q2֤-7#Y6=m2=r c !o翱 U7onYKźz[۰ڶ`W6{ǂ[ƣmU[fmmceB| 79e45::nOK]雐W\S oZT;O / R'>yq[ܨn@.aΜ j/8w܆M^y=T[!y-cԹ} h hmץqHseW% PSA,^{1Б=~|r}l#qG|\رq5)Wxtm[O9UI(+bd2M~lqƙwM/J~vJo9āAXeN&?ަnD.9+"N~u>mJ;|8[޺'MLkSM/oNxv7Zc7!Ԩ6sab]Zd}U+ߵxR,$v6nrW'OJr,q/lzR݁[sR- P`i_"VgܾfP{;#G㩽঵@ۯ5mjΆ. B5z !lZ*.iI]t|إ&y)gv]q 䭀֥yhvtW:ָrnS,5Yn7?ŴE=m6Մ` ɫ/LW}xY>QԤsWZψi%\2\9[eukOz_W+|Z(oO5rZ!/7^Y3yسJW&e:cb| :c{[.uS#7ؿKZ?@0sxrEiS;gOĻEXd3Jc31# ]"z+o7+Vcۆfa]mY Vؓa\~#7:~prz"{@Uv%g\(09XZm;Dof:Vt~iדىօp~fS|زv >h>)qu#F4x';EX$؟Ν$ƌzG[ZGqwwĶS DCG;uyU=ٱ1q˕uNu,'.>}_+{~]HޑslO?]Ae|EMg=jd׵9=rF.êbPPp]!d%JG\g$w-RXlջBw.[`)'UaN`~Ȭ}buGflcukyk݇_l"8mԲ+kD*Yrqdnk1\;VtoԓgwlbmbR @No `':i3N>8uf45vЋ_jc摷s;b:w|p;͗Wv'-x0Իx䍞F2?s/ҥ1|On"K2Gu>$M$;_F8' ܦl{jg?l:e+n?g)@ LRs;)´sHn)(W$geli]ٲ'mq߿j4:`ۜ?e^'I^]IYǏ4K.3BV"% X\ёan+G?~"L\7dx[%Rm55昽ڲu K^q\8τCtyPn@X=q}>,{t\>bSPuӴ $V(02i_˨0vZXaZգo_0_W>TQKlxH&z v.l\kCk(ߦ&LUtjiCeE77^//$̕sD[bPCtu*3p˱.=jmlJۊu8xz]@B\+8rn[Tiڧ6;WFy;8ʋ,;=4?~ }qjc)ejTYRq+î]?guJRW6`*=뷨1W9x/~Z5 ݋JKf˖+OZlH}7JO:L6帣Ŗ6Sl14GIա: N ȓv p.Ŧgȸat20U踩c\ne0Vg޾X=\U0>(ryzqbOfeA D6z=6^U߁hZOe;-ƚY(yeG~bgyv[ʥ^/c>UeGc8 \ʲmݺO.S(Lk||-%yrLP6 GS/J\ؿ69t-º͏oŘZ)n9xwM+&~[ch~->j.5nPk""rʳ~Bм[x/a"kP'qLg;fe`ڶO3Of4ɇ`P?{s+U AsƭJ8fϚk۾2/efǎ>r5tkz}8ڇdwϟ{?Eܻ&+JAng3aZ𮑶X|' hk渍TW(0Erվ~Φ}X.Ӿk<o6ݶ⻸E<gEu4:A 2tu.?ݱGvoJ!; ىR{ocb̜TF\o0<3X;V.N@V5:EpW>h) qcv5UNM>BKlYg (3"E{K>K D6x@}uE[U}hܞIDkU>Sl`epm-~!nɗOwFAm?^e]- _U;2mFcd.\- zmc“uu{3f¢ѭ#z²lz!/2xe7r3QsNT޹_ P`(aZ/:CwKʘPgcWZ\ $Ē.Q)Z"cubM._OHO.Klyb`$nhkCu8eyRSujS̋;/îd]J lm~\,Mp?>Q[{]9udaر픺|脥ޑW.&JUa|4ߞH}G,Q>"a<~2&!ҎM+Z6H{Y{ O*O lMY}=)XeZ~Bٶ`BwMBqQ ڂ2砍*4,oBoS []juT=>d%أ>\qGdzC]Zb5"(XkTN;LscJZnB^[w$~BX]׃TTk]Gm[ h>]jRiuZHSI/_}0VkOKdMQN6eGivkmx& BEk&>uNhQIhFʜ[&kUoAe7e}fNXιc P`,ƪ㡣܉ew]lH۵:d]hKs=$Tct + ۳yF@3eψ#V/qId~Ol˼NyW}6#Ԕ$Zf:NNҁO22lvQOmJM;qa b XHiie'*S8nrׁ;h'S%ñ㟱Dz2OS[`\cѾ-X}ZdU kMxeU2XOnQMM~y2t/M'#߰a>I-WDszu$5ek'b\c\n>r0 (O:oz?:SکRTUܹ\yż|fٵvY.m ].4xm;D^vώ8PI^/x<` +eQ'_5~_(PtiP3r:p_!lz"_=رm5ZgB];CFcom<*aam" ŷno UlkaeSE-S~TeWnC'1@OSɜs*)2[ݸ=aْ[0Mj)Sjb{K{|dᔟ8}Z3GOlJY P`2 EZ:m_#X=L+M5.ZxȪ|lڵlcw헡>WT}T}h%צ]o}jƱ6aK|L@;GO4Xn/ L]4txow-v;z_}# kf͆Zˮza)W#36z^jJ8ۤ+;mN-J2\DOk,$gh櫕R_QdN%")fks:y{lˮaNPƹ[ P`L P>kCNcB!ÔX/Vi cmy׈2]4w-sry+qI^syD_ߌ6O6u)l ѥ1V"R7teFcu{ &l:62D{qt=LtOn ؐ07mPlU(4Дnlӛ?'͟&7)ēIr{.Ͼ !M~g?n7rҝ]$5{!kB\/6p}+>G:y @\2Uo֏({ԭtld<-D\zF~X\: zKnD\e~#Caezӽiͧ%}VKg } ZW[*Ύ@@m_z%.;W/SO\u'}9Ffysx-8y󬙧z3zcGm%zh(ܔk\|sDzY'Nh9W>P\ݡEn#S5ΠOJ>Y]wHw\dDW_ѡ܍9~@<:!տD}tHvojK?zSQIp K0 MΈϺɴ.liPPשAw{/.ׯ_k:0^ZzV)Z ~VtQ5;c;sSV~K6)ԄL߾$oo}^"#՝I_"/Cv,J]B;:`yF5kd 8۬vYalRwf$rG[cr[lZufȷk80ؾqqy8}~-(=JIswRbuU1b V/Z)mJK.y@ܤ}&cLLco"icEIS-+V[-[[CWsCJ^"jq0Sr2$ν]B Cm- KC$t˿O}՗)æ^K9qnئ%hKMؕ]@j'OJ6~Z9hħu]c_ABB~Û;J)R?sm_cHvN,(bEӶ2 p2׌wTJF ^- w[T8.8Kz ⠶)y:ϙ?i(Ҩ[c>[eT 8(P:+>jh&]U$]/;Iw' f: -0{4meq oFd,TՎ9(em!$# PguVj"@.4xn<Z//AkFiDwtIkM/o,&`D蕃lSa>[  PXOt@KbjSvO;tmm䷟ʀ ݰn={lvPϧ"  E VMņ @ZAÅ-H_Γ^ߚt %.g++vd @ ؃BDߒ$M3K~IH\%ۯd^ֿ=Zmc @ V}S@4HE |/1 ;|4,sJרAR  P@ R&5HV[*e/ 6y  @muGpTm$8_,E@ eV&?l.g  _:  @~IE@@@@#@;uMI@@@@@ @C2    xG@wꚒ"    A@d@@@@R5%E@@@@R      ީkJ    @@@@@;JSה@@@@ J 0$#    wz))    `HF@@@@(N]SR@@@@0(5     Pꝺ     ` Pj!@@@@#@;uMI@@@@@ @C2    xG@wꚒ"    AJonn'O6!-011!> G ܺuK=*---.9E XW+W2k2vbSf' 0vvRmg^V$a255UT@GVZ傜E\vV< @U숀;k= 0vZuNҁRd     (CvzIENDB`DBI/vignettes/DBI-proposal.Rmd0000644000176200001440000006646313054310030015563 0ustar liggesusers--- title: "A Common Interface to Relational Databases from R and S -- A Proposal" author: "David James" date: "March 16, 2000" output: rmarkdown::html_vignette bibliography: biblio.bib vignette: > %\VignetteIndexEntry{A Common Interface to Relational Databases from R and S -- A Proposal} %\VignetteEngine{knitr::rmarkdown} --- For too long S and similar data analysis environments have lacked good interfaces to relational database systems (RDBMS). For the last twenty years or so these RDBMS have evolved into highly optimized client-server systems for data storage and manipulation, and currently they serve as repositories for most of the business, industrial, and research “raw” data that analysts work with. Other analysis packages, such as SAS, have traditionally provided good data connectivity, but S and GNU R have relied on intermediate text files as means of importing data (but see @R.imp-exp and @R-dbms.) Although this simple approach works well for relatively modest amounts of mostly static data, it does not scale up to larger amounts of data distributed over machines and locations, nor does it scale up to data that is highly dynamic – situations that are becoming increasingly common. We want to propose a common interface between R/S and RDBMS that would allow users to access data stored on database servers in a uniform and predictable manner irrespective of the database engine. The interface defines a small set of classes and methods similar in spirit to Python’s DB-API, Java’s JDBC, Microsoft’s ODBC, Perl’s DBI, etc., but it conforms to the “whole-object” philosophy so natural in S and R. # Computing with Distributed Data {#sec:distr} As data analysts, we are increasingly faced with the challenge of larger data sources distributed over machines and locations; most of these data sources reside in relational database management systems (RDBMS). These relational databases represent a mature client-server distributed technology that we as analysts could be exploiting more that we’ve done in the past. The relational technology provides a well-defined standard, the ANSI SQL-92 @sql92, both for defining and manipulating data in a highly optimized fashion from virtually any application. In contrast, S and Splus have provided somewhat limited tools for coping with the challenges of larger and distributed data sets (Splus does provide an `import` function to import from databases, but it is quite limited in terms of SQL facilities). The R community has been more resourceful and has developed a number of good libraries for connecting to mSQL, MySQL, PostgreSQL, and ODBC; each library, however, has defined its own interface to each database engine a bit differently. We think it would be to everybody’s advantage to coordinate the definition of a common interface, an effort not unlike those taken in the Python and Perl communities. The goal of a common, seamless access to distributed data is a modest one in our evolution towards a fully distributed computing environment. We recognize the greater goal of distributed computing as the means to fully integrate diverse systems – not just databases – into a truly flexible analysis environment. Good connectivity to databases, however, is of immediate necessity both in practical terms and as a means to help us transition from monolithic, self-contained systems to those in which computations, not only the data, can be carried out in parallel over a wide number of computers and/or systems @duncan2000. Issues of reliability, security, location transparency, persistence, etc., will be new to most of us and working with distributed data may provide a more gradual change to ease in the ultimate goal of full distributed computing. # A Common Interface {#sec:rs-dbi} We believe that a common interface to databases can help users easily access data stored in RDBMS. A common interface would describe, in a uniform way, how to connect to RDBMS, extract meta-data (such as list of available databases, tables, etc.) as well as a uniform way to execute SQL statements and import their output into R and S. The current emphasis is on querying databases and not so much in a full low-level interface for database development as in JDBC or ODBC, but unlike these, we want to approach the interface from the “whole-object” perspective @S4 so natural to R/S and Python – for instance, by fetching all fields and records simultaneously into a single object. The basic idea is to split the interface into a front-end consisting of a few classes and generic functions that users invoke and a back-end set of database-specific classes and methods that implement the actual communication. (This is a very well-known pattern in software engineering, and another good verbatim is the device-independent graphics in R/S where graphics functions produce similar output on a variety of different devices, such X displays, Postscript, etc.) The following verbatim shows the front-end: ``` > mgr <- dbManager("Oracle") > con <- dbConnect(mgr, user = "user", passwd = "passwd") > rs <- dbExecStatement(con, "select fld1, fld2, fld3 from MY_TABLE") > tbls <- fetch(rs, n = 100) > hasCompleted(rs) [1] T > close(rs) > rs <- dbExecStatement(con, "select id_name, q25, q50 from liv2") > res <- fetch(rs) > getRowCount(rs) [1] 73 > close(con) ``` Such scripts should work with other RDBMS (say, MySQL) by replacing the first line with ``` > mgr <- dbManager("MySQL") ``` ## Interface Classes {#sec:rs-dbi-classes} The following are the main RS-DBI classes. They need to be extended by individual database back-ends (MySQL, Oracle, etc.) `dbManager` : Virtual class[^2] extended by actual database managers, e.g., Oracle, MySQL, Informix. `dbConnection` : Virtual class that captures a connection to a database instance[^3]. `dbResult` : Virtual class that describes the result of an SQL statement. `dbResultSet` : Virtual class, extends `dbResult` to fully describe the output of those statements that produce output records, i.e., `SELECT` (or `SELECT`-like) SQL statement. All these classes should implement the methods `show`, `describe`, and `getInfo`: `show` : (`print` in R) prints a one-line identification of the object. `describe` : prints a short summary of the meta-data of the specified object (like `summary` in R/S). `getInfo` : takes an object of one of the above classes and a string specifying a meta-data item, and it returns the corresponding information (`NULL` if unavailable). > mgr <- dbManager("MySQL") > getInfo(mgr, "version") > con <- dbConnect(mgr, ...) > getInfo(con, "type") The reason we implement the meta-data through `getInfo` in this way is to simplify the writing of database back-ends. We don’t want to overwhelm the developers of drivers (ourselves, most likely) with hundreds of methods as in the case of JDBC. In addition, the following methods should also be implemented: `getDatabases` : lists all available databases known to the `dbManager`. `getTables` : lists tables in a database. `getTableFields` : lists the fields in a table in a database. `getTableIndices` : lists the indices defined for a table in a database. These methods may be implemented using the appropriate `getInfo` method above. In the next few sections we describe in detail each of these classes and their methods. ### Class `dbManager` {#sec:dbManager} This class identifies the relational database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.) The `dbManager` class defines the following methods: `load` : initializes the driver code. We suggest having the generator, `dbManager(driver)`, automatically load the driver. `unload` : releases whatever resources the driver is using. `getVersion` : returns the version of the RS-DBI currently implemented, plus any other relevant information about the implementation itself and the RDBMS being used. ### Class `dbConnection` {#sec:dbConnection} This virtual class captures a connection to a RDBMS, and it provides access to dynamic SQL, result sets, RDBMS session management (transactions), etc. Note that the `dbManager` may or may not allow multiple simultaneous connections. The methods it defines include: `dbConnect` : opens a connection to the database `dbname`. Other likely arguments include `host`, `user`, and `password`. It returns an object that extends `dbConnection` in a driver-specific manner (e.g., the MySQL implementation creates a connection of class `MySQLConnection` that extends `dbConnection`). Note that we could separate the steps of connecting to a RDBMS and opening a database there (i.e., opening an *instance*). For simplicity we do the 2 steps in this method. If the user needs to open another instance in the same RDBMS, just open a new connection. `close` : closes the connection and discards all pending work. `dbExecStatement` : submits one SQL statement. It returns a `dbResult` object, and in the case of a `SELECT` statement, the object also inherits from `dbResultSet`. This `dbResultSet` object is needed for fetching the output rows of `SELECT` statements. The result of a non-`SELECT` statement (e.g., `UPDATE, DELETE, CREATE, ALTER`, ...) is defined as the number of rows affected (this seems to be common among RDBMS). `commit` : commits pending transaction (optional). `rollback` : undoes current transaction (optional). `callProc` : invokes a stored procedure in the RDBMS (tentative). Stored procedures are *not* part of the ANSI SQL-92 standard and possibly vary substantially from one RDBMS to another. For instance, Oracle seems to have a fairly decent implementation of stored procedures, but MySQL currently does not support them. `dbExec` : submit an SQL “script” (multiple statements). May be implemented by looping with `dbExecStatement`. `dbNextResultSet` : When running SQL scripts (multiple statements), it closes the current result set in the `dbConnection`, executes the next statement and returns its result set. ### Class `dbResult` {#sec:dbResult} This virtual class describes the result of an SQL statement (any statement) and the state of the operation. Non-query statements (e.g., `CREATE`, `UPDATE`, `DELETE`) set the “completed” state to 1, while `SELECT` statements to 0. Error conditions set this slot to a negative number. The `dbResult` class defines the following methods: `getStatement` : returns the SQL statement associated with the result set. `getDBConnection` : returns the `dbConnection` associated with the result set. `getRowsAffected` : returns the number of rows affected by the operation. `hasCompleted` : was the operation completed? `SELECT`’s, for instance, are not completed until their output rows are all fetched. `getException` : returns the status of the last SQL statement on a given connection as a list with two members, status code and status description. ### Class `dbResultSet` {#sec:dbResultSet} This virtual class extends `dbResult`, and it describes additional information from the result of a `SELECT` statement and the state of the operation. The `completed` state is set to 0 so long as there are pending rows to fetch. The `dbResultSet` class defines the following additional methods: `getRowCount` : returns the number of rows fetched so far. `getNullOk` : returns a logical vector with as many elements as there are fields in the result set, each element describing whether the corresponding field accepts `NULL` values. `getFields` : describes the `SELECT`ed fields. The description includes field names, RDBMS internal data types, internal length, internal precision and scale, null flag (i.e., column allows `NULL`’s), and corresponding S classes (which can be over-ridden with user-provided classes). The current MySQL and Oracle implementations define a `dbResultSet` as a named list with the following elements: `connection`: : the connection object associated with this result set; `statement`: : a string with the SQL statement being processed; `description`: : a field description `data.frame` with as many rows as there are fields in the `SELECT` output, and columns specifying the `name`, `type`, `length`, `precision`, `scale`, `Sclass` of the corresponding output field. `rowsAffected`: : the number of rows that were affected; `rowCount`: : the number of rows so far fetched; `completed`: : a logical value describing whether the operation has completed or not. `nullOk`: : a logical vector specifying whether the corresponding column may take NULL values. The methods above are implemented as accessor functions to this list in the obvious way. `setDataMappings` : defines a conversion between internal RDBMS data types and R/S classes. We expect the default mappings to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. (See Section [sec:mappings] for details.) `close` : closes the result set and frees resources both in R/S and the RDBMS. `fetch` : extracts the next `max.rec` records (-1 means all). ## Data Type Mappings {#sec:mappings} The data types supported by databases are slightly different than the data types in R and S, but the mapping between them is straightforward: Any of the many fixed and varying length character types are mapped to R/S `character`. Fixed-precision (non-IEEE) numbers are mapped into either doubles (`numeric`) or long (`integer`). Dates are mapped to character using the appropriate `TO_CHAR` function in the RDBMS (which should take care of any locale information). Some RDBMS support the type `CURRENCY` or `MONEY` which should be mapped to `numeric`. Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion as follows: 1. run the query (either with `dbExec` or `dbExecStatement`): > rs <- dbExecStatement(con, "select whatever-You-need") 2. extract the output field definitions > flds <- getFields(rs) 3. replace the class generator in the, say 3rd field, by the user own generator: > flds[3, "Sclass"] # default mapping [1] "character" by > flds[3, "Sclass"] <- "myOwnGeneratorFunction" 4. set the new data mapping prior to fetching > setDataMappings(resutlSet, flds) 5. fetch the rows and store in a `data.frame` > data <- fetch(resultSet) ## Open Issues {#sec:open-issues} We may need to provide some additional utilities, for instance to convert dates, to escape characters such as quotes and slashes in query strings, to strip excessive blanks from some character fields, etc. We need to decide whether we provide hooks so these conversions are done at the C level, or do all the post-processing in R or S. Another issue is what kind of data object is the output of an SQL query. Currently the MySQL and Oracle implementations return data as a `data.frame`; data frames have the slight inconvenience that they automatically re-label the fields according to R/S syntax, changing the actual RDBMS labels of the variables; the issue of non-numeric data being coerced into factors automatically “at the drop of a hat” (as someone in s-news wrote) is also annoying. The execution of SQL scripts is not fully described. The method that executes scripts could run individual statements without returning until it encounters a query (`SELECT`-like) statement. At that point it could return that one result set. The application is then responsible for fetching these rows, and then for invoking `dbNextResultSet` on the opened `dbConnection` object to repeat the `dbExec`/`fetch` loop until it encounters the next `dbResultSet`. And so on. Another (potentially very expensive) alternative would be to run all statements sequentially and return a list of `data.frame`s, each element of the list storing the result of each statement. Binary objects and large objects present some challenges both to R and S. It is becoming more common to store images, sounds, and other data types as binary objects in RDBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects – perhaps tentatively not in full generality. Large objects could be fetched by repeatedly invoking a specified R/S function that takes as argument chunks of a specified number of raw bytes. In the case of S4 (and Splus5.x) the RS-DBI implementation can write into an opened connection for which the user has defined a reader (but can we guarantee that we won’t overflow the connection?). In the case of R it is not clear what data type binary large objects (BLOB) should be mapped into. ## Limitations {#sec:limitations} These are some of the limitations of the current interface definition: - we only allow one SQL statement at a time, forcing users to split SQL scripts into individual statements; - transaction management is not fully described; - the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement /* SQL */ SELECT * from emp_table where emp_id = :sampleEmployee would take the vector `sampleEmployee` and iterate over each of its elements to get the result. Perhaps RS-DBI could at some point in the future implement this feature. # Other Approaches The high-level, front-end description of RS-DBI is the more critical aspect of the interface. Details on how to actually implement this interface may change over time. The approach described in this document based on one back-end driver per RDBMS is reasonable, but not the only approach – we simply felt that a simpler approach based on well-understood and self-contained tools (R, S, and C API’s) would be a better start. Nevertheless we want to briefly mention a few alternatives that we considered and tentatively decided against, but may quite possibly re-visit in the near future. ## Open Database Connectivity (ODBC) {#sec:odbc} The ODBC protocol was developed by Microsoft to allow connectivity among C/C++ applications and RDBMS. As you would expect, originally implementations of the ODBC were only available under Windows environments. There are various effort to create a Unix implementation (see [the Unix ODBC](http://www.unixodbc.org/) web-site and @odbc.lj). This approach looks promising because it allows us to write only one back-end, instead of one per RDBMS. Since most RDBMS already provide ODBC drivers, this could greatly simplify development. Unfortunately, the Unix implementation of ODBC was not mature enough at the time we looked at it, a situation we expect will change in the next year or so. At that point we will need to re-evaluate it to make sure that such an ODBC interface does not penalize the interface in terms of performance, ease of use, portability among the various Unix versions, etc. ## Java Database Connectivity (JDBC) {#sec:jdbc} Another protocol, the Java database connectivity, is very well-done and supported by just about every RDBMS. The issue with JDBC is that as of today neither S nor R (which are written in C) interfaces cleanly with Java. There are several efforts (some in a quite fairly advanced state) to allow S and R to invoke Java methods. Once this interface is widely available in Splus5x and R we will need to re-visit this issue again and study the performance, usability, etc., of JDBC as a common back-end to the RS-DBI. ## CORBA and a 3-tier Architecture {#sec:corba} Yet another approach is to move the interface to RDBMS out of R and S altogether into a separate system or server that would serve as a proxy between R/S and databases. The communication to this middle-layer proxy could be done through CORBA [@s-corba.98, @corba:siegel.96], Java’s RMI, or some other similar technology. Such a design could be very flexible, but the CORBA facilities both in R and S are not widely available yet, and we do not know whether this will be made available to Splus5 users from MathSoft. Also, my experience with this technology is rather limited. On the other hand, this 3-tier architecture seem to offer the most flexibility to cope with very large distributed databases, not necessarily relational. # Resources {#sec:resources} The latest documentation and software on the RS-DBI was available at www.omegahat.net (link dead now: `http://www.omegahat.net/contrib/RS-DBI/index.html`). The R community has developed interfaces to some databases: [RmSQL](https://cran.r-project.org/src/contrib/Archive/RmSQL/) is an interface to the [mSQL](http://www.Hughes.com.au) database written by Torsten Hothorn; [RPgSQL](http://www.nceas.ucsb.edu/~keitt/R) is an interface to [PostgreSQL](http://www.postgreSQL.org) and was written by Timothy H. Keitt; [RODBC](http://www.stats.ox.ac.uk/pub/bdr) is an interface to ODBC, and it was written by [Michael Lapsley](mailto:mlapsley@sthelier.sghms.ac.uk). (For more details on all these see @R.imp-exp.) The are R and S-Plus interfaces to [MySQL](http://www.mysql.org) that follow the propose RS-DBI API described here; also, there’s an S-Plus interface SOracle @RS-Oracle to [Oracle](http://www.oracle.com) (we expect to have an R implementation soon.) The idea of a common interface to databases has been successfully implemented in Java’s Database Connectivity (JDBC) ([www.javasoft.com](http://www.javasoft.com/products/jdbc/index.html)), in C through the Open Database Connectivity (ODBC) ([www.unixodbc.org](http://www.unixodbc.org/)), in Python’s Database Application Programming Interface ([www.python.org](http://www.python.org)), and in Perl’s Database Interface ([www.cpan.org](http://www.cpan.org)). # Acknowledgements The R/S database interface came about from suggestions, comments, and discussions with [John M. Chambers](mailto:jmc@research.bell-labs.com) and [Duncan Temple Lang](mailto:duncan@research.bell-labs.com) in the context of the Omega Project for Statistical Computing. [Doug Bates](mailto:bates@stat.wisc.edu) and [Saikat DebRoy](mailto:saikat@stat.wisc.edu) ported (and greatly improved) the first MySQL implementation to R. # The S Version 4 Definitions The following code is meant to serve as a detailed description of the R/S to database interface. We decided to use S4 (instead of R or S version 3) because its clean syntax help us to describe easily the classes and methods that form the RS-DBI, and also to convey the inter-class relationships. ```R ## Define all the classes and methods to be used by an ## implementation of the RS-DataBase Interface. Mostly, ## these classes are virtual and each driver should extend ## them to provide the actual implementation. ## Class: dbManager ## This class identifies the DataBase Management System ## (Oracle, MySQL, Informix, PostgreSQL, etc.) setClass("dbManager", VIRTUAL) setGeneric("load", def = function(dbMgr,...) standardGeneric("load") ) setGeneric("unload", def = function(dbMgr,...) standardGeneric("unload") ) setGeneric("getVersion", def = function(dbMgr,...) standardGeneric("getVersion") ) ## Class: dbConnections ## This class captures a connection to a database instance. setClass("dbConnection", VIRTUAL) setGeneric("dbConnection", def = function(dbMgr, ...) standardGeneric("dbConnection") ) setGeneric("dbConnect", def = function(dbMgr, ...) standardGeneric("dbConnect") ) setGeneric("dbExecStatement", def = function(con, statement, ...) standardGeneric("dbExecStatement") ) setGeneric("dbExec", def = function(con, statement, ...) standardGeneric("dbExec") ) setGeneric("getResultSet", def = function(con, ..) standardGeneric("getResultSet") ) setGeneric("commit", def = function(con, ...) standardGeneric("commit") ) setGeneric("rollback", def = function(con, ...) standardGeneric("rollback") ) setGeneric("callProc", def = function(con, ...) standardGeneric("callProc") ) setMethod("close", signature = list(con="dbConnection", type="missing"), def = function(con, type) NULL ) ## Class: dbResult ## This is a base class for arbitrary results from the RDBMS ## (INSERT, UPDATE, DELETE). SELECTs (and SELECT-like) ## statements produce "dbResultSet" objects, which extend ## dbResult. setClass("dbResult", VIRTUAL) setMethod("close", signature = list(con="dbResult", type="missing"), def = function(con, type) NULL ) ## Class: dbResultSet ## Note that we define a resultSet as the result of a ## SELECT SQL statement. setClass("dbResultSet", "dbResult") setGeneric("fetch", def = function(resultSet,n,...) standardGeneric("fetch") ) setGeneric("hasCompleted", def = function(object, ...) standardGeneric("hasCompleted") ) setGeneric("getException", def = function(object, ...) standardGeneric("getException") ) setGeneric("getDBconnection", def = function(object, ...) standardGeneric("getDBconnection") ) setGeneric("setDataMappings", def = function(resultSet, ...) standardGeneric("setDataMappings") ) setGeneric("getFields", def = function(object, table, dbname, ...) standardGeneric("getFields") ) setGeneric("getStatement", def = function(object, ...) standardGeneric("getStatement") ) setGeneric("getRowsAffected", def = function(object, ...) standardGeneric("getRowsAffected") ) setGeneric("getRowCount", def = function(object, ...) standardGeneric("getRowCount") ) setGeneric("getNullOk", def = function(object, ...) standardGeneric("getNullOk") ) ## Meta-data: setGeneric("getInfo", def = function(object, ...) standardGeneric("getInfo") ) setGeneric("describe", def = function(object, verbose=F, ...) standardGeneric("describe") ) setGeneric("getCurrentDatabase", def = function(object, ...) standardGeneric("getCurrentDatabase") ) setGeneric("getDatabases", def = function(object, ...) standardGeneric("getDatabases") ) setGeneric("getTables", def = function(object, dbname, ...) standardGeneric("getTables") ) setGeneric("getTableFields", def = function(object, table, dbname, ...) standardGeneric("getTableFields") ) setGeneric("getTableIndices", def = function(object, table, dbname, ...) standardGeneric("getTableIndices") ) ``` [^2]: A virtual class allows us to group classes that share some common functionality, e.g., the virtual class “`dbConnection`” groups all the connection implementations by Informix, Ingres, DB/2, Oracle, etc. Although the details will vary from one RDBMS to another, the defining characteristic of these objects is what a virtual class captures. R and S version 3 do not explicitly define virtual classes, but they can easily implement the idea through inheritance. [^3]: The term “database” is sometimes (confusingly) used both to denote the RDBMS, such as Oracle, MySQL, and also to denote a particular database instance under a RDBMS, such as “opto” or “sales” databases under the same RDBMS. DBI/vignettes/biblio.bib0000644000176200001440000001771513027447303014614 0ustar liggesusers@string{jcgs="Journal of Computational and Graphical Statistics"} @inproceedings{s-corba.98, author = "Chambers, John M. and Hansen, Mark H. and James, David A. and Temple Lang, Duncan", title = "Distributed Computing with Data: A CORBA-based Approach", booktitle = "Computing Science and Statistics", year = 1998, organization = "Inteface Foundation of North America" } @book{S.88, author = "Becker, R. A. and Chambers, J. M. and Wilks, A. R", year = "1988", title = "The New S Language", publisher = "Wadsworth", address = "Pacific Grove, California" } @book{S.92, editor = "Chambers, J. M. and Hastie, T.", year = 1992, title = "Statistical Models in S", publisher = "Wadsworth", address = "Pacific Grove, California" } @book{S4, author = "Chambers, J. M.", title = "Programming with Data: A Guide to the S Language", publisher = "Springer", address = "New York", year = 1998 } @article{R.96, author = "Ihaka, Ross and Gentleman, Robert", title = "R: A Language for Data Analysis and Graphics", journal = jcgs, volume = 5, number = 3, year = 1996, pages = "299-314" } @book{corba:siegel.96, author = "Siegel, Jon", title = "CORBA Fundamentals and Programming", publisher = "Wiley", address = "New York", year = 1996 } @book{pvm, title = "PVM: Parallel Virtual Machine. A User's Guide and Tutorial for Networked Parallel Computing", author="Geist, A. and Beguelin, A. and Dongarra, J. and Jiang, W. and Mancheck, R. and Sunderam, V.", year = 1994, publisher = "MIT Press", address = "Cambridge, MA" } @manual{splus, title = "S-PLUS Software Documentation", key = "S-PLUS", organization = "StatSci Division of MathSoft Inc.", note = "Version 3.3", year = 1995, address = "Seattle, WA", } @book{tierney.90, author = "Tierney, Luke", year = 1990, title = "LISP-STAT: An Object-Oriented Environment for Statistical Computing and Dynamic Graphics", publisher = "Wiley", address = "New York" } @article{tierney.96, author = "Tierney, Luke", title = "Recent Development and Future Directions in {LispStat}", journal = jcgs, volume = 5, number = 3, year = 1996, pages = "250-262" } @article{odbc.lj, author = "Harvey, Peter", title = "{Open Database Connectivity}", journal = "{Linux Journal}", year = 1999, volume = "Nov.", number = 67, pages = "68-72" } @article{duncan2000, author = "Temple Lang, Duncan", title = "{The Omegahat Environment: New Possibilities for Statistical Computing}", journal = jcgs, volume = "to appear", year = 2000, number = "" } @manual{sql92, title = "{X/Open CAE Specification: SQL and RDA}", organization = "X/Open Company Ltd.", address = "Reading, UK", year = 1994 } @book{MySQL, author = "DuBois, Paul", title = "{MySQL}", publisher = "New Riders Publishing", year = 2000 } @manual{R.ext, title = "Writing {R} Extensions", organization = "{R} Development Core Team", note = "Version 1.2.1 (2001-01-15)", year = 2001 } @manual{R.imp-exp, title = "{R} Data Import/Export", organization = "R-Development Core Team", note = "Version 1.2.1 (2001-01-15)", year = 2001 } @manual{R-dbms, title = "Using Relational Database Systems with {R}", organization = "R-Developemt Core Team", note = "Draft", year = 2000 } @manual{bates.mysql, title = "Using Relational Database Systems with {R}", organization = "R-Developemt Core Team", note = "Draft", year = 2000 } @techreport{proxyDBMS, author = "James, David A.", title = "Proxy Database Object in the S Language", institution = "Bell Labs, Lucent Technologies", year = "In preparation" } @techreport{RS-DBI, author = "James, David A.", title = "A Common Interface to Relational Database Management Sysmtems from {R} and {S} --- A Proposal", institution = "Bell Labs, Lucent Technologies", year = "2000", address = "www.omegahat.org" } @techreport{RS-MySQL, author = "James, David A.", title = "An {R}/{S} Interface to the {MySQL} Database", institution = "Bell Labs, Lucent Technologies", year = "2001", address = "www.omegahat.org" } @techreport{RS-Oracle, author = "James, David A.", title = "An {R}/{S} Interface to the {Oracle} Database", institution = "Bell Labs, Lucent Technologies", year = "In preparation", address = "www.omegahat.org" } @manual{r-data-imp:2001, author = {R Development Core Team}, title = {R Data Import/Export}, year = {2001}, address = {\url{http://www.r-project.org}} } @manual{mysql:2000, author = "Axmark, David and Widenius, Michael and Cole, Jeremy and DuBois, Paul", title = {MySQL Reference Manual}, year = {2001}, address = {\url{http://www.mysql.com/documentation/mysql}} } @manual{jdbc:2000, author = "Ellis, Jon and Ho, Linda and Fisher, Maydene", title = {JDBC 3.0 Specification}, organization = {Sun Microsystems, Inc}, year = {2000}, address = {\url{http://java.sun.com/Download4}} } @article{using-data:2001, author = "Ripley, Brian D.", title = {Using Databases with {R}}, journal = {R {N}ews}, year = {2001}, month = {January}, volume = {1}, number = {1}, pages = {18--20}, address = {\url{http://www.r-project.org/doc/Rnews/}} } @Manual{odbc:2001, title = {Microsoft {ODBC}}, organization = {Microsoft Inc}, address = {\url{http://www.microsoft.com/data/odbc/}}, year = 2001 } @Book{PerlDBI:2000, author = "Descartes, Alligator and Bunce, Tim", title = {Programming the {P}erl {DBI}}, publisher = {O'Reilly}, year = 2000 } @Book{Reese:2000, author = "Reese, George", title = {Database Programming with {JDBC} and {J}ava}, publisher = {O'Reilly}, year = 2000, edition = {second} } @book{Xopen-sql, author = {X/Open Company Ltd.}, title = {X/Open SQL and RDA Specification}, publisher = {X/Open Company Ltd.}, year = 1994 } @book{mysql-dubois, author = "DuBois, Paul", title = {MySQL}, publisher = {New Riders}, year = 2000 } @techreport{data-management:1991, author = "Chambers, John M.", title = {Data Management in {S}}, institution = {Bell Labs, Lucent Technologies}, year = 1991 } @techreport{database-classes:1999, author = "Chambers, John M.", title = {Database Classes}, institution = {Bell Labs, Lucent Technologies}, year = 1998 } @inproceedings{R-dcom, author = "Neuwirth, Erich and Baier, Thomas", title = {Embedding {R} in Standard Software, and the other way around}, organization = {Vienna University of Technology}, year = 2001, booktitle = {Proceedings of the Distributed Statistical Computing 2001 Workshop}, address = {\url{http://www.ci.tuwien.ac.at/Conferences/DSC-2001}} } @inproceedings{R-tcltk, author = "Dalgaard, Peter", title = {The {R}-{T}cl/{T}k Interface}, organization = {Vienna University of Technology}, year = 2001, booktitle = {Proceedings of the Distributed Statistical Computing 2001 Workshop}, address = {\url{http://www.ci.tuwien.ac.at/Conferences/DSC-2001}} } @inproceedings{duncan-dsc2001, author = "Temple Lang, Duncan", title = {Embedding {S} in Other Languages and Environments}, organization = {Vienna University of Technology}, year = 2001, booktitle = {Proceedings of the Distributed Statistical Computing 2001 Workshop}, address = {\url{http://www.ci.tuwien.ac.at/Conferences/DSC-2001}} } @inproceedings{BDR-RMR, author = "Ripley, B. D. and Ripley, R. M.", title = {Applications of {R} Clients and Servers}, organization = {Vienna University of Technology}, year = 2001, booktitle = {Proceedings of the Distributed Statistical Computing 2001 Workshop}, address = {\url{http://www.ci.tuwien.ac.at/Conferences/DSC-2001}} } @inproceedings{rsdbi-dsc2001, author = "Hothorn, Torsten and James, David A. and Ripley, Brian D.", title = {{R}/{S} Interfaces to Databases}, organization = {Vienna University of Technology}, year = 2001, booktitle = {Proceedings of the Distributed Statistical Computing 2001 Workshop}, address = {\url{http://www.ci.tuwien.ac.at/Conferences/DSC-2001}} } DBI/vignettes/backend.Rmd0000644000176200001440000002340513267404720014724 0ustar liggesusers --- title: "Implementing a new backend" author: "Hadley Wickham" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Implementing a new backend} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r, echo = FALSE} library(DBI) knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` The goal of this document is to help you implement a new backend for DBI. If you are writing a package that connects a database to R, I highly recommend that you make it DBI compatible because it makes your life easier by spelling out exactly what you need to do. The consistent interface provided by DBI makes it easier for you to implement the package (because you have fewer arbitrary choices to make), and easier for your users (because it follows a familiar pattern). In addition, the `DBItest` package provides test cases which you can easily incorporate in your package. I'll illustrate the process using a fictional database called Kazam. ## Getting started Start by creating a package. It's up to you what to call the package, but following the existing pattern of `RSQLite`, `RMySQL`, `RPostgres` and `ROracle` will make it easier for people to find it. For this example, I'll call my package `RKazam`. In your `DESCRIPTION`, make sure to include: ```yaml Imports: DBI (>= 0.3.0), methods Suggests: DBItest, testthat ``` Importing `DBI` is fine, because your users are not supposed to *attach* your package anyway; the preferred method is to attach `DBI` and use explicit qualification via `::` to access the driver in your package (which needs to be done only once). ## Testing Why testing at this early stage? Because testing should be an integral part of the software development cycle. Test right from the start, add automated tests as you go, finish faster (because tests are automated) while maintaining superb code quality (because tests also check corner cases that you might not be aware of). Don't worry: if some test cases are difficult or impossible to satisfy, or take too long to run, you can just turn them off. Take the time now to head over to the `DBItest` vignette. You will find a vast amount of ready-to-use test cases that will help you in the process of implementing your new DBI backend. ```r vignette("test", package = "DBItest") ``` Add custom tests that are not covered by `DBItest` at your discretion, or enhance `DBItest` and file a pull request if the test is generic enough to be useful for many DBI backends. ## Driver Start by making a driver class which inherits from `DBIDriver`. This class doesn't need to do anything, it's just used to dispatch other generics to the right method. Users don't need to know about this, so you can remove it from the default help listing with `@keywords internal`: ```{r} #' Driver for Kazam database. #' #' @keywords internal #' @export #' @import DBI #' @import methods setClass("KazamDriver", contains = "DBIDriver") ``` The driver class was more important in older versions of DBI, so you should also provide a dummy `dbUnloadDriver()` method. ```{r} #' @export #' @rdname Kazam-class setMethod("dbUnloadDriver", "KazamDriver", function(drv, ...) { TRUE }) ``` If your package needs global setup or tear down, do this in the `.onLoad()` and `.onUnload()` functions. You might also want to add a show method so the object prints nicely: ```{r} setMethod("show", "KazamDriver", function(object) { cat("\n") }) ``` Next create `Kazam()` which instantiates this class. ```{r} #' @export Kazam <- function() { new("KazamDriver") } Kazam() ``` ## Connection Next create a connection class that inherits from `DBIConnection`. This should store all the information needed to connect to the database. If you're talking to a C api, this will include a slot that holds an external pointer. ```{r} #' Kazam connection class. #' #' @export #' @keywords internal setClass("KazamConnection", contains = "DBIConnection", slots = list( host = "character", username = "character", # and so on ptr = "externalptr" ) ) ``` Now you have some of the boilerplate out of the way, you can start work on the connection. The most important method here is `dbConnect()` which allows you to connect to a specified instance of the database. Note the use of `@rdname Kazam`. This ensures that `Kazam()` and the connect method are documented together. ```{r} #' @param drv An object created by \code{Kazam()} #' @rdname Kazam #' @export #' @examples #' \dontrun{ #' db <- dbConnect(RKazam::Kazam()) #' dbWriteTable(db, "mtcars", mtcars) #' dbGetQuery(db, "SELECT * FROM mtcars WHERE cyl == 4") #' } setMethod("dbConnect", "KazamDriver", function(drv, ...) { # ... new("KazamConnection", host = host, ...) }) ``` * Replace `...` with the arguments needed to connect to your database. You'll always need to include `...` in the arguments, even if you don't use it, for compatibility with the generic. * This is likely to be where people first come for help, so the examples should show how to connect to the database, and how to query it. (Obviously these examples won't work yet.) Ideally, include examples that can be run right away (perhaps relying on a publicly hosted database), but failing that surround in `\dontrun{}` so people can at least see the code. Next, implement `show()` and `dbDisconnect()` methods. ## Results Finally, you're ready to implement the meat of the system: fetching results of a query into a data frame. First define a results class: ```{r} #' Kazam results class. #' #' @keywords internal #' @export setClass("KazamResult", contains = "DBIResult", slots = list(ptr = "externalptr") ) ``` Then write a `dbSendQuery()` method. This takes a connection and SQL string as arguments, and returns a result object. Again `...` is needed for compatibility with the generic, but you can add other arguments if you need them. ```{r} #' Send a query to Kazam. #' #' @export #' @examples #' # This is another good place to put examples setMethod("dbSendQuery", "KazamConnection", function(conn, statement, ...) { # some code new("KazamResult", ...) }) ``` Next, implement `dbClearResult()`, which should close the result set and free all resources associated with it: ```{r} #' @export setMethod("dbClearResult", "KazamResult", function(res, ...) { # free resources TRUE }) ``` The hardest part of every DBI package is writing the `dbFetch()` method. This needs to take a result set and (optionally) number of records to return, and create a dataframe. Mapping R's data types to those of your database may require a custom implementation of the `dbDataType()` method for your connection class: ```{r} #' Retrieve records from Kazam query #' @export setMethod("dbFetch", "KazamResult", function(res, n = -1, ...) { ... }) # (optionally) #' Find the database data type associated with an R object #' @export setMethod("dbDataType", "KazamConnection", function(dbObj, obj, ...) { ... }) ``` Next, implement `dbHasCompleted()` which should return a `logical` indicating if there are any rows remaining to be fetched. ```{r} #' @export setMethod("dbHasCompleted", "KazamResult", function(res, ...) { }) ``` With these four methods in place, you can now use the default `dbGetQuery()` to send a query to the database, retrieve results if available and then clean up. Spend some time now making sure this works with an existing database, or relax and let the `DBItest` package do the work for you. ## SQL methods You're now on the home stretch, and can make your wrapper substantially more useful by implementing methods that wrap around variations in SQL across databases: * `dbQuoteString()` and `dbQuoteIdentifer()` are used to safely quote strings and identifiers to avoid SQL injection attacks. Note that the former must be vectorized, but not the latter. * `dbWriteTable()` creates a database table given an R dataframe. I'd recommend using the functions prefixed with `sql` in this package to generate the SQL. These functions are still a work in progress so please let me know if you have problems. * `dbReadTable()`: a simple wrapper around `SELECT * FROM table`. Use `dbQuoteIdentifer()` to safely quote the table name and prevent mismatches between the names allowed by R and the database. * `dbListTables()` and `dbExistsTable()` let you determine what tables are available. If not provided by your database's API, you may need to generate sql that inspects the system tables. * `dbListFields()` shows which fields are available in a given table. * `dbRemoveTable()` wraps around `DROP TABLE`. Start with `SQL::sqlTableDrop()`. * `dbBegin()`, `dbCommit()` and `dbRollback()`: implement these three functions to provide basic transaction support. This functionality is currently not tested in the `DBItest` package. ## Metadata methods There are a lot of extra metadata methods for result sets (and one for the connection) that you might want to implement. They are described in the following. * `dbIsValid()` returns if a connection or a result set is open (`TRUE`) or closed (`FALSE`). All further methods in this section are valid for result sets only. * `dbGetStatement()` returns the issued query as a character value. * `dbColumnInfo()` lists the names and types of the result set's columns. * `dbGetRowCount()` and `dbGetRowsAffected()` returns the number of rows returned or altered in a `SELECT` or `INSERT`/`UPDATE` query, respectively. * `dbBind()` allows using parametrised queries. Take a look at `sqlInterpolate()` and `sqlParseVariables()` if your SQL engine doesn't offer native parametrised queries. ## Full DBI compliance By now, your package should implement all methods defined in the DBI specification. If you want to walk the extra mile, offer a read-only mode that allows your users to be sure that their valuable data doesn't get destroyed inadvertently. DBI/vignettes/spec.Rmd0000644000176200001440000001173413575266047014303 0ustar liggesusers--- title: "DBI specification" author: "Kirill Müller" output: rmarkdown::html_vignette abstract: > The DBI package defines the generic DataBase Interface for R. The connection to individual DBMS is provided by other packages that import DBI (so-called *DBI backends*). This document formalizes the behavior expected by the methods declared in DBI and implemented by the individual backends. To ensure maximum portability and exchangeability, and to reduce the effort for implementing a new DBI backend, the DBItest package defines a comprehensive set of test cases that test conformance to the DBI specification. This document is derived from comments in the test definitions of the DBItest package. Any extensions or updates to the tests will be reflected in this document. vignette: > %\VignetteIndexEntry{DBI specification} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r echo = FALSE} library(magrittr) library(xml2) knitr::opts_chunk$set(echo = FALSE) r <- rprojroot::is_r_package$make_fix_file() ``` ```{r error=TRUE} rd_db <- tools::Rd_db(dir = r()) Links <- tools::findHTMLlinks() html_topic <- function(name) { rd <- rd_db[[paste0(name, ".Rd")]] conn <- textConnection(NULL, "w") on.exit(close(conn)) #tools::Rd2HTML(rd, conn, Links = Links) tools::Rd2HTML(rd, conn) textConnectionValue(conn) } xml_topic <- function(name, patcher) { html <- html_topic(name) x <- read_html(paste(html, collapse = "\n")) # No idea why this is necessary when embedding HTML in Markdown codes <- x %>% xml_find_all("//code[contains(., '$')]") xml_text(codes) <- gsub("[$]", "\\\\$", xml_text(codes)) xx <- x %>% xml_find_first("/html/body") xx %>% xml_find_first("//table") %>% xml_remove() xx %>% xml_find_all("//pre") %>% xml_set_attr("class", "r") patcher(xx) } out_topic <- function(name, patcher = identity) { xml <- lapply(name, xml_topic, patcher = patcher) sapply(xml, as.character) %>% paste(collapse = "\n") } patch_package_doc <- function(x) { x %>% xml_find_first("//h3") %>% xml_remove remove_see_also_section(x) remove_authors_section(x) x } move_contents_of_usage_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 usage_contents <- x %>% xml_find_all( "//h3[.='Usage']/following-sibling::node() [not(self::h3)] [count(preceding-sibling::h3)=2]") usage_text <- usage_contents %>% xml_find_first("//pre") %>% xml_text h3 <- x %>% xml_find_first("//h3") intro_text <- read_xml( paste0( "

This section describes the behavior of the following method", if (length(grep("[(]", strsplit(usage_text, "\n")[[1]])) > 1) "s" else "", ":

") ) xml_add_sibling( h3, intro_text, .where = "before") lapply(usage_contents, xml_add_sibling, .x = h3, .copy = FALSE, .where = "before") x %>% xml_find_first("//h3[.='Usage']") %>% xml_remove x } move_additional_arguments_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error additional_arguments <- x %>% xml_find_all( "//h3[.='Additional arguments'] | //h3[.='Additional arguments']/following-sibling::node()[following-sibling::h3]") after_arg <- x %>% xml_find_first("//h3[text()='Arguments']/following-sibling::h3") lapply(additional_arguments, xml_add_sibling, .x = after_arg, .copy = FALSE, .where = "before") x } remove_see_also_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='See Also'] | //h3[.='See Also']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } remove_authors_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='Author(s)'] | //h3[.='Author(s)']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } patch_method_doc <- function(x) { move_contents_of_usage_section(x) remove_see_also_section(x) move_additional_arguments_section(x) x } topics <- c( "dbDataType", "dbConnect", "dbDisconnect", "dbSendQuery", "dbFetch", "dbClearResult", "dbBind", "dbGetQuery", "dbSendStatement", "dbExecute", "dbQuoteString", "dbQuoteIdentifier", "dbReadTable", "dbWriteTable", "dbListTables", "dbExistsTable", "dbRemoveTable", "dbListFields", "dbIsValid", "dbHasCompleted", "dbGetStatement", "dbGetRowCount", "dbGetRowsAffected", "dbColumnInfo", "transactions", "dbWithTransaction" ) html <- c( out_topic("DBI-package", patch_package_doc), out_topic(topics, patch_method_doc) ) temp_html <- tempfile(fileext = ".html") temp_md <- tempfile(fileext = ".md") #temp_html <- "out.html" #temp_md <- "out.md" #html <- '
\na\nb\n
' writeLines(html, temp_html) rmarkdown::pandoc_convert(temp_html, "gfm", verbose = FALSE, output = temp_md) knitr::asis_output(paste(readLines(temp_md), collapse = "\n")) ``` DBI/vignettes/DBI-history.Rmd0000644000176200001440000001221413575266047015440 0ustar liggesusers--- title: "History of DBI" author: "David James" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{"History of DBI"} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The following history of DBI was contributed by David James, the driving force behind the development of DBI, and many of the packages that implement it. The idea/work of interfacing S (originally S3 and S4) to RDBMS goes back to the mid- and late 1990's in Bell Labs. The first toy interface I did was to implement John Chamber's early concept of "Data Management in S" (1991). The implementation followed that interface pretty closely and immediately showed some of the limitations when dealing with very large databases; if my memory serves me, the issue was the instance-based of the language back then, e.g., if you attached an RDBMS to the `search()` path and then needed to resolve a symbol "foo", you effectively had to bring all the objects in the database to check their mode/class, i.e., the instance object had the metadata in itself as attributes. The experiment showed that the S3 implementation of "data management" was not really suitable to large external RDBMS (probably it was never intended to do that anyway). (Note however, that since then, John and Duncan Temple Lang generalized the data management in S4 a lot, including Duncan's implementation in his RObjectTables package where he considered a lot of synchronization/caching issues relevant to DBI and, more generally, to most external interfaces). Back then we were working very closely with Lucent's microelectronics manufacturing --- our colleagues there had huge Oracle (mostly) databases that we needed to constantly query via [SQL*Plus](http://en.wikipedia.org/wiki/SQL*Plus). My colleague Jake Luciani was developing advanced applications in C and SQL, and the two of us came up with the first implementation of S3 directly connecting with Oracle. What I remember is that the Linux [PRO*C](http://en.wikipedia.org/wiki/Pro*C) pre-compiler (that embedded SQL in C code) was very buggy --- we spent a lot of time looking for workarounds and tricks until we got the C interface running. At the time, other projects within Bell Labs began using MySQL, and we moved to MySQL (with the help of Doug Bates' student Saikat DebRoy, then a summer intern) with no intentions of looking back at the very difficult Oracle interface. It was at this time that I moved all the code from S3 methods to S4 classes and methods and begun reaching out to the S/R community for suggestions, ideas, etc. All (most) of this work was on Bell Labs versions of S3 and S4, but I made sure it worked with S-Plus. At some point around 2000 (I don't remember exactly when), I ported all the code to R regressing to S3 methods, and later on (once S4 classes and methods were available in R) I re-implemented everything back to S4 classes and methods in R (a painful back-and-forth). It was at this point that I decided to drop S-Plus altogether. Around that time, I came across a very early implementation of SQLite and I was quite interested and thought it was a very nice RDBMS that could be used for all kinds of experimentation, etc., so it was pretty easy to implement on top of the DBI. Within the R community, there were quite a number of people that showed interest on defining a common interface to databases, but only a few folks actually provided code/suggestions/etc. (Tim Keitt was most active with the dbi/PostgreSQL packages --- he also was considering what he called "proxy" objects, which was reminiscent of what Duncan had been doing). Kurt Hornick, Vincent Carey, Robert Gentleman, and others provided suggestions/comments/support for the DBI definition. By around 2003, the DBI was more or less implemented as it is today. I'm sure I'll forget some (most should be in the THANKS sections of the various packages), but the names that come to my mind at this moment are Jake Luciani (ROracle), Don MacQueen and other early ROracle users (super helpful), Doug Bates and his student Saikat DebRoy for RMySQL, Fei Chen (at the time a student of Prof. Ripley) also contributed to RMySQL, Tim Keitt (working on an early S3 interface to PostgrSQL), Torsten Hothorn (worked with mSQL and also MySQL), Prof. Ripley working/extending the RODBC package, in addition to John Chambers and Duncan Temple-Lang who provided very important comments and suggestions. Actually, the real impetus behind the DBI was always to do distributed statistical computing --- *not* to provide a yet-another import/export mechanism --- and this perspective was driven by John and Duncan's vision and work on inter-system computing, COM, CORBA, etc. I'm not sure many of us really appreciated (even now) the full extent of those ideas and concepts. Just like in other languages (C's ODBC, Java's JDBC, Perl's DBI/DBD, Python dbapi), R/S DBI was meant to unify the interfacing to RDBMS so that R/S applications could be developed on top of the DBI and not be hard coded to any one relation database. The interface I tried to follow the closest was the Python's DBAPI --- I haven't worked on this topic for a while, but I still feel Python's DBAPI is the cleanest and most relevant for the S language. DBI/vignettes/DBI.Rmd0000644000176200001440000001005113575266047013736 0ustar liggesusers--- title: "Introduction to DBI" author: "Katharina Brunner" date: "14 October 2019" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{"Introduction to DBI"} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` The {DBI} package defines a common interface between the R and database management systems (DBMS). Hence the name: DBI stands for **d**ata**b**ase **i**nterface. Using DBI, developers can focus on the functionalities of their code, instead of setting up the infrastructure depending on the underlying database. This DBMS-agnostic approach is possible, because DBI works best with several other packages that act as drivers to absorb the peculiarities of the specific DBMSs. These packages import {DBI} and implement its methods depending on the specific database management system. Currently, DBI works with the [many different database management systems](https://github.com/r-dbi/DBI/issues/274), e.g.: * MySQL, using the R-package [RMySQL](https://github.com/r-dbi/RMySQL) * MariaDB, using the R-package [RMariaDB](https://github.com/r-dbi/RMariaDB) * Postgres, using and the R-package [RPostgres](https://github.com/r-dbi/RPostgres) * SQLite, using and the R-package [RSQLite](https://github.com/r-dbi/RSQLite) DBI offers a set of classes and methods that define what operations are possible and how they are performed: * connect/disconnect to the DBMS * create and execute statements in the DBMS * extract results/output from statements * error/exception handling * information (meta-data) from database objects * transaction management (optional) ## Examples To showcase DBI capabilities, we create a in-memory RSQLite database ```{r} library(DBI) con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:") con ``` The function `dbListTables()` displays the names tables in the remote database. Since we haven't pushed any data to the database, there are no tables to show. ```{r} dbListTables(con) ``` We can write the famous data `mtcars` dataset to the remote database by using `dbWriteTable()`. Calling `dbListTables()` displays the table name: ```{r} dbWriteTable(con, "mtcars", mtcars) dbListTables(con) ``` To get all columns names of a remote table, use `dbListFields()`. It returns a character vector with all column names in the same order as in the database: ```{r} dbListFields(con, "mtcars") ``` If you want to import database table from the DBMS as a data frame, `dbReadTable()` helps to do that. Basically, it is the result of the most generic SQL call `SELECT * FROM `. ```{r} dbReadTable(con, "mtcars") ``` Of course, you can run more specific SQL queries, too. `dbGetQuery()` is the function to send a query to a database and retrieve the result as a data frame. Especially when working with large datasets, it is important to free the resources associated with retrieving the result. `dbGetQuery()` cares about this, too. ```{r} df <- dbGetQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df ``` Behind the scences, `dbGetQuery()` is a combination of `dbSendQuery()`, `dbFetch()` and `dbClearResult()`. The following snippet leads to the same result as `dbGetQuery()` above: ```{r} res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df <- dbFetch(res) dbClearResult(res) df ``` When working with large datasets it might be smart to fetch the result step by step, not in one big chunk. This can be implemented with a `while` loop and a `dbFetch()` call that defines a maximum number of records to retrieve per fetch, here `n = 5`. There are eleven cars with four cylinders, so we expect two chunks of five rows and one chuck of one row: ```{r} res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") while(!dbHasCompleted(res)){ chunk <- dbFetch(res, n = 5) print(nrow(chunk)) } ``` Again, call `dbClearResult()` and disconnect from the connection with `dbDisconnect()`, when you are done: ```{r} dbClearResult(res) dbDisconnect(con) ``` ## Further Reading * An overview on [working with databases in R on Rstudio.com](https://db.rstudio.com/) DBI/R/0000755000176200001440000000000013575266242011065 5ustar liggesusersDBI/R/table-insert.R0000644000176200001440000001176113575062550013603 0ustar liggesusers#' @include hidden.R NULL #' Compose query to insert rows into a table #' #' `sqlAppendTable()` generates a single SQL string that inserts a #' data frame into an existing table. `sqlAppendTableTemplate()` generates #' a template suitable for use with [dbBind()]. #' The default methods are ANSI SQL 99 compliant. #' These methods are mostly useful for backend implementers. #' #' The `row.names` argument must be passed explicitly in order to avoid #' a compatibility warning. The default will be changed in a later release. #' #' @inheritParams sqlCreateTable #' @inheritParams rownames #' @param values A data frame. Factors will be converted to character vectors. #' Character vectors will be escaped with [dbQuoteString()]. #' @family SQL generation #' @export #' @examples #' sqlAppendTable(ANSI(), "iris", head(iris)) #' #' sqlAppendTable(ANSI(), "mtcars", head(mtcars)) #' sqlAppendTable(ANSI(), "mtcars", head(mtcars), row.names = FALSE) setGeneric("sqlAppendTable", def = function(con, table, values, row.names = NA, ...) standardGeneric("sqlAppendTable") ) #' @rdname hidden_aliases #' @export setMethod("sqlAppendTable", signature("DBIConnection"), function(con, table, values, row.names = NA, ...) { stopifnot(is.list(values)) if (missing(row.names)) { warning("Do not rely on the default value of the row.names argument for sqlAppendTable(), it will change in the future.", call. = FALSE ) } sql_values <- sqlData(con, values, row.names) table <- dbQuoteIdentifier(con, table) fields <- dbQuoteIdentifier(con, names(sql_values)) # Convert fields into a character matrix rows <- do.call(paste, c(sql_values, sep = ", ")) SQL(paste0( "INSERT INTO ", table, "\n", " (", paste(fields, collapse = ", "), ")\n", "VALUES\n", paste0(" (", rows, ")", collapse = ",\n") )) } ) #' @rdname sqlAppendTable #' @inheritParams sqlCreateTable #' @inheritParams rownames #' @param prefix Parameter prefix to use for placeholders. #' @param pattern Parameter pattern to use for placeholders: #' - `""`: no pattern #' - `"1"`: position #' - anything else: field name #' @export #' @examples #' sqlAppendTableTemplate(ANSI(), "iris", iris) #' #' sqlAppendTableTemplate(ANSI(), "mtcars", mtcars) #' sqlAppendTableTemplate(ANSI(), "mtcars", mtcars, row.names = FALSE) sqlAppendTableTemplate <- function(con, table, values, row.names = NA, prefix = "?", ..., pattern = "") { if (missing(row.names)) { warning("Do not rely on the default value of the row.names argument for sqlAppendTableTemplate(), it will change in the future.", call. = FALSE ) } table <- dbQuoteIdentifier(con, table) values <- sqlRownamesToColumn(values[0, , drop = FALSE], row.names) fields <- dbQuoteIdentifier(con, names(values)) if (pattern == "") { suffix <- rep("", length(fields)) } else if (pattern == "1") { suffix <- as.character(seq_along(fields)) } else { suffix <- names(fields) } placeholders <- lapply(paste0(prefix, suffix), SQL) names(placeholders) <- names(values) sqlAppendTable( con = con, table = table, values = placeholders, row.names = row.names ) } #' Insert rows into a table #' #' The `dbAppendTable()` method assumes that the table has been created #' beforehand, e.g. with [dbCreateTable()]. #' The default implementation calls [sqlAppendTableTemplate()] and then #' [dbExecute()] with the `param` argument. Backends compliant to #' ANSI SQL 99 which use `?` as a placeholder for prepard queries don't need #' to override it. Backends with a different SQL syntax which use `?` #' as a placeholder for prepared queries can override [sqlAppendTable()]. #' Other backends (with different placeholders or with entirely different #' ways to create tables) need to override the `dbAppendTable()` method. #' #' The `row.names` argument is not supported by this method. #' Process the values with [sqlRownamesToColumn()] before calling this method. #' #' @param name Name of the table, escaped with [dbQuoteIdentifier()]. #' @param value A data frame of values. The column names must be consistent #' with those in the target table in the database. #' @param row.names Must be `NULL`. #' @inheritParams sqlAppendTableTemplate #' @inheritParams dbDisconnect #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' dbCreateTable(con, "iris", iris) #' dbAppendTable(con, "iris", iris) #' dbReadTable(con, "iris") #' dbDisconnect(con) setGeneric("dbAppendTable", def = function(conn, name, value, ..., row.names = NULL) standardGeneric("dbAppendTable") ) #' @rdname hidden_aliases #' @export setMethod("dbAppendTable", signature("DBIConnection"), function(conn, name, value, ..., row.names = NULL) { stopifnot(is.null(row.names)) query <- sqlAppendTableTemplate( con = conn, table = name, values = value, row.names = row.names, prefix = "?", pattern = "", ... ) dbExecute(conn, query, params = unname(as.list(value))) } ) DBI/R/rd.R0000644000176200001440000000201313550652132011577 0ustar liggesusersmethods_as_rd <- function(method) { if (method == "transactions") { method <- c("dbBegin", "dbCommit", "dbRollback") } methods <- unlist(lapply(method, methods::findMethods), recursive = FALSE) # Extracted from roxygen2::object_topic.s4method s4_topic <- function(x) { sig <- paste0(x@defined, collapse = ",") sig_text <- paste0('"', x@defined, '"', collapse = ", ") package <- tryCatch( getNamespaceName(environment(x@.Data)), error = function(e) NA ) if (is.na(package) || package == "DBI") { NA_character_ } else { paste0( "\\code{\\link[=", x@generic, ",", sig, "-method]{", package, "::", x@generic, "(", sig_text, ")}}" ) } } item_text <- vapply(methods@.Data, s4_topic, character(1)) item_text <- item_text[!is.na(item_text)] if (length(item_text) == 0) return("") paste0( "\\subsection{Methods in other packages}{\n\n", "\\itemize{\n", paste0("\\item ", item_text, "\n", collapse = ""), "}}\n" ) } DBI/R/transactions.R0000644000176200001440000001331313575100377013715 0ustar liggesusers#' @include hidden.R NULL #' Begin/commit/rollback SQL transactions #' #' A transaction encapsulates several SQL statements in an atomic unit. #' It is initiated with `dbBegin()` and either made persistent with `dbCommit()` #' or undone with `dbRollback()`. #' In any case, the DBMS guarantees that either all or none of the statements #' have a permanent effect. #' This helps ensuring consistency of write operations to multiple tables. #' #' Not all database engines implement transaction management, in which case #' these methods should not be implemented for the specific #' [DBIConnection-class] subclass. #' #' @template methods #' @templateVar method_name transactions #' #' @inherit DBItest::spec_transaction_begin_commit_rollback return #' @inheritSection DBItest::spec_transaction_begin_commit_rollback Specification #' #' @inheritParams dbGetQuery #' @seealso Self-contained transactions: [dbWithTransaction()] #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "cash", data.frame(amount = 100)) #' dbWriteTable(con, "account", data.frame(amount = 2000)) #' #' # All operations are carried out as logical unit: #' dbBegin(con) #' withdrawal <- 300 #' dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) #' dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) #' dbCommit(con) #' #' dbReadTable(con, "cash") #' dbReadTable(con, "account") #' #' # Rolling back after detecting negative value on account: #' dbBegin(con) #' withdrawal <- 5000 #' dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) #' dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) #' if (dbReadTable(con, "account")$amount >= 0) { #' dbCommit(con) #' } else { #' dbRollback(con) #' } #' #' dbReadTable(con, "cash") #' dbReadTable(con, "account") #' #' dbDisconnect(con) #' @name transactions NULL #' @export #' @rdname transactions setGeneric("dbBegin", def = function(conn, ...) standardGeneric("dbBegin") ) #' @export #' @rdname transactions setGeneric("dbCommit", def = function(conn, ...) standardGeneric("dbCommit") ) #' @export #' @rdname transactions setGeneric("dbRollback", def = function(conn, ...) standardGeneric("dbRollback") ) #' Self-contained SQL transactions #' #' Given that \link{transactions} are implemented, this function #' allows you to pass in code that is run in a transaction. #' The default method of `dbWithTransaction()` calls [dbBegin()] #' before executing the code, #' and [dbCommit()] after successful completion, #' or [dbRollback()] in case of an error. #' The advantage is #' that you don't have to remember to do `dbBegin()` and `dbCommit()` or #' `dbRollback()` -- that is all taken care of. #' The special function `dbBreak()` allows an early exit with rollback, #' it can be called only inside `dbWithTransaction()`. #' #' DBI implements `dbWithTransaction()`, backends should need to override this #' generic only if they implement specialized handling. #' #' @template methods #' @templateVar method_name dbWithTransaction #' #' @inherit DBItest::spec_transaction_with_transaction return #' @inheritSection DBItest::spec_transaction_with_transaction Specification #' #' @inheritParams dbGetQuery #' @param code An arbitrary block of R code. #' #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "cash", data.frame(amount = 100)) #' dbWriteTable(con, "account", data.frame(amount = 2000)) #' #' # All operations are carried out as logical unit: #' dbWithTransaction( #' con, #' { #' withdrawal <- 300 #' dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) #' dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) #' } #' ) #' #' # The code is executed as if in the curent environment: #' withdrawal #' #' # The changes are committed to the database after successful execution: #' dbReadTable(con, "cash") #' dbReadTable(con, "account") #' #' # Rolling back with dbBreak(): #' dbWithTransaction( #' con, #' { #' withdrawal <- 5000 #' dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) #' dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) #' if (dbReadTable(con, "account")$amount < 0) { #' dbBreak() #' } #' } #' ) #' #' # These changes were not committed to the database: #' dbReadTable(con, "cash") #' dbReadTable(con, "account") #' #' dbDisconnect(con) setGeneric("dbWithTransaction", def = function(conn, code, ...) standardGeneric("dbWithTransaction") ) #' @rdname hidden_aliases #' @export setMethod("dbWithTransaction", signature("DBIConnection"), function(conn, code) { ## needs to be a closure, because it accesses conn rollback_because <- function(e) { call <- dbRollback(conn) if (identical(call, FALSE)) { stop( paste( "Failed to rollback transaction.", "Tried to roll back because an error", "occurred:", conditionMessage(e) ), call. = FALSE ) } if (inherits(e, "error")) { stop(e) } } ## check if each operation is successful call <- dbBegin(conn) if (identical(call, FALSE)) { stop("Failed to begin transaction", call. = FALSE) } tryCatch( { res <- force(code) call <- dbCommit(conn) if (identical(call, FALSE)) { stop("Failed to commit transaction", call. = FALSE) } res }, dbi_abort = rollback_because, error = rollback_because ) }) #' @export #' @rdname dbWithTransaction dbBreak <- function() { signalCondition( structure( list(message = "Aborting DBI processing", call = NULL), class = c("dbi_abort", "condition") ) ) stop("Invalid usage of dbBreak().", call. = FALSE) } DBI/R/rownames.R0000644000176200001440000000526413550652132013040 0ustar liggesusers#' Convert row names back and forth between columns #' #' These functions provide a reasonably automatic way of preserving the row #' names of data frame during back-and-forth translation to an SQL table. #' By default, row names will be converted to an explicit column #' called "row_names", and any query returning a column called "row_names" #' will have those automatically set as row names. #' These methods are mostly useful for backend implementers. #' #' @param df A data frame #' @param row.names Either `TRUE`, `FALSE`, `NA` or a string. #' #' If `TRUE`, always translate row names to a column called "row_names". #' If `FALSE`, never translate row names. If `NA`, translate #' rownames only if they're a character vector. #' #' A string is equivalent to `TRUE`, but allows you to override the #' default name. #' #' For backward compatibility, `NULL` is equivalent to `FALSE`. #' @name rownames #' @examples #' # If have row names #' sqlRownamesToColumn(head(mtcars)) #' sqlRownamesToColumn(head(mtcars), FALSE) #' sqlRownamesToColumn(head(mtcars), "ROWNAMES") #' #' # If don't have #' sqlRownamesToColumn(head(iris)) #' sqlRownamesToColumn(head(iris), TRUE) #' sqlRownamesToColumn(head(iris), "ROWNAMES") #' NULL #' @export #' @rdname rownames sqlRownamesToColumn <- function(df, row.names = NA) { name <- guessRowName(df, row.names) if (is.null(name)) { rownames(df) <- NULL return(df) } rn <- stats::setNames(list(row.names(df)), name) df <- c(rn, df) class(df) <- "data.frame" attr(df, "row.names") <- .set_row_names(length(rn[[1]])) df } #' @export #' @rdname rownames sqlColumnToRownames <- function(df, row.names = NA) { name <- guessColName(df, row.names) if (is.null(name)) return(df) if (!(name %in% names(df))) { stop("Column ", name, " not present in output", call. = FALSE) } row.names(df) <- df[[name]] df[[name]] <- NULL df } guessRowName <- function(df, row.names) { if (identical(row.names, TRUE)) { "row_names" } else if (identical(row.names, FALSE) || is.null(row.names)) { NULL } else if (identical(row.names, NA)) { is_char <- is.character(attr(df, "row.names")) if (is_char) { "row_names" } else { NULL } } else if (is.character(row.names)) { row.names[1] } else { stop("Unknown input") } } guessColName <- function(df, row.names) { if (identical(row.names, TRUE)) { "row_names" } else if (identical(row.names, FALSE) || is.null(row.names)) { NULL } else if (identical(row.names, NA)) { if ("row_names" %in% names(df)) { "row_names" } else { NULL } } else if (is.character(row.names)) { row.names[1] } else { stop("Unknown input") } } DBI/R/table-create.R0000644000176200001440000000753413550653013013536 0ustar liggesusers#' @include hidden.R NULL #' Compose query to create a simple table #' #' Exposes an interface to simple `CREATE TABLE` commands. The default #' method is ANSI SQL 99 compliant. #' This method is mostly useful for backend implementers. #' #' The `row.names` argument must be passed explicitly in order to avoid #' a compatibility warning. The default will be changed in a later release. #' #' @param con A database connection. #' @param table Name of the table. Escaped with #' [dbQuoteIdentifier()]. #' @param fields Either a character vector or a data frame. #' #' A named character vector: Names are column names, values are types. #' Names are escaped with [dbQuoteIdentifier()]. #' Field types are unescaped. #' #' A data frame: field types are generated using #' [dbDataType()]. #' @param temporary If `TRUE`, will generate a temporary table statement. #' @inheritParams rownames #' @param ... Other arguments used by individual methods. #' @export #' @examples #' sqlCreateTable(ANSI(), "my-table", c(a = "integer", b = "text")) #' sqlCreateTable(ANSI(), "my-table", iris) #' #' # By default, character row names are converted to a row_names colum #' sqlCreateTable(ANSI(), "mtcars", mtcars[, 1:5]) #' sqlCreateTable(ANSI(), "mtcars", mtcars[, 1:5], row.names = FALSE) setGeneric("sqlCreateTable", def = function(con, table, fields, row.names = NA, temporary = FALSE, ...) standardGeneric("sqlCreateTable") ) #' @rdname hidden_aliases #' @export setMethod("sqlCreateTable", signature("DBIConnection"), function(con, table, fields, row.names = NA, temporary = FALSE, ...) { if (missing(row.names)) { warning("Do not rely on the default value of the row.names argument for sqlCreateTable(), it will change in the future.", call. = FALSE ) } table <- dbQuoteIdentifier(con, table) if (is.data.frame(fields)) { fields <- sqlRownamesToColumn(fields, row.names) fields <- vapply(fields, function(x) DBI::dbDataType(con, x), character(1)) } field_names <- dbQuoteIdentifier(con, names(fields)) field_types <- unname(fields) fields <- paste0(field_names, " ", field_types) SQL(paste0( "CREATE ", if (temporary) "TEMPORARY ", "TABLE ", table, " (\n", " ", paste(fields, collapse = ",\n "), "\n)\n" )) } ) #' Create a table in the database #' #' The default `dbCreateTable()` method calls [sqlCreateTable()] and #' [dbExecute()]. #' Backends compliant to ANSI SQL 99 don't need to override it. #' Backends with a different SQL syntax can override `sqlCreateTable()`, #' backends with entirely different ways to create tables need to #' override this method. #' #' The `row.names` argument is not supported by this method. #' Process the values with [sqlRownamesToColumn()] before calling this method. #' #' The argument order is different from the `sqlCreateTable()` method, the #' latter will be adapted in a later release of DBI. #' #' @param name Name of the table, escaped with [dbQuoteIdentifier()]. #' @param row.names Must be `NULL`. #' @inheritParams sqlCreateTable #' @inheritParams dbDisconnect #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' dbCreateTable(con, "iris", iris) #' dbReadTable(con, "iris") #' dbDisconnect(con) setGeneric("dbCreateTable", def = function(conn, name, fields, ..., row.names = NULL, temporary = FALSE) standardGeneric("dbCreateTable") ) #' @rdname hidden_aliases #' @export setMethod("dbCreateTable", signature("DBIConnection"), function(conn, name, fields, ..., row.names = NULL, temporary = FALSE) { stopifnot(is.null(row.names)) stopifnot(is.logical(temporary), length(temporary) == 1L) query <- sqlCreateTable( con = conn, table = name, fields = fields, row.names = row.names, temporary = temporary, ... ) dbExecute(conn, query) invisible(TRUE) } ) DBI/R/interpolate.R0000644000176200001440000002264113575266047013546 0ustar liggesusers#' @include hidden.R NULL #' Safely interpolate values into an SQL string #' #' @description #' Accepts a query string with placeholders for values, and returns a string #' with the values embedded. #' The function is careful to quote all of its inputs with [dbQuoteLiteral()] #' to protect against SQL injection attacks. #' #' Placeholders can be specified with one of two syntaxes: #' #' - `?`: each occurrence of a standalone `?` is replaced with a value #' - `?name1`, `?name2`, ...: values are given as named arguments or a #' named list, the names are used to match the values #' #' Mixing `?` and `?name` syntaxes is an error. #' The number and names of values supplied must correspond to the placeholders #' used in the query. #' #' @section Backend authors: #' If you are implementing an SQL backend with non-ANSI quoting rules, you'll #' need to implement a method for [sqlParseVariables()]. Failure to #' do so does not expose you to SQL injection attacks, but will (rarely) result #' in errors matching supplied and interpolated variables. #' #' @inheritParams dbGetQuery #' @param sql A SQL string containing variables to interpolate. #' Variables must start with a question mark and can be any valid R #' identifier, i.e. it must start with a letter or `.`, and be followed #' by a letter, digit, `.` or `_`. #' @param ...,.dots Values (for `...`) or a list (for `.dots`) #' to interpolate into a string. #' Names are required if `sql` uses the `?name` syntax for placeholders. #' All values will be first escaped with [dbQuoteLiteral()] prior #' to interpolation to protect against SQL injection attacks. #' Arguments created by [SQL()] or [dbQuoteIdentifier()] remain unchanged. #' @return The `sql` query with the values from `...` and `.dots` safely #' embedded. #' @export #' @examples #' sql <- "SELECT * FROM X WHERE name = ?name" #' sqlInterpolate(ANSI(), sql, name = "Hadley") #' #' # This is safe because the single quote has been double escaped #' sqlInterpolate(ANSI(), sql, name = "H'); DROP TABLE--;") #' #' # Using paste0() could lead to dangerous SQL with carefully crafted inputs #' # (SQL injection) #' name <- "H'); DROP TABLE--;" #' paste0("SELECT * FROM X WHERE name = '", name, "'") #' #' # Use SQL() or dbQuoteIdentifier() to avoid escaping #' sql2 <- "SELECT * FROM ?table WHERE name in ?names" #' sqlInterpolate(ANSI(), sql2, #' table = dbQuoteIdentifier(ANSI(), "X"), #' names = SQL("('a', 'b')") #' ) #' #' # Don't use SQL() to escape identifiers to avoid SQL injection #' sqlInterpolate(ANSI(), sql2, #' table = SQL("X; DELETE FROM X; SELECT * FROM X"), #' names = SQL("('a', 'b')") #' ) #' #' # Use dbGetQuery() or dbExecute() to process these queries: #' if (requireNamespace("RSQLite", quietly = TRUE)) { #' con <- dbConnect(RSQLite::SQLite()) #' sql <- "SELECT ?value AS value" #' query <- sqlInterpolate(con, sql, value = 3) #' print(dbGetQuery(con, query)) #' dbDisconnect(con) #' } setGeneric("sqlInterpolate", def = function(conn, sql, ..., .dots = list()) standardGeneric("sqlInterpolate") ) #' @rdname hidden_aliases #' @export setMethod("sqlInterpolate", signature("DBIConnection"), function(conn, sql, ..., .dots = list()) { pos <- sqlParseVariables(conn, sql) if (length(pos$start) == 0) { return(SQL(sql)) } vars <- substring(sql, pos$start + 1, pos$end) positional_vars <- pos$start == pos$end if (all(positional_vars) != any(positional_vars)) { stop("Can't mix positional (?) and named (?asdf) variables", call. = FALSE) } values <- c(list(...), .dots) if (all(positional_vars)) { if (length(vars) != length(values)) { stop("Supplied values don't match positional vars to interpolate", call. = FALSE) } if (any(names(values) != "")) { stop("Positional variables don't take named arguments") } } else { if (!setequal(vars, names(values))) { stop("Supplied values don't match named vars to interpolate", call. = FALSE) } values <- values[vars] } safe_values <- vapply(values, function(x) dbQuoteLiteral(conn, x), character(1)) for (i in rev(seq_along(vars))) { sql <- paste0( substring(sql, 0, pos$start[i] - 1), safe_values[i], substring(sql, pos$end[i] + 1, nchar(sql)) ) } SQL(sql) }) #' Parse interpolated variables from SQL. #' #' If you're implementing a backend that uses non-ANSI quoting or commenting #' rules, you'll need to implement a method for `sqlParseVariables` that #' calls `sqlParseVariablesImpl` with the appropriate quote and #' comment specifications. #' #' #' @param start,end Start and end characters for quotes and comments #' @param endRequired Is the ending character of a comment required? #' @param doubleEscape Can quoting characters be escaped by doubling them? #' Defaults to `TRUE`. #' @param escape What character can be used to escape quoting characters? #' Defaults to `""`, i.e. nothing. #' @keywords internal #' @export #' @examples #' # Use [] for quoting and no comments #' sqlParseVariablesImpl("[?a]", #' list(sqlQuoteSpec("[", "]", "\\", FALSE)), #' list() #' ) #' #' # Standard quotes, use # for commenting #' sqlParseVariablesImpl("# ?a\n?b", #' list(sqlQuoteSpec("'", "'"), sqlQuoteSpec('"', '"')), #' list(sqlCommentSpec("#", "\n", FALSE)) #' ) setGeneric("sqlParseVariables", def = function(conn, sql, ...) standardGeneric("sqlParseVariables") ) #' @rdname hidden_aliases #' @export setMethod("sqlParseVariables", signature("DBIConnection"), function(conn, sql, ...) { sqlParseVariablesImpl( sql, list( sqlQuoteSpec('"', '"'), sqlQuoteSpec("'", "'") ), list( sqlCommentSpec("/*", "*/", TRUE), sqlCommentSpec("--", "\n", FALSE) ) ) }) #' @export #' @rdname sqlParseVariables sqlCommentSpec <- function(start, end, endRequired) { list(start = start, end = end, endRequired = endRequired) } #' @export #' @rdname sqlParseVariables sqlQuoteSpec <- function(start, end, escape = "", doubleEscape = TRUE) { list(start = start, end = end, escape = escape, doubleEscape = doubleEscape) } #' @export #' @rdname sqlParseVariables #' @param sql SQL to parse (a character string) #' @param quotes A list of `QuoteSpec` calls defining the quoting #' specification. #' @param comments A list of `CommentSpec` calls defining the commenting #' specification. sqlParseVariablesImpl <- function(sql, quotes, comments) { str_to_vec <- function(s) strsplit(s, "", fixed = TRUE)[[1L]] sql_arr <- c(str_to_vec(as.character(sql)), " ") # characters valid in variable names var_chars <- c(LETTERS, letters, 0:9, "_") # return values var_pos_start <- integer() var_pos_end <- integer() # internal helper variables quote_spec_offset <- 0L comment_spec_offset <- 0L sql_variable_start <- 0L # prepare comments & quotes for quicker comparisions for (c in seq_along(comments)) { comments[[c]][["start"]] <- str_to_vec(comments[[c]][["start"]]) comments[[c]][["end"]] <- str_to_vec(comments[[c]][["end"]]) } for (q in seq_along(quotes)) { quotes[[q]][["hasEscape"]] <- nchar(quotes[[q]][["escape"]]) > 0L } state <- "default" i <- 0L while (i < length(sql_arr)) { i <- i + 1L switch(state, default = { # variable if (sql_arr[[i]] == "?") { sql_variable_start <- i state <- "variable" next } # starting quoted area for (q in seq_along(quotes)) { if (identical(sql_arr[[i]], quotes[[q]][["start"]])) { quote_spec_offset <- q state <- "quote" break } } # we can abort here if the state has changed if (state != "default") next # starting comment for (c in seq_along(comments)) { comment_start_arr <- comments[[c]][["start"]] comment_start_length <- length(comment_start_arr) if (identical(sql_arr[i:(i + comment_start_length - 1L)], comment_start_arr)) { comment_spec_offset <- c i <- i + comment_start_length state <- "comment" break } } }, variable = { if (!(sql_arr[[i]] %in% var_chars)) { # append current variable offsets to return vectors var_pos_start <- c(var_pos_start, sql_variable_start) # we have already read too much, go back i <- i - 1L var_pos_end <- c(var_pos_end, i) state <- "default" } }, quote = { # if we see backslash-like escapes, ignore next character if (quotes[[quote_spec_offset]][["hasEscape"]] && identical(sql_arr[[i]], quotes[[quote_spec_offset]][[3]])) { i <- i + 1L next } # end quoted area if (identical(sql_arr[[i]], quotes[[quote_spec_offset]][["end"]])) { quote_spec_offset <- 0L state <- "default" } }, comment = { # end commented area comment_end_arr <- comments[[comment_spec_offset]][["end"]] comment_end_length <- length(comment_end_arr) if (identical(sql_arr[i:(i + comment_end_length - 1L)], comment_end_arr)) { i <- i + comment_end_length comment_spec_offset <- 0L state <- "default" } } ) # } # if (quote_spec_offset > 0L) { stop("Unterminated literal") } if (comment_spec_offset > 0L && comments[[comment_spec_offset]][["endRequired"]]) { stop("Unterminated comment") } list(start = var_pos_start, end = var_pos_end) } DBI/R/table.R0000644000176200001440000000310213550652311012260 0ustar liggesusers#' @include hidden.R NULL #' @rdname Id setClass("Id", slots = list(name = "character")) #' Refer to a table nested in a hierarchy (e.g. within a schema) #' #' Objects of class `Id` have a single slot `name`, which is a named #' character vector. #' The [dbQuoteIdentifier()] method converts `Id` objects to strings. #' Support for `Id` objects depends on the database backend. #' They can be used in the following methods as `name` argument: #' - [dbCreateTable()] #' - [dbAppendTable()] #' - [dbReadTable()] #' - [dbWriteTable()] #' - [dbExistsTable()] #' - [dbRemoveTable()] #' Objects of this class are also returned from [dbListObjects()]. #' #' @param ... Components of the hierarchy, e.g. `schema`, `table`, #' or `cluster`, `catalog`, `schema`, `table`. #' For more on these concepts, see #' \url{http://stackoverflow.com/questions/7022755/} #' @export #' @examples #' Id(schema = "dbo", table = "Customer") #' dbQuoteIdentifier(ANSI(), Id(schema = "nycflights13", table = "flights")) #' Id(cluster = "mycluster", catalog = "mycatalog", schema = "myschema", table = "mytable") Id <- function(...) { components <- c(...) if (is.null(names(components)) || any(names(components) == "")) { stop("All arguments to Id() must be named.", call. = FALSE) } new("Id", name = components) } #' @rdname hidden_aliases #' @param object Table object to print #' @export setMethod("show", signature("Id"), function(object) { cat(toString(object), "\n", sep = "") }) #' @export toString.Id <- function(x, ...) { paste0(" ", paste0(names(x@name), " = ", x@name, collapse = ", ")) } DBI/R/deprecated.R0000644000176200001440000002334613575266047013323 0ustar liggesusers#' @include hidden.R NULL #' Make R identifiers into legal SQL identifiers #' #' These methods are DEPRECATED. Please use [dbQuoteIdentifier()] #' (or possibly [dbQuoteString()]) instead. #' #' The algorithm in `make.db.names` first invokes `make.names` and #' then replaces each occurrence of a dot `.` by an underscore `_`. If #' `allow.keywords` is `FALSE` and identifiers collide with SQL #' keywords, a small integer is appended to the identifier in the form of #' `"_n"`. #' #' The set of SQL keywords is stored in the character vector #' `.SQL92Keywords` and reflects the SQL ANSI/ISO standard as documented #' in "X/Open SQL and RDA", 1994, ISBN 1-872630-68-8. Users can easily #' override or update this vector. #' #' @section Bugs: #' The current mapping is not guaranteed to be fully reversible: some SQL #' identifiers that get mapped into R identifiers with `make.names` and #' then back to SQL with [make.db.names()] will not be equal to the #' original SQL identifiers (e.g., compound SQL identifiers of the form #' `username.tablename` will loose the dot ``.''). #' #' @references The set of SQL keywords is stored in the character vector #' `.SQL92Keywords` and reflects the SQL ANSI/ISO standard as documented #' in "X/Open SQL and RDA", 1994, ISBN 1-872630-68-8. Users can easily #' override or update this vector. #' @aliases #' make.db.names #' SQLKeywords #' isSQLKeyword #' @param dbObj any DBI object (e.g., `DBIDriver`). #' @param snames a character vector of R identifiers (symbols) from which we #' need to make SQL identifiers. #' @param name a character vector with database identifier candidates we need #' to determine whether they are legal SQL identifiers or not. #' @param unique logical describing whether the resulting set of SQL names #' should be unique. Its default is `TRUE`. Following the SQL 92 #' standard, uniqueness of SQL identifiers is determined regardless of whether #' letters are upper or lower case. #' @param allow.keywords logical describing whether SQL keywords should be #' allowed in the resulting set of SQL names. Its default is `TRUE` #' @param keywords a character vector with SQL keywords, by default it's #' `.SQL92Keywords` defined by the DBI. #' @param case a character string specifying whether to make the comparison as #' lower case, upper case, or any of the two. it defaults to `any`. #' @param \dots any other argument are passed to the driver implementation. #' @return `make.db.names` returns a character vector of legal SQL #' identifiers corresponding to its `snames` argument. #' #' `SQLKeywords` returns a character vector of all known keywords for the #' database-engine associated with `dbObj`. #' #' `isSQLKeyword` returns a logical vector parallel to `name`. #' @export #' @keywords internal setGeneric("make.db.names", def = function(dbObj, snames, keywords = .SQL92Keywords, unique = TRUE, allow.keywords = TRUE, ...) standardGeneric("make.db.names"), signature = c("dbObj", "snames"), valueClass = "character" ) #' @rdname hidden_aliases setMethod("make.db.names", signature(dbObj = "DBIObject", snames = "character"), definition = function(dbObj, snames, keywords, unique, allow.keywords, ...) { make.db.names.default(snames, keywords, unique, allow.keywords) }, valueClass = "character" ) ## produce legal SQL identifiers from strings in a character vector ## unique, in this function, means unique regardless of lower/upper case #' @rdname make.db.names #' @export make.db.names.default <- function(snames, keywords = .SQL92Keywords, unique = TRUE, allow.keywords = TRUE) { makeUnique <- function(x, sep = "_") { if (length(x) == 0) return(x) out <- x lc <- make.names(tolower(x), unique = FALSE) i <- duplicated(lc) lc <- make.names(lc, unique = TRUE) out[i] <- paste(out[i], substring(lc[i], first = nchar(out[i]) + 1), sep = sep) out } ## Note: SQL identifiers *can* be enclosed in double or single quotes ## when they are equal to reserverd keywords. fc <- substring(snames, 1, 1) lc <- substring(snames, nchar(snames)) i <- match(fc, c("'", '"'), 0) > 0 & match(lc, c("'", '"'), 0) > 0 snames[!i] <- make.names(snames[!i], unique = FALSE) if (unique) { snames[!i] <- makeUnique(snames[!i]) } if (!allow.keywords) { kwi <- match(keywords, toupper(snames), nomatch = 0L) snames[kwi] <- paste('"', snames[kwi], '"', sep = "") } gsub("\\.", "_", snames) } #' @rdname make.db.names #' @export setGeneric("isSQLKeyword", def = function(dbObj, name, keywords = .SQL92Keywords, case = c("lower", "upper", "any")[3], ...) standardGeneric("isSQLKeyword"), signature = c("dbObj", "name"), valueClass = "logical" ) #' @rdname hidden_aliases setMethod("isSQLKeyword", signature(dbObj = "DBIObject", name = "character"), definition = function(dbObj, name, keywords, case, ...) isSQLKeyword.default(name, keywords, case), valueClass = "logical" ) #' @rdname make.db.names #' @export isSQLKeyword.default <- function(name, keywords = .SQL92Keywords, case = c("lower", "upper", "any")[3]) { n <- pmatch(case, c("lower", "upper", "any"), nomatch = 0) if (n == 0) { stop('case must be one of "lower", "upper", or "any"') } kw <- switch(c("lower", "upper", "any")[n], lower = tolower(keywords), upper = toupper(keywords), any = toupper(keywords) ) if (n == 3) { name <- toupper(name) } match(name, keywords, nomatch = 0) > 0 } ## SQL ANSI 92 (plus ISO's) keywords --- all 220 of them! ## (See pp. 22 and 23 in X/Open SQL and RDA, 1994, isbn 1-872630-68-8) #' @export setGeneric("SQLKeywords", def = function(dbObj, ...) standardGeneric("SQLKeywords"), valueClass = "character" ) #' @rdname hidden_aliases setMethod("SQLKeywords", signature("DBIObject"), definition = function(dbObj, ...) .SQL92Keywords, valueClass = "character" ) #' @rdname hidden_aliases setMethod("SQLKeywords", signature("missing"), definition = function(dbObj, ...) .SQL92Keywords, valueClass = "character" ) #' @export .SQL92Keywords <- c( "ABSOLUTE", "ADD", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "AS", "ASC", "ASSERTION", "AT", "AUTHORIZATION", "AVG", "BEGIN", "BETWEEN", "BIT", "BIT_LENGTH", "BY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR", "CHARACTER", "CHARACTER_LENGTH", "CHAR_LENGTH", "CHECK", "CLOSE", "COALESCE", "COLLATE", "COLLATION", "COLUMN", "COMMIT", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTINUE", "CONVERT", "CORRESPONDING", "COUNT", "CREATE", "CURRENT", "CURRENT_DATE", "CURRENT_TIMESTAMP", "CURRENT_TYPE", "CURSOR", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DICONNECT", "DICTIONATRY", "DISPLACEMENT", "DISTINCT", "DOMAIN", "DOUBLE", "DROP", "ELSE", "END", "END-EXEC", "ESCAPE", "EXCEPT", "EXCEPTION", "EXEC", "EXECUTE", "EXISTS", "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FIRST", "FLOAT", "FOR", "FOREIGN", "FOUND", "FROM", "FULL", "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GROUP", "HAVING", "HOUR", "IDENTITY", "IGNORE", "IMMEDIATE", "IN", "INCLUDE", "INDEX", "INDICATOR", "INITIALLY", "INNER", "INPUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT", "INTERVAL", "INTO", "IS", "ISOLATION", "JOIN", "KEY", "LANGUAGE", "LAST", "LEFT", "LEVEL", "LIKE", "LOCAL", "LOWER", "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATIONAL", "NCHAR", "NEXT", "NOT", "NULL", "NULLIF", "NUMERIC", "OCTECT_LENGTH", "OF", "OFF", "ONLY", "OPEN", "OPTION", "OR", "ORDER", "OUTER", "OUTPUT", "OVERLAPS", "PARTIAL", "POSITION", "PRECISION", "PREPARE", "PRESERVE", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE", "PUBLIC", "READ", "REAL", "REFERENCES", "RESTRICT", "REVOKE", "RIGHT", "ROLLBACK", "ROWS", "SCHEMA", "SCROLL", "SECOND", "SECTION", "SELECT", "SET", "SIZE", "SMALLINT", "SOME", "SQL", "SQLCA", "SQLCODE", "SQLERROR", "SQLSTATE", "SQLWARNING", "SUBSTRING", "SUM", "SYSTEM", "TABLE", "TEMPORARY", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TO", "TRANSACTION", "TRANSLATE", "TRANSLATION", "TRUE", "UNION", "UNIQUE", "UNKNOWN", "UPDATE", "UPPER", "USAGE", "USER", "USING", "VALUE", "VALUES", "VARCHAR", "VARYING", "VIEW", "WHEN", "WHENEVER", "WHERE", "WITH", "WORK", "WRITE", "YEAR", "ZONE" ) #' Call an SQL stored procedure #' #' **Deprecated since 2014** #' #' The recommended way of calling a stored procedure is now #' #' \enumerate{ #' \item{\code{\link{dbGetQuery}} if a result set is returned} #' \item{\code{\link{dbExecute}} for data manipulation and other cases where no result set is returned} #' } #' #' @inheritParams dbGetQuery #' @keywords internal #' @export setGeneric("dbCallProc", def = function(conn, ...) { .Deprecated() standardGeneric("dbCallProc") } ) #' Determine the current version of the package. #' #' @export #' @keywords internal dbGetDBIVersion <- function() { .Deprecated("packageVersion('DBI')") utils::packageVersion("DBI") } #' Set data mappings between an DBMS and R. #' #' This generic is deprecated since no working implementation was ever produced. #' #' Sets one or more conversion functions to handle the translation of DBMS data #' types to R objects. This is only needed for non-primitive data, since all #' DBI drivers handle the common base types (integers, numeric, strings, etc.) #' #' The details on conversion functions (e.g., arguments, whether they can invoke #' initializers and/or destructors) have not been specified. #' #' @inheritParams dbClearResult #' @keywords internal #' @param flds a field description object as returned by `dbColumnInfo`. #' @export setGeneric("dbSetDataMappings", def = function(res, flds, ...) { .Deprecated() standardGeneric("dbSetDataMappings") } ) DBI/R/DBI-package.R0000644000176200001440000000132613550652132013167 0ustar liggesusers#' @description #' DBI defines an interface for communication between R and relational database #' management systems. #' All classes in this package are virtual and need to be extended by #' the various R/DBMS implementations (so-called *DBI backends*). #' #' @inheritSection DBItest::DBIspec Definition #' @inheritSection DBItest::DBIspec DBI classes and methods #' @inheritSection DBItest::DBIspec Construction of the DBIDriver object #' #' @examples #' RSQLite::SQLite() #' @seealso #' Important generics: [dbConnect()], [dbGetQuery()], #' [dbReadTable()], [dbWriteTable()], [dbDisconnect()] #' #' Formal specification (currently work in progress and incomplete): #' `vignette("spec", package = "DBI")` "_PACKAGE" DBI/R/list-pairs.R0000644000176200001440000000026413550652132013267 0ustar liggesusersprint_list_pairs <- function(x, ...) { for(key in names(x)){ value <- format(x[[key]]) if (identical(value, "")) next cat(key, "=", value, "\n") } invisible(x) } DBI/R/data.R0000644000176200001440000000474413575062232012123 0ustar liggesusers#' @include hidden.R NULL #' Convert a data frame into form suitable for upload to an SQL database #' #' This is a generic method that coerces R objects into vectors suitable for #' upload to the database. The output will vary a little from method to #' method depending on whether the main upload device is through a single #' SQL string or multiple parameterized queries. #' This method is mostly useful for backend implementers. #' #' The default method: #' \itemize{ #' \item Converts factors to characters #' \item Quotes all strings #' \item Converts all columns to strings #' \item Replaces NA with NULL #' } #' #' @inheritParams sqlCreateTable #' @inheritParams rownames #' @param value A data frame #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' sqlData(con, head(iris)) #' sqlData(con, head(mtcars)) #' #' dbDisconnect(con) setGeneric("sqlData", def = function(con, value, row.names = NA, ...) standardGeneric("sqlData") ) #' @rdname hidden_aliases #' @export setMethod("sqlData", signature("DBIConnection"), function(con, value, row.names = NA, ...) { value <- sqlRownamesToColumn(value, row.names) # Convert factors to strings is_factor <- vapply(value, is.factor, logical(1)) value[is_factor] <- lapply(value[is_factor], as.character) # Quote all strings is_char <- vapply(value, is.character, logical(1)) value[is_char] <- lapply(value[is_char], function(x) { enc2utf8(dbQuoteString(con, x)) }) # Convert everything to character and turn NAs into NULL value[] <- lapply(value, as.character) value[is.na(value)] <- "NULL" value }) # Coercion rules --------------------------------------------------------------- coerce <- function(sqlvar, from, to) { list(from = from, to = to) } sqlDate <- function() { coerce( function(x) as.integer(x), function(x) { stopifnot(is.integer(x)) structure(x, class = "Date") } ) } sqlDateTime <- function() { coerce( function(x) as.numeric(x), function(x) { stopifnot(is.numeric(x)) structure(x, class = c("POSIXct", "POSIXt"), tzone = "UTC") } ) } sqlSerialize <- function() { coerce( function(x) { lapply(x, serialize, connection = NULL) }, function(x) { lapply(x, unserialize) } ) } sqlBoolean <- function() { coerce( function(x) as.integer(x), function(x) as.logical(x) ) } sqlFactor <- function(levels) { coerce( function(x) as.integer(x), function(x) factor(x, levels = levels) ) } DBI/R/ANSI.R0000644000176200001440000000064113550652140011730 0ustar liggesusers#' @include hidden.R #' @include DBConnection.R #' @include DBDriver.R setClass("AnsiConnection", contains = "DBIConnection") #' A dummy DBI connector that simulates ANSI-SQL compliance #' #' @export #' @keywords internal #' @examples #' ANSI() ANSI <- function() { new("AnsiConnection") } #' @rdname hidden_aliases #' @export setMethod("show", "AnsiConnection", function(object) { cat("\n") }) DBI/R/DBResult.R0000644000176200001440000002651613575062550012702 0ustar liggesusers#' @include hidden.R NULL #' DBIResult class #' #' This virtual class describes the result and state of execution of #' a DBMS statement (any statement, query or non-query). The result set #' keeps track of whether the statement produces output how many rows were #' affected by the operation, how many rows have been fetched (if statement is #' a query), whether there are more rows to fetch, etc. #' #' @section Implementation notes: #' Individual drivers are free to allow single or multiple #' active results per connection. #' #' The default show method displays a summary of the query using other #' DBI generics. #' #' @name DBIResult-class #' @docType class #' @family DBI classes #' @family DBIResult generics #' @export #' @include DBObject.R setClass("DBIResult", contains = c("DBIObject", "VIRTUAL")) #' @rdname hidden_aliases #' @param object Object to display #' @export setMethod("show", signature("DBIResult"), function(object) { # to protect drivers that fail to implement the required methods (e.g., # RPostgreSQL) tryCatch( show_result(object), error = function(e) NULL ) invisible(NULL) }) show_result <- function(object) { cat("<", is(object)[1], ">\n", sep = "") if (!dbIsValid(object)) { cat("EXPIRED\n") } else { cat(" SQL ", dbGetStatement(object), "\n", sep = "") done <- if (dbHasCompleted(object)) "complete" else "incomplete" cat(" ROWS Fetched: ", dbGetRowCount(object), " [", done, "]\n", sep = "") cat(" Changed: ", dbGetRowsAffected(object), "\n", sep = "") } } #' Fetch records from a previously executed query #' #' Fetch the next `n` elements (rows) from the result set and return them #' as a data.frame. #' #' `fetch()` is provided for compatibility with older DBI clients - for all #' new code you are strongly encouraged to use `dbFetch()`. The default #' implementation for `dbFetch()` calls `fetch()` so that it is compatible with #' existing code. Modern backends should implement for `dbFetch()` only. #' #' @template methods #' @templateVar method_name dbFetch #' #' @inherit DBItest::spec_result_fetch return #' @inheritSection DBItest::spec_result_fetch Specification #' @inheritSection DBItest::spec_result_roundtrip Specification #' #' @param res An object inheriting from [DBIResult-class], created by #' [dbSendQuery()]. #' @param n maximum number of records to retrieve per fetch. Use `n = -1` #' or `n = Inf` #' to retrieve all pending records. Some implementations may recognize other #' special values. #' @param ... Other arguments passed on to methods. #' @seealso Close the result set with [dbClearResult()] as soon as you #' finish retrieving the records you want. #' @family DBIResult generics #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' #' # Fetch all results #' rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") #' dbFetch(rs) #' dbClearResult(rs) #' #' # Fetch in chunks #' rs <- dbSendQuery(con, "SELECT * FROM mtcars") #' while (!dbHasCompleted(rs)) { #' chunk <- dbFetch(rs, 10) #' print(nrow(chunk)) #' } #' #' dbClearResult(rs) #' dbDisconnect(con) #' @export setGeneric("dbFetch", def = function(res, n = -1, ...) standardGeneric("dbFetch"), valueClass = "data.frame" ) #' @rdname hidden_aliases #' @export setMethod("dbFetch", signature("DBIResult"), function(res, n = -1, ...) { fetch(res, n = n, ...) }) #' @rdname dbFetch #' @export setGeneric("fetch", def = function(res, n = -1, ...) standardGeneric("fetch"), valueClass = "data.frame" ) #' Clear a result set #' #' Frees all resources (local and remote) associated with a result set. In some #' cases (e.g., very large result sets) this can be a critical step to avoid #' exhausting resources (memory, file descriptors, etc.) #' #' @template methods #' @templateVar method_name dbClearResult #' #' @inherit DBItest::spec_result_clear_result return #' @inheritSection DBItest::spec_result_clear_result Specification #' #' @param res An object inheriting from [DBIResult-class]. #' @param ... Other arguments passed on to methods. #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' rs <- dbSendQuery(con, "SELECT 1") #' print(dbFetch(rs)) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbClearResult", def = function(res, ...) standardGeneric("dbClearResult") ) #' Information about result types #' #' Produces a data.frame that describes the output of a query. The data.frame #' should have as many rows as there are output fields in the result set, and #' each column in the data.frame describes an aspect of the result set #' field (field name, type, etc.) #' #' @inheritParams dbClearResult #' #' @inherit DBItest::spec_meta_column_info return #' @inheritSection DBItest::spec_meta_column_info Specification #' #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' rs <- dbSendQuery(con, "SELECT 1 AS a, 2 AS b") #' dbColumnInfo(rs) #' dbFetch(rs) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbColumnInfo", def = function(res, ...) standardGeneric("dbColumnInfo"), valueClass = "data.frame" ) #' Get the statement associated with a result set #' #' Returns the statement that was passed to [dbSendQuery()] #' or [dbSendStatement()]. #' #' @template methods #' @templateVar method_name dbGetStatement #' #' @inherit DBItest::spec_meta_get_statement return #' #' @inheritParams dbClearResult #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' rs <- dbSendQuery(con, "SELECT * FROM mtcars") #' dbGetStatement(rs) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbGetStatement", def = function(res, ...) standardGeneric("dbGetStatement"), valueClass = "character" ) #' Completion status #' #' This method returns if the operation has completed. #' A `SELECT` query is completed if all rows have been fetched. #' A data manipulation statement is always completed. #' #' @template methods #' @templateVar method_name dbHasCompleted #' #' @inherit DBItest::spec_meta_has_completed return #' @inheritSection DBItest::spec_meta_has_completed Specification #' #' @inheritParams dbClearResult #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' rs <- dbSendQuery(con, "SELECT * FROM mtcars") #' #' dbHasCompleted(rs) #' ret1 <- dbFetch(rs, 10) #' dbHasCompleted(rs) #' ret2 <- dbFetch(rs) #' dbHasCompleted(rs) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbHasCompleted", def = function(res, ...) standardGeneric("dbHasCompleted"), valueClass = "logical" ) #' The number of rows affected #' #' This method returns the number of rows that were added, deleted, or updated #' by a data manipulation statement. #' #' @template methods #' @templateVar method_name dbGetRowsAffected #' #' @inherit DBItest::spec_meta_get_rows_affected return #' #' @inheritParams dbClearResult #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' rs <- dbSendStatement(con, "DELETE FROM mtcars") #' dbGetRowsAffected(rs) #' nrow(mtcars) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbGetRowsAffected", def = function(res, ...) standardGeneric("dbGetRowsAffected"), valueClass = "numeric" ) #' The number of rows fetched so far #' #' Returns the total number of rows actually fetched with calls to [dbFetch()] #' for this result set. #' #' @template methods #' @templateVar method_name dbGetRowCount #' #' @inherit DBItest::spec_meta_get_row_count return #' #' @inheritParams dbClearResult #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' rs <- dbSendQuery(con, "SELECT * FROM mtcars") #' #' dbGetRowCount(rs) #' ret1 <- dbFetch(rs, 10) #' dbGetRowCount(rs) #' ret2 <- dbFetch(rs) #' dbGetRowCount(rs) #' nrow(ret1) + nrow(ret2) #' #' dbClearResult(rs) #' dbDisconnect(con) setGeneric("dbGetRowCount", def = function(res, ...) standardGeneric("dbGetRowCount"), valueClass = "numeric" ) #' @name dbGetInfo #' @section Implementation notes: #' The default implementation for `DBIResult objects` #' constructs such a list from the return values of the corresponding methods, #' [dbGetStatement()], [dbGetRowCount()], #' [dbGetRowsAffected()], and [dbHasCompleted()]. NULL #' @rdname hidden_aliases setMethod("dbGetInfo", signature("DBIResult"), function(dbObj, ...) { list( statement = dbGetStatement(dbObj), row.count = dbGetRowCount(dbObj), rows.affected = dbGetRowsAffected(dbObj), has.completed = dbHasCompleted(dbObj) ) }) #' Bind values to a parameterized/prepared statement #' #' For parametrized or prepared statements, #' the [dbSendQuery()] and [dbSendStatement()] functions can be called with #' statements that contain placeholders for values. The `dbBind()` function #' binds these placeholders #' to actual values, and is intended to be called on the result set #' before calling [dbFetch()] or [dbGetRowsAffected()]. #' #' \pkg{DBI} supports parametrized (or prepared) queries and statements #' via the `dbBind()` generic. #' Parametrized queries are different from normal queries #' in that they allow an arbitrary number of placeholders, #' which are later substituted by actual values. #' Parametrized queries (and statements) serve two purposes: #' #' - The same query can be executed more than once with different values. #' The DBMS may cache intermediate information for the query, #' such as the execution plan, #' and execute it faster. #' - Separation of query syntax and parameters protects against SQL injection. #' #' The placeholder format is currently not specified by \pkg{DBI}; #' in the future, a uniform placeholder syntax may be supported. #' Consult the backend documentation for the supported formats. #' For automated testing, backend authors specify the placeholder syntax with #' the `placeholder_pattern` tweak. #' Known examples are: #' #' - `?` (positional matching in order of appearance) in \pkg{RMySQL} and \pkg{RSQLite} #' - `$1` (positional matching by index) in \pkg{RPostgres} and \pkg{RSQLite} #' - `:name` and `$name` (named matching) in \pkg{RSQLite} #' #' @template methods #' @templateVar method_name dbBind #' #' @inherit DBItest::spec_meta_bind return #' @inheritSection DBItest::spec_meta_bind Specification #' #' @inheritParams dbClearResult #' @param params A list of bindings, named or unnamed. #' @family DBIResult generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "iris", iris) #' #' # Using the same query for different values #' iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > ?") #' dbBind(iris_result, list(2.3)) #' dbFetch(iris_result) #' dbBind(iris_result, list(3)) #' dbFetch(iris_result) #' dbClearResult(iris_result) #' #' # Executing the same statement with different values at once #' iris_result <- dbSendStatement(con, "DELETE FROM iris WHERE [Species] = $species") #' dbBind(iris_result, list(species = c("setosa", "versicolor", "unknown"))) #' dbGetRowsAffected(iris_result) #' dbClearResult(iris_result) #' #' nrow(dbReadTable(con, "iris")) #' #' dbDisconnect(con) setGeneric("dbBind", def = function(res, params, ...) standardGeneric("dbBind") ) DBI/R/DBConnection.R0000644000176200001440000005201113575266242013514 0ustar liggesusers#' @include table.R #' @include hidden.R NULL #' DBIConnection class #' #' This virtual class encapsulates the connection to a DBMS, and it provides #' access to dynamic queries, result sets, DBMS session management #' (transactions), etc. #' #' @section Implementation note: #' Individual drivers are free to implement single or multiple simultaneous #' connections. #' #' @docType class #' @name DBIConnection-class #' @family DBI classes #' @family DBIConnection generics #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' con #' dbDisconnect(con) #' #' \dontrun{ #' con <- dbConnect(RPostgreSQL::PostgreSQL(), "username", "passsword") #' con #' dbDisconnect(con) #' } #' @export #' @include DBObject.R setClass("DBIConnection", contains = c("DBIObject", "VIRTUAL")) #' @rdname hidden_aliases #' @param object Object to display #' @export setMethod("show", "DBIConnection", function(object) { # to protect drivers that fail to implement the required methods (e.g., # RPostgreSQL) tryCatch( show_connection(object), error = function(e) NULL ) invisible(NULL) }) show_connection <- function(object) { cat("<", is(object)[1], ">\n", sep = "") if (!dbIsValid(object)) { cat(" DISCONNECTED\n") } } #' Disconnect (close) a connection #' #' This closes the connection, discards all pending work, and frees #' resources (e.g., memory, sockets). #' #' @template methods #' @templateVar method_name dbDisconnect #' #' @inherit DBItest::spec_connection_disconnect return #' @inheritSection DBItest::spec_connection_disconnect Specification #' #' @inheritParams dbGetQuery #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' dbDisconnect(con) setGeneric("dbDisconnect", def = function(conn, ...) standardGeneric("dbDisconnect") ) #' Execute a query on a given database connection #' #' The `dbSendQuery()` method only submits and synchronously executes the #' SQL query to the database engine. It does \emph{not} extract any #' records --- for that you need to use the [dbFetch()] method, and #' then you must call [dbClearResult()] when you finish fetching the #' records you need. For interactive use, you should almost always prefer #' [dbGetQuery()]. #' #' This method is for `SELECT` queries only. Some backends may #' support data manipulation queries through this method for compatibility #' reasons. However, callers are strongly encouraged to use #' [dbSendStatement()] for data manipulation statements. #' #' The query is submitted to the database server and the DBMS executes it, #' possibly generating vast amounts of data. Where these data live #' is driver-specific: some drivers may choose to leave the output on the server #' and transfer them piecemeal to R, others may transfer all the data to the #' client -- but not necessarily to the memory that R manages. See individual #' drivers' `dbSendQuery()` documentation for details. #' #' @template methods #' @templateVar method_name dbSendQuery #' #' @inherit DBItest::spec_result_send_query return #' @inheritSection DBItest::spec_result_send_query Additional arguments #' @inheritSection DBItest::spec_result_send_query Specification #' @inheritSection DBItest::spec_result_send_query Specification for the `immediate` argument #' #' @inheritParams dbGetQuery #' @param statement a character string containing SQL. #' #' @family DBIConnection generics #' @seealso For updates: [dbSendStatement()] and [dbExecute()]. #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") #' dbFetch(rs) #' dbClearResult(rs) #' #' # Pass one set of values with the param argument: #' rs <- dbSendQuery( #' con, #' "SELECT * FROM mtcars WHERE cyl = ?", #' params = list(4L) #' ) #' dbFetch(rs) #' dbClearResult(rs) #' #' # Pass multiple sets of values with dbBind(): #' rs <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = ?") #' dbBind(rs, list(6L)) #' dbFetch(rs) #' dbBind(rs, list(8L)) #' dbFetch(rs) #' dbClearResult(rs) #' #' dbDisconnect(con) #' @export setGeneric("dbSendQuery", def = function(conn, statement, ...) standardGeneric("dbSendQuery"), valueClass = "DBIResult" ) #' Execute a data manipulation statement on a given database connection #' #' The `dbSendStatement()` method only submits and synchronously executes the #' SQL data manipulation statement (e.g., `UPDATE`, `DELETE`, #' `INSERT INTO`, `DROP TABLE`, ...) to the database engine. To query #' the number of affected rows, call [dbGetRowsAffected()] on the #' returned result object. You must also call [dbClearResult()] after #' that. For interactive use, you should almost always prefer #' [dbExecute()]. #' #' [dbSendStatement()] comes with a default implementation that simply #' forwards to [dbSendQuery()], to support backends that only #' implement the latter. #' #' @template methods #' @templateVar method_name dbSendStatement #' #' @inherit DBItest::spec_result_send_statement return #' @inheritSection DBItest::spec_result_send_statement Additional arguments #' @inheritSection DBItest::spec_result_send_statement Specification #' @inheritSection DBItest::spec_result_send_statement Specification for the `immediate` argument #' #' @inheritParams dbGetQuery #' @param statement a character string containing SQL. #' #' @family DBIConnection generics #' @seealso For queries: [dbSendQuery()] and [dbGetQuery()]. #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "cars", head(cars, 3)) #' #' rs <- dbSendStatement( #' con, #' "INSERT INTO cars (speed, dist) VALUES (1, 1), (2, 2), (3, 3)" #' ) #' dbHasCompleted(rs) #' dbGetRowsAffected(rs) #' dbClearResult(rs) #' dbReadTable(con, "cars") # there are now 6 rows #' #' # Pass one set of values directly using the param argument: #' rs <- dbSendStatement( #' con, #' "INSERT INTO cars (speed, dist) VALUES (?, ?)", #' params = list(4L, 5L) #' ) #' dbClearResult(rs) #' #' # Pass multiple sets of values using dbBind(): #' rs <- dbSendStatement( #' con, #' "INSERT INTO cars (speed, dist) VALUES (?, ?)" #' ) #' dbBind(rs, list(5:6, 6:7)) #' dbBind(rs, list(7L, 8L)) #' dbClearResult(rs) #' dbReadTable(con, "cars") # there are now 10 rows #' #' dbDisconnect(con) #' @export setGeneric("dbSendStatement", def = function(conn, statement, ...) standardGeneric("dbSendStatement"), valueClass = "DBIResult" ) #' @rdname hidden_aliases #' @export setMethod( "dbSendStatement", signature("DBIConnection", "character"), function(conn, statement, ...) { dbSendQuery(conn, statement, ...) } ) #' Send query, retrieve results and then clear result set #' #' Returns the result of a query as a data frame. #' `dbGetQuery()` comes with a default implementation #' (which should work with most backends) that calls #' [dbSendQuery()], then [dbFetch()], ensuring that #' the result is always free-d by [dbClearResult()]. #' #' This method is for `SELECT` queries only #' (incl. other SQL statements that return a `SELECT`-alike result, #' e. g. execution of a stored procedure). #' #' To execute a stored procedure that does not return a result set, #' use [dbExecute()]. #' #' Some backends may #' support data manipulation statements through this method for compatibility #' reasons. However, callers are strongly advised to use #' [dbExecute()] for data manipulation statements. #' #' @template methods #' @templateVar method_name dbGetQuery #' #' @inherit DBItest::spec_result_get_query return #' @inheritSection DBItest::spec_result_get_query Additional arguments #' @inheritSection DBItest::spec_result_get_query Specification #' @inheritSection DBItest::spec_result_get_query Specification for the `immediate` argument #' #' @section Implementation notes: #' Subclasses should override this method only if they provide some sort of #' performance optimization. #' #' @param conn A [DBIConnection-class] object, as returned by #' [dbConnect()]. #' @param statement a character string containing SQL. #' @param ... Other parameters passed on to methods. #' @family DBIConnection generics #' @seealso For updates: [dbSendStatement()] and [dbExecute()]. #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' dbGetQuery(con, "SELECT * FROM mtcars") #' dbGetQuery(con, "SELECT * FROM mtcars", n = 6) #' #' # Pass values using the param argument: #' # (This query runs eight times, once for each different #' # parameter. The resulting rows are combined into a single #' # data frame.) #' dbGetQuery( #' con, #' "SELECT COUNT(*) FROM mtcars WHERE cyl = ?", #' params = list(1:8) #' ) #' #' dbDisconnect(con) setGeneric("dbGetQuery", def = function(conn, statement, ...) standardGeneric("dbGetQuery") ) #' @rdname hidden_aliases #' @param n Number of rows to fetch, default -1 #' @export setMethod("dbGetQuery", signature("DBIConnection", "character"), function(conn, statement, ..., n = -1L) { rs <- dbSendQuery(conn, statement, ...) on.exit(dbClearResult(rs)) dbFetch(rs, n = n, ...) } ) #' Execute an update statement, query number of rows affected, and then close result set #' #' Executes a statement and returns the number of rows affected. #' `dbExecute()` comes with a default implementation #' (which should work with most backends) that calls #' [dbSendStatement()], then [dbGetRowsAffected()], ensuring that #' the result is always free-d by [dbClearResult()]. #' #' You can also use `dbExecute()` to call a stored procedure #' that performs data manipulation or other actions that do not return a result set. #' To execute a stored procedure that returns a result set use [dbGetQuery()] instead. #' #' @template methods #' @templateVar method_name dbExecute #' #' @section Implementation notes: #' Subclasses should override this method only if they provide some sort of #' performance optimization. #' #' @inherit DBItest::spec_result_execute return #' @inheritSection DBItest::spec_result_execute Additional arguments #' @inheritSection DBItest::spec_result_execute Specification #' @inheritSection DBItest::spec_result_execute Specification for the `immediate` argument #' #' @inheritParams dbGetQuery #' @param statement a character string containing SQL. #' @family DBIConnection generics #' @seealso For queries: [dbSendQuery()] and [dbGetQuery()]. #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "cars", head(cars, 3)) #' dbReadTable(con, "cars") # there are 3 rows #' dbExecute( #' con, #' "INSERT INTO cars (speed, dist) VALUES (1, 1), (2, 2), (3, 3)" #' ) #' dbReadTable(con, "cars") # there are now 6 rows #' #' # Pass values using the param argument: #' dbExecute( #' con, #' "INSERT INTO cars (speed, dist) VALUES (?, ?)", #' params = list(4:7, 5:8) #' ) #' dbReadTable(con, "cars") # there are now 10 rows #' #' dbDisconnect(con) setGeneric("dbExecute", def = function(conn, statement, ...) standardGeneric("dbExecute") ) #' @rdname hidden_aliases #' @export setMethod( "dbExecute", signature("DBIConnection", "character"), function(conn, statement, ...) { rs <- dbSendStatement(conn, statement, ...) on.exit(dbClearResult(rs)) dbGetRowsAffected(rs) } ) #' Get DBMS exceptions #' #' DEPRECATED. Backends should use R's condition system to signal errors and #' warnings. #' #' @inheritParams dbGetQuery #' @family DBIConnection generics #' @return a list with elements `errorNum` (an integer error number) and #' `errorMsg` (a character string) describing the last error in the #' connection `conn`. #' @export #' @keywords internal setGeneric("dbGetException", def = function(conn, ...) standardGeneric("dbGetException") ) #' A list of all pending results #' #' DEPRECATED. DBI currenty supports only one open result set per connection, #' you need to keep track of the result sets you open if you need this #' functionality. #' #' @inheritParams dbGetQuery #' @family DBIConnection generics #' @return a list. If no results are active, an empty list. If only #' a single result is active, a list with one element. #' @export #' @keywords internal setGeneric("dbListResults", def = function(conn, ...) standardGeneric("dbListResults") ) #' List field names of a remote table #' #' @inheritParams dbGetQuery #' @param name a character string with the name of the remote table. #' #' @inherit DBItest::spec_sql_list_fields return #' @inheritSection DBItest::spec_sql_list_fields Specification #' #' @family DBIConnection generics #' @seealso [dbColumnInfo()] to get the type of the fields. #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars) #' dbListFields(con, "mtcars") #' #' dbDisconnect(con) setGeneric("dbListFields", def = function(conn, name, ...) standardGeneric("dbListFields"), valueClass = "character" ) #' @rdname hidden_aliases #' @export setMethod("dbListFields", signature("DBIConnection", "character"), function(conn, name, ...) { list_fields(conn, name) } ) #' @rdname hidden_aliases #' @export setMethod("dbListFields", signature("DBIConnection", "Id"), function(conn, name, ...) { list_fields(conn, name) } ) list_fields <- function(conn, name) { rs <- dbSendQuery( conn, paste( "SELECT * FROM ", dbQuoteIdentifier(conn, name), "LIMIT 0" ) ) on.exit(dbClearResult(rs)) names(dbFetch(rs, n = 0, row.names = FALSE)) } #' List remote tables #' #' Returns the unquoted names of remote tables accessible through this #' connection. #' This should include views and temporary objects, but not all database backends #' (in particular \pkg{RMariaDB} and \pkg{RMySQL}) support this. #' #' @template methods #' @templateVar method_name dbListTables #' #' @inherit DBItest::spec_sql_list_tables return #' #' @inheritParams dbGetQuery #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbListTables(con) #' dbWriteTable(con, "mtcars", mtcars) #' dbListTables(con) #' #' dbDisconnect(con) setGeneric("dbListTables", def = function(conn, ...) standardGeneric("dbListTables"), valueClass = "character" ) #' List remote objects #' #' Returns the names of remote objects accessible through this connection #' as a data frame. #' This should include temporary objects, but not all database backends #' (in particular \pkg{RMariaDB} and \pkg{RMySQL}) support this. #' Compared to [dbListTables()], this method also enumerates tables and views #' in schemas, and returns fully qualified identifiers to access these objects. #' This allows exploration of all database objects available to the current #' user, including those that can only be accessed by giving the full #' namespace. #' #' @template methods #' @templateVar method_name dbListObjects #' #' @inherit DBItest::spec_sql_list_objects return #' @inheritSection DBItest::spec_sql_list_objects Additional arguments #' @inheritSection DBItest::spec_sql_list_objects Specification #' #' @inheritParams dbGetQuery #' @param prefix A fully qualified path in the database's namespace, or `NULL`. #' This argument will be processed with [dbUnquoteIdentifier()]. #' If given the method will return all objects accessible through this prefix. #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbListObjects(con) #' dbWriteTable(con, "mtcars", mtcars) #' dbListObjects(con) #' #' dbDisconnect(con) setGeneric("dbListObjects", def = function(conn, prefix = NULL, ...) standardGeneric("dbListObjects"), valueClass = "data.frame" ) #' @rdname hidden_aliases #' @export setMethod("dbListObjects", signature("DBIConnection", "ANY"), function(conn, prefix = NULL, ...) { names <- dbListTables(conn) tables <- lapply(names, function(x) Id(table = x)) ret <- data.frame( table = I(unname(tables)), stringsAsFactors = FALSE ) ret$is_prefix <- rep_len(FALSE, nrow(ret)) ret } ) #' Copy data frames from database tables #' #' Reads a database table to a data frame, optionally converting #' a column to row names and converting the column names to valid #' R identifiers. #' #' @template methods #' @templateVar method_name dbReadTable #' #' @inherit DBItest::spec_sql_read_table return #' @inheritSection DBItest::spec_sql_read_table Additional arguments #' @inheritSection DBItest::spec_sql_read_table Specification #' #' @inheritParams dbGetQuery #' @param name A character string specifying the unquoted DBMS table name, #' or the result of a call to [dbQuoteIdentifier()]. #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars[1:10, ]) #' dbReadTable(con, "mtcars") #' #' dbDisconnect(con) setGeneric("dbReadTable", def = function(conn, name, ...) standardGeneric("dbReadTable"), valueClass = "data.frame" ) #' @rdname hidden_aliases #' @export setMethod("dbReadTable", signature("DBIConnection", "character"), function(conn, name, ..., row.names = FALSE, check.names = TRUE) { sql_name <- dbQuoteIdentifier(conn, x = name, ...) if (length(sql_name) != 1L) { stop("Invalid name: ", format(name), call. = FALSE) } if (!is.null(row.names)) { stopifnot(length(row.names) == 1L) stopifnot(is.logical(row.names) || is.character(row.names)) } stopifnot(length(check.names) == 1L) stopifnot(is.logical(check.names)) stopifnot(!is.na(check.names)) out <- dbGetQuery(conn, paste0("SELECT * FROM ", sql_name)) out <- sqlColumnToRownames(out, row.names) if (check.names) { names(out) <- make.names(names(out), unique = TRUE) } out } ) #' @rdname hidden_aliases #' @export setMethod("dbReadTable", signature("DBIConnection", "Id"), function(conn, name, ...) { dbReadTable(conn, dbQuoteIdentifier(conn, name), ...) } ) #' Copy data frames to database tables #' #' Writes, overwrites or appends a data frame to a database table, optionally #' converting row names to a column and specifying SQL data types for fields. #' New code should prefer [dbCreateTable()] and [dbAppendTable()]. #' #' @template methods #' @templateVar method_name dbWriteTable #' #' @inherit DBItest::spec_sql_write_table return #' @inheritSection DBItest::spec_sql_write_table Additional arguments #' @inheritSection DBItest::spec_sql_write_table Specification #' #' @inheritParams dbGetQuery #' @inheritParams dbReadTable #' @param value a [data.frame] (or coercible to data.frame). #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbWriteTable(con, "mtcars", mtcars[1:5, ]) #' dbReadTable(con, "mtcars") #' #' dbWriteTable(con, "mtcars", mtcars[6:10, ], append = TRUE) #' dbReadTable(con, "mtcars") #' #' dbWriteTable(con, "mtcars", mtcars[1:10, ], overwrite = TRUE) #' dbReadTable(con, "mtcars") #' #' # No row names #' dbWriteTable(con, "mtcars", mtcars[1:10, ], overwrite = TRUE, row.names = FALSE) #' dbReadTable(con, "mtcars") #' #' @export setGeneric("dbWriteTable", def = function(conn, name, value, ...) standardGeneric("dbWriteTable") ) #' @rdname hidden_aliases #' @export setMethod("dbWriteTable", signature("DBIConnection", "Id", "ANY"), function(conn, name, value, ...) { dbWriteTable(conn, dbQuoteIdentifier(conn, name), value, ...) } ) #' Does a table exist? #' #' Returns if a table given by name exists in the database. #' #' @template methods #' @templateVar method_name dbExistsTable #' #' @inherit DBItest::spec_sql_exists_table return #' @inheritSection DBItest::spec_sql_exists_table Specification #' #' @inheritParams dbGetQuery #' @param name A character string specifying a DBMS table name. #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbExistsTable(con, "iris") #' dbWriteTable(con, "iris", iris) #' dbExistsTable(con, "iris") #' #' dbDisconnect(con) setGeneric("dbExistsTable", def = function(conn, name, ...) standardGeneric("dbExistsTable"), valueClass = "logical" ) #' @rdname hidden_aliases #' @export setMethod("dbExistsTable", signature("DBIConnection", "Id"), function(conn, name, ...) { dbExistsTable(conn, dbQuoteIdentifier(conn, name), ...) } ) #' Remove a table from the database #' #' Remove a remote table (e.g., created by [dbWriteTable()]) #' from the database. #' #' @template methods #' @templateVar method_name dbRemoveTable #' #' @inherit DBItest::spec_sql_remove_table return #' @inheritSection DBItest::spec_sql_remove_table Additional arguments #' @inheritSection DBItest::spec_sql_remove_table Specification #' #' @inheritParams dbGetQuery #' @param name A character string specifying a DBMS table name. #' @family DBIConnection generics #' @export #' @examples #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbExistsTable(con, "iris") #' dbWriteTable(con, "iris", iris) #' dbExistsTable(con, "iris") #' dbRemoveTable(con, "iris") #' dbExistsTable(con, "iris") #' #' dbDisconnect(con) setGeneric("dbRemoveTable", def = function(conn, name, ...) standardGeneric("dbRemoveTable") ) #' @rdname hidden_aliases #' @export setMethod("dbRemoveTable", signature("DBIConnection", "Id"), function(conn, name, ...) { dbRemoveTable(conn, dbQuoteIdentifier(conn, name), ...) } ) DBI/R/data-types.R0000644000176200001440000000255613550653013013260 0ustar liggesuserssetGeneric("dbiDataType", def = function(x, ...) standardGeneric("dbiDataType") ) data_frame_data_type <- function(x) { vapply(x, dbiDataType, FUN.VALUE = character(1), USE.NAMES = TRUE) } varchar_data_type <- function(x) { "TEXT" } list_data_type <- function(x) { check_raw_list(x) "BLOB" } check_raw_list <- function(x) { is_raw <- vapply(x, is.raw, logical(1)) if (!all(is_raw)) { stop("Only lists of raw vectors are currently supported", call. = FALSE) } } as_is_data_type <- function(x) { oldClass(x) <- oldClass(x)[-1] dbiDataType(x) } setOldClass("difftime") setOldClass("AsIs") setMethod("dbiDataType", signature("data.frame"), data_frame_data_type) setMethod("dbiDataType", signature("integer"), function(x) "INT") setMethod("dbiDataType", signature("numeric"), function(x) "DOUBLE") setMethod("dbiDataType", signature("logical"), function(x) "SMALLINT") setMethod("dbiDataType", signature("Date"), function(x) "DATE") setMethod("dbiDataType", signature("difftime"), function(x) "TIME") setMethod("dbiDataType", signature("POSIXct"), function(x) "TIMESTAMP") setMethod("dbiDataType", signature("character"), varchar_data_type) setMethod("dbiDataType", signature("factor"), varchar_data_type) setMethod("dbiDataType", signature("list"), list_data_type) setMethod("dbiDataType", signature("AsIs"), as_is_data_type) DBI/R/hidden.R0000644000176200001440000000033313550652132012430 0ustar liggesusers#' Internal page for hidden aliases #' #' For S4 methods that require a documentation entry but only clutter the index. #' #' @usage NULL #' @format NULL #' @keywords internal #' @docType methods hidden_aliases <- NULL DBI/R/DBConnector.R0000644000176200001440000000772513575266047013366 0ustar liggesusers#' @include hidden.R NULL #' DBIConnector class #' #' Wraps objects of the [DBIDriver-class] class to include connection options. #' The purpose of this class is to store both the driver #' and the connection options. #' A database connection can be established #' with a call to [dbConnect()], passing only that object #' without additional arguments. #' #' To prevent leakage of passwords and other credentials, #' this class supports delayed evaluation. #' All arguments can optionally be a function (callable without arguments). #' In such a case, the function is evaluated transparently when connecting in #' [dbGetConnectArgs()]. #' # FIXME: Include this # Database backends can take advantage of this feature by returning an # instance of this class instead of `DBIDriver`. # See the implementation of [RSQLite::SQLite()] for an example. #' #' @docType class #' @name DBIConnector-class #' @family DBI classes #' @family DBIConnector generics #' @export #' @include DBDriver.R #' @examples #' # Create a connector: #' cnr <- new("DBIConnector", #' .drv = RSQLite::SQLite(), #' .conn_args = list(dbname = ":memory:") #' ) #' cnr #' #' # Establish a connection through this connector: #' con <- dbConnect(cnr) #' con #' #' # Access the database through this connection: #' dbGetQuery(con, "SELECT 1 AS a") #' dbDisconnect(con) setClass("DBIConnector", slots = c(".drv" = "DBIDriver", ".conn_args" = "list"), contains = c("DBIObject") ) #' @rdname hidden_aliases #' @param object Object to display #' @export setMethod("show", signature("DBIConnector"), function(object) { cat("") show(object@.drv) cat("Arguments:\n") show(object@.conn_args) invisible(NULL) }) #' @rdname hidden_aliases #' @export setMethod("dbConnect", signature("DBIConnector"), function(drv, ...) { dots_args <- list(...) has_name <- names2(dots_args) != "" # Unnamed dots come first (they are not picked up by modifyList()) unnamed_dots <- dots_args[!has_name] # Named dots come last, an extra drv argument is erased silently named_dots <- dots_args[has_name] named_dots$drv <- NULL # Named dots are supplemented with connector args extra_args <- utils::modifyList( dbGetConnectArgs(drv), named_dots ) all_args <- c( list(drv = drv@.drv), unnamed_dots, extra_args ) do.call(dbConnect, all_args) } ) names2 <- function(x) { if (is.null(names(x))) { rep("", length(x)) } else { names(x) } } #' Get connection arguments #' #' Returns the arguments stored in a [DBIConnector-class] object for inspection, #' optionally evaluating them. #' This function is called by [dbConnect()] #' and usually does not need to be called directly. #' #' @template methods #' @templateVar method_name dbGetConnectArgs #' #' @param drv A object inheriting from [DBIConnector-class]. #' @param eval Set to `FALSE` to return the functions that generate the argument #' instead of evaluating them. #' @param ... Other arguments passed on to methods. Not otherwise used. #' @family DBIConnector generics #' @examples #' cnr <- new("DBIConnector", #' .drv = RSQLite::SQLite(), #' .conn_args = list(dbname = ":memory:", password = function() "supersecret") #' ) #' dbGetConnectArgs(cnr) #' dbGetConnectArgs(cnr, eval = FALSE) #' @export setGeneric("dbGetConnectArgs", def = function(drv, eval = TRUE, ...) standardGeneric("dbGetConnectArgs"), valueClass = "list" ) #' @rdname hidden_aliases #' @export setMethod("dbGetConnectArgs", signature("DBIConnector"), function(drv, eval = TRUE, ...) { conn_args <- drv@.conn_args if (isTRUE(eval)) { conn_args <- lapply(conn_args, function(x) { if (is.function(x)) x() else x }) } conn_args }) #' @rdname hidden_aliases #' @export setMethod("dbDataType", signature("DBIConnector"), function(dbObj, obj, ...) { dbDataType(dbObj@.drv, obj, ...) }) #' @rdname hidden_aliases setMethod("dbIsReadOnly", signature("DBIConnector"), function(dbObj, ...) { dbIsReadOnly(dbObj@.drv, ...) }) DBI/R/quote.R0000644000176200001440000002732013575266047012354 0ustar liggesusers#' @include hidden.R #' @include DBConnection.R NULL #' SQL quoting #' #' This set of classes and generics make it possible to flexibly deal with SQL #' escaping needs. By default, any user supplied input to a query should be #' escaped using either [dbQuoteIdentifier()] or [dbQuoteString()] #' depending on whether it refers to a table or variable name, or is a literal #' string. #' These functions may return an object of the `SQL` class, #' which tells DBI functions that a character string does not need to be escaped #' anymore, to prevent double escaping. #' The `SQL` class has associated the `SQL()` constructor function. #' #' @section Implementation notes: #' #' DBI provides default generics for SQL-92 compatible quoting. If the database #' uses a different convention, you will need to provide your own methods. #' Note that because of the way that S4 dispatch finds methods and because #' SQL inherits from character, if you implement (e.g.) a method for #' `dbQuoteString(MyConnection, character)`, you will also need to #' implement `dbQuoteString(MyConnection, SQL)` - this should simply #' return `x` unchanged. #' #' @param x A character vector to label as being escaped SQL. #' @param ... Other arguments passed on to methods. Not otherwise used. #' @param names Names for the returned object, must have the same length as `x`. #' @return An object of class `SQL`. #' @export #' @examples #' dbQuoteIdentifier(ANSI(), "SELECT") #' dbQuoteString(ANSI(), "SELECT") #' #' # SQL vectors are always passed through as is #' var_name <- SQL("SELECT") #' var_name #' #' dbQuoteIdentifier(ANSI(), var_name) #' dbQuoteString(ANSI(), var_name) #' #' # This mechanism is used to prevent double escaping #' dbQuoteString(ANSI(), dbQuoteString(ANSI(), "SELECT")) SQL <- function(x, ..., names = NULL) { if (!is.null(names)) { stopifnot(length(x) == length(names)) } names(x) <- names new("SQL", x) } #' @rdname SQL #' @export #' @aliases #' SQL-class setClass("SQL", contains = "character") #' @rdname hidden_aliases #' @export setMethod("show", "SQL", function(object) { cat(paste0(" ", object@.Data, collapse = "\n"), "\n", sep = "") }) #' @export `[.SQL` <- function(x, ...) SQL(NextMethod()) #' @export `[[.SQL` <- function(x, ...) SQL(NextMethod()) #' Quote identifiers #' #' Call this method to generate a string that is suitable for #' use in a query as a column or table name, to make sure that you #' generate valid SQL and protect against SQL injection attacks. The inverse #' operation is [dbUnquoteIdentifier()]. #' #' @inheritParams dbGetQuery #' @param x A character vector, [SQL] or [Id] object to quote as identifier. #' @param ... Other arguments passed on to methods. #' #' @template methods #' @templateVar method_name dbQuoteIdentifier #' #' @inherit DBItest::spec_sql_quote_identifier return #' @inheritSection DBItest::spec_sql_quote_identifier Specification #' #' @family DBIResult generics #' @export #' @examples #' # Quoting ensures that arbitrary input is safe for use in a query #' name <- "Robert'); DROP TABLE Students;--" #' dbQuoteIdentifier(ANSI(), name) #' #' # SQL vectors are always passed through as is #' var_name <- SQL("select") #' var_name #' #' dbQuoteIdentifier(ANSI(), var_name) #' #' # This mechanism is used to prevent double escaping #' dbQuoteIdentifier(ANSI(), dbQuoteIdentifier(ANSI(), name)) setGeneric("dbQuoteIdentifier", def = function(conn, x, ...) standardGeneric("dbQuoteIdentifier") ) quote_identifier <- function(conn, x, ...) { # Don't support lists, auto-vectorization violates type stability if (is(x, "SQL")) return(x) if (is(x, "Id")) { return(SQL(paste0(dbQuoteIdentifier(conn, x@name), collapse = "."))) } if (!is.character(x)) stop("x must be character or SQL", call. = FALSE) if (any(is.na(x))) { stop("Cannot pass NA to dbQuoteIdentifier()", call. = FALSE) } # Avoid fixed = TRUE due to https://github.com/r-dbi/DBItest/issues/156 x <- gsub('"', '""', enc2utf8(x)) if (length(x) == 0L) { SQL(character(), names = names(x)) } else { # Not calling encodeString() here to keep things simple SQL(paste('"', x, '"', sep = ""), names = names(x)) } } #' @rdname hidden_aliases #' @export setMethod("dbQuoteIdentifier", signature("DBIConnection"), quote_identifier) # Need to keep other method declarations around for now, because clients might # use getMethod(), see e.g. https://github.com/r-dbi/odbc/pull/149 #' @rdname hidden_aliases #' @export setMethod("dbQuoteIdentifier", signature("DBIConnection", "character"), quote_identifier) #' @rdname hidden_aliases #' @export setMethod("dbQuoteIdentifier", signature("DBIConnection", "SQL"), quote_identifier) #' @rdname hidden_aliases #' @export setMethod("dbQuoteIdentifier", signature("DBIConnection", "Id"), quote_identifier) #' Unquote identifiers #' #' Call this method to convert a [SQL] object created by [dbQuoteIdentifier()] #' back to a list of [Id] objects. #' #' @inheritParams dbGetQuery #' @param x An [SQL] or [Id] object. #' @param ... Other arguments passed on to methods. #' #' @template methods #' @templateVar method_name dbUnquoteIdentifier #' #' @inherit DBItest::spec_sql_unquote_identifier return #' @inheritSection DBItest::spec_sql_unquote_identifier Specification #' #' @family DBIResult generics #' @export #' @examples #' # Unquoting allows to understand the structure of a #' # possibly complex quoted identifier #' dbUnquoteIdentifier( #' ANSI(), #' SQL(c('"Catalog"."Schema"."Table"', '"Schema"."Table"', '"UnqualifiedTable"')) #' ) #' #' # The returned object is always a list, #' # also for Id objects #' dbUnquoteIdentifier( #' ANSI(), #' Id(catalog = "Catalog", schema = "Schema", table = "Table") #' ) #' #' # Quoting is the inverse operation to unquoting the elements #' # of the returned list #' dbQuoteIdentifier( #' ANSI(), #' dbUnquoteIdentifier(ANSI(), SQL("UnqualifiedTable"))[[1]] #' ) #' #' dbQuoteIdentifier( #' ANSI(), #' dbUnquoteIdentifier(ANSI(), Id(schema = "Schema", table = "Table"))[[1]] #' ) setGeneric("dbUnquoteIdentifier", def = function(conn, x, ...) standardGeneric("dbUnquoteIdentifier") ) #' @rdname hidden_aliases #' @export setMethod("dbUnquoteIdentifier", signature("DBIConnection"), function(conn, x, ...) { if (is(x, "SQL")) { id_rx <- '(?:"((?:[^"]|"")+)"|([^". ]+))' rx <- paste0( "^", "(?:|(?:|", id_rx, "[.])", id_rx, "[.])", "(?:|", id_rx, ")", "$" ) bad <- grep(rx, x, invert = TRUE) if (length(bad) > 0) { stop("Can't unquote ", x[bad[[1]]], call. = FALSE) } catalog <- gsub(rx, "\\1\\2", x) catalog <- gsub('""', '"', catalog) schema <- gsub(rx, "\\3\\4", x) schema <- gsub('""', '"', schema) table <- gsub(rx, "\\5\\6", x) table <- gsub('""', '"', table) ret <- Map(catalog, schema, table, f = as_table) names(ret) <- names(x) return(ret) } if (is(x, "Id")) { return(list(x)) } stop("x must be SQL or Id", call. = FALSE) }) as_table <- function(catalog, schema, table) { args <- c(catalog = catalog, schema = schema, table = table) # Also omits NA args args <- args[!is.na(args) & args != ""] do.call(Id, as.list(args)) } #' Quote literal strings #' #' Call this method to generate a string that is suitable for #' use in a query as a string literal, to make sure that you #' generate valid SQL and protect against SQL injection attacks. #' #' @inheritParams dbGetQuery #' @param x A character vector to quote as string. #' @param ... Other arguments passed on to methods. #' #' @template methods #' @templateVar method_name dbQuoteString #' #' @inherit DBItest::spec_sql_quote_string return #' @inheritSection DBItest::spec_sql_quote_string Specification #' #' @family DBIResult generics #' @export #' @examples #' # Quoting ensures that arbitrary input is safe for use in a query #' name <- "Robert'); DROP TABLE Students;--" #' dbQuoteString(ANSI(), name) #' #' # NAs become NULL #' dbQuoteString(ANSI(), c("x", NA)) #' #' # SQL vectors are always passed through as is #' var_name <- SQL("select") #' var_name #' dbQuoteString(ANSI(), var_name) #' #' # This mechanism is used to prevent double escaping #' dbQuoteString(ANSI(), dbQuoteString(ANSI(), name)) setGeneric("dbQuoteString", def = function(conn, x, ...) standardGeneric("dbQuoteString") ) quote_string <- function(conn, x, ...) { if (is(x, "SQL")) return(x) if (!is.character(x)) stop("x must be character or SQL", call. = FALSE) # Avoid fixed = TRUE due to https://github.com/r-dbi/DBItest/issues/156 x <- gsub("'", "''", enc2utf8(x)) if (length(x) == 0L) { SQL(character()) } else { # Not calling encodeString() here, see also http://stackoverflow.com/a/549244/946850 # and especially the comment by Álvaro González str <- paste("'", x, "'", sep = "") str[is.na(x)] <- "NULL" SQL(str) } } # Need to keep other method declarations around for now, because clients might # use getMethod(), see e.g. https://github.com/r-dbi/odbc/pull/149 #' @rdname hidden_aliases #' @export setMethod("dbQuoteString", signature("DBIConnection"), quote_string) #' @rdname hidden_aliases #' @export setMethod("dbQuoteString", signature("DBIConnection", "character"), quote_string) #' @rdname hidden_aliases #' @export setMethod("dbQuoteString", signature("DBIConnection", "SQL"), quote_string) #' Quote literal values #' #' @description #' Call these methods to generate a string that is suitable for #' use in a query as a literal value of the correct type, to make sure that you #' generate valid SQL and protect against SQL injection attacks. #' #' @inheritParams dbQuoteString #' @param x A vector to quote as string. #' #' @template methods #' @templateVar method_name dbQuoteLiteral #' #' @inherit DBItest::spec_sql_quote_literal return #' @inheritSection DBItest::spec_sql_quote_literal Specification #' #' @family DBIResult generics #' @export #' @examples #' # Quoting ensures that arbitrary input is safe for use in a query #' name <- "Robert'); DROP TABLE Students;--" #' dbQuoteLiteral(ANSI(), name) #' #' # NAs become NULL #' dbQuoteLiteral(ANSI(), c(1:3, NA)) #' #' # Logicals become integers by default #' dbQuoteLiteral(ANSI(), c(TRUE, FALSE, NA)) #' #' # Raw vectors become hex strings by default #' dbQuoteLiteral(ANSI(), list(as.raw(1:3), NULL)) #' #' # SQL vectors are always passed through as is #' var_name <- SQL("select") #' var_name #' dbQuoteLiteral(ANSI(), var_name) #' #' # This mechanism is used to prevent double escaping #' dbQuoteLiteral(ANSI(), dbQuoteLiteral(ANSI(), name)) setGeneric("dbQuoteLiteral", def = function(conn, x, ...) standardGeneric("dbQuoteLiteral") ) #' @rdname hidden_aliases #' @export setMethod("dbQuoteLiteral", signature("DBIConnection"), function(conn, x, ...) { # Switchpatching to avoid ambiguous S4 dispatch, so that our method # is used only if no alternatives are available. if (is(x, "SQL")) return(x) if (is.factor(x)) return(dbQuoteString(conn, as.character(x))) if (is.character(x)) return(dbQuoteString(conn, x)) if (inherits(x, "POSIXt")) { return(dbQuoteString( conn, strftime(as.POSIXct(x), "%Y%m%d%H%M%S", tz = "UTC") )) } if (inherits(x, "Date")) return(dbQuoteString(conn, as.character(x, usetz = TRUE))) if (is.list(x)) { blob_data <- vapply( x, function(x) { if (is.null(x)) { "NULL" } else if (is.raw(x)) { paste0("X'", paste(format(x), collapse = ""), "'") } else { stop("Lists must contain raw vectors or NULL", call. = FALSE) } }, character(1) ) return(SQL(blob_data, names = names(x))) } if (is.logical(x)) x <- as.numeric(x) x <- as.character(x) x[is.na(x)] <- "NULL" SQL(x, names = names(x)) } ) DBI/R/DBDriver.R0000644000176200001440000002310513575266047012655 0ustar liggesusers#' @include hidden.R NULL #' DBIDriver class #' #' Base class for all DBMS drivers (e.g., RSQLite, MySQL, PostgreSQL). #' The virtual class `DBIDriver` defines the operations for creating #' connections and defining data type mappings. Actual driver classes, for #' instance `RPostgres`, `RMariaDB`, etc. implement these operations in a #' DBMS-specific manner. #' #' @docType class #' @name DBIDriver-class #' @family DBI classes #' @family DBIDriver generics #' @export #' @include DBObject.R setClass("DBIDriver", contains = c("DBIObject", "VIRTUAL")) #' Load and unload database drivers #' #' @description #' These methods are deprecated, please consult the documentation of the #' individual backends for the construction of driver instances. #' #' `dbDriver()` is a helper method used to create an new driver object #' given the name of a database or the corresponding R package. It works #' through convention: all DBI-extending packages should provide an exported #' object with the same name as the package. `dbDriver()` just looks for #' this object in the right places: if you know what database you are connecting #' to, you should call the function directly. #' #' @details #' The client part of the database communication is #' initialized (typically dynamically loading C code, etc.) but note that #' connecting to the database engine itself needs to be done through calls to #' `dbConnect`. #' #' @param drvName character name of the driver to instantiate. #' @param drv an object that inherits from `DBIDriver` as created by #' `dbDriver`. #' @param ... any other arguments are passed to the driver `drvName`. #' @return In the case of `dbDriver`, an driver object whose class extends #' `DBIDriver`. This object may be used to create connections to the #' actual DBMS engine. #' #' In the case of `dbUnloadDriver`, a logical indicating whether the #' operation succeeded or not. #' @import methods #' @family DBIDriver generics #' @export #' @keywords internal #' @examples #' # Create a RSQLite driver with a string #' d <- dbDriver("SQLite") #' d #' #' # But better, access the object directly #' RSQLite::SQLite() setGeneric("dbDriver", def = function(drvName, ...) standardGeneric("dbDriver"), valueClass = "DBIDriver" ) #' @rdname hidden_aliases setMethod("dbDriver", signature("character"), definition = function(drvName, ...) { findDriver(drvName)(...) } ) #' @rdname hidden_aliases #' @param object Object to display #' @export setMethod("show", signature("DBIDriver"), function(object) { tryCatch( # to protect drivers that fail to implement the required methods (e.g., # RPostgreSQL) show_driver(object), error = function(e) NULL ) invisible(NULL) }) show_driver <- function(object) { cat("<", is(object)[1], ">\n", sep = "") } findDriver <- function(drvName) { # If it exists in the global environment, use that d <- get2(drvName, globalenv()) if (!is.null(d)) return(d) # Otherwise, see if the appropriately named package is available if (is_attached(drvName)) { d <- get2(drvName, asNamespace(drvName)) if (!is.null(d)) return(d) } pkgName <- paste0("R", drvName) # First, see if package with name R + drvName is available if (is_attached(pkgName)) { d <- get2(drvName, asNamespace(pkgName)) if (!is.null(d)) return(d) } # Can't find it: stop( "Couldn't find driver ", drvName, ". Looked in:\n", "* global namespace\n", "* in package called ", drvName, "\n", "* in package called ", pkgName, call. = FALSE ) } get2 <- function(x, env) { if (!exists(x, envir = env)) return(NULL) get(x, envir = env) } is_attached <- function(x) { x %in% loadedNamespaces() } #' @description #' `dbUnloadDriver()` is not implemented for modern backends. #' @rdname dbDriver #' @family DBIDriver generics #' @export setGeneric("dbUnloadDriver", def = function(drv, ...) standardGeneric("dbUnloadDriver") ) #' Create a connection to a DBMS #' #' Connect to a DBMS going through the appropriate authentication procedure. #' Some implementations may allow you to have multiple connections open, so you #' may invoke this function repeatedly assigning its output to different #' objects. #' The authentication mechanism is left unspecified, so check the #' documentation of individual drivers for details. #' Use [dbCanConnect()] to check if a connection can be established. #' #' @template methods #' @templateVar method_name dbConnect #' #' @inherit DBItest::spec_driver_connect return #' @inheritSection DBItest::spec_driver_connect Specification #' #' @param drv an object that inherits from [DBIDriver-class], #' or an existing [DBIConnection-class] #' object (in order to clone an existing connection). #' @param ... authentication arguments needed by the DBMS instance; these #' typically include `user`, `password`, `host`, `port`, `dbname`, etc. #' For details see the appropriate `DBIDriver`. #' @seealso [dbDisconnect()] to disconnect from a database. #' @family DBIDriver generics #' @family DBIConnector generics #' @export #' @examples #' # SQLite only needs a path to the database. (Here, ":memory:" is a special #' # path that creates an in-memory database.) Other database drivers #' # will require more details (like user, password, host, port, etc.) #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' con #' #' dbListTables(con) #' #' dbDisconnect(con) setGeneric("dbConnect", def = function(drv, ...) standardGeneric("dbConnect"), valueClass = "DBIConnection" ) #' Check if a connection to a DBMS can be established #' #' Like [dbConnect()], but only checks validity without actually returning #' a connection object. The default implementation opens a connection #' and disconnects on success, but individual backends might implement #' a lighter-weight check. #' #' @template methods #' @templateVar method_name dbCanConnect #' #' @return A scalar logical. If `FALSE`, the `"reason"` attribute indicates #' a reason for failure. #' #' @inheritParams dbConnect #' @family DBIDriver generics #' @export #' @examples #' # SQLite only needs a path to the database. (Here, ":memory:" is a special #' # path that creates an in-memory database.) Other database drivers #' # will require more details (like user, password, host, port, etc.) #' dbCanConnect(RSQLite::SQLite(), ":memory:") setGeneric("dbCanConnect", def = function(drv, ...) standardGeneric("dbCanConnect"), valueClass = "logical" ) #' @rdname hidden_aliases #' @export setMethod("dbCanConnect", signature("DBIDriver"), function(drv, ...) { tryCatch( { con <- dbConnect(drv, ...) dbDisconnect(con) TRUE }, error = function(e) { structure( FALSE, reason = conditionMessage(e) ) } ) }) #' List currently open connections #' #' DEPRECATED, drivers are no longer required to implement this method. #' Keep track of the connections you opened if you require a list. #' #' @param drv A object inheriting from [DBIDriver-class] #' @param ... Other arguments passed on to methods. #' @family DBIDriver generics #' @keywords internal #' @export #' @return a list setGeneric("dbListConnections", def = function(drv, ...) standardGeneric("dbListConnections") ) #' Determine the SQL data type of an object #' #' Returns an SQL string that describes the SQL data type to be used for an #' object. #' The default implementation of this generic determines the SQL type of an #' R object according to the SQL 92 specification, which may serve as a starting #' point for driver implementations. DBI also provides an implementation #' for data.frame which will return a character vector giving the type for each #' column in the dataframe. #' #' The data types supported by databases are different than the data types in R, #' but the mapping between the primitive types is straightforward: #' - Any of the many fixed and varying length character types are mapped to #' character vectors #' - Fixed-precision (non-IEEE) numbers are mapped into either numeric or #' integer vectors. #' #' Notice that many DBMS do not follow IEEE arithmetic, so there are potential #' problems with under/overflows and loss of precision. #' #' @template methods #' @templateVar method_name dbDataType #' #' @inherit DBItest::spec_driver_data_type return #' @inheritSection DBItest::spec_driver_data_type Specification #' @inheritSection DBItest::spec_result_create_table_with_data_type Specification #' #' @inheritParams dbListConnections #' @param dbObj A object inheriting from [DBIDriver-class] #' or [DBIConnection-class] #' @param obj An R object whose SQL type we want to determine. #' @family DBIDriver generics #' @family DBIConnection generics #' @family DBIConnector generics #' @examples #' dbDataType(ANSI(), 1:5) #' dbDataType(ANSI(), 1) #' dbDataType(ANSI(), TRUE) #' dbDataType(ANSI(), Sys.Date()) #' dbDataType(ANSI(), Sys.time()) #' dbDataType(ANSI(), Sys.time() - as.POSIXct(Sys.Date())) #' dbDataType(ANSI(), c("x", "abc")) #' dbDataType(ANSI(), list(raw(10), raw(20))) #' dbDataType(ANSI(), I(3)) #' #' dbDataType(ANSI(), iris) #' #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' #' dbDataType(con, 1:5) #' dbDataType(con, 1) #' dbDataType(con, TRUE) #' dbDataType(con, Sys.Date()) #' dbDataType(con, Sys.time()) #' dbDataType(con, Sys.time() - as.POSIXct(Sys.Date())) #' dbDataType(con, c("x", "abc")) #' dbDataType(con, list(raw(10), raw(20))) #' dbDataType(con, I(3)) #' #' dbDataType(con, iris) #' #' dbDisconnect(con) #' @export setGeneric("dbDataType", def = function(dbObj, obj, ...) standardGeneric("dbDataType"), valueClass = "character" ) #' @rdname hidden_aliases #' @export setMethod("dbDataType", signature("DBIObject"), function(dbObj, obj, ...) { dbiDataType(obj) }) DBI/R/DBObject.R0000644000176200001440000000666513575266047012644 0ustar liggesusers#' @include hidden.R NULL #' DBIObject class #' #' Base class for all other DBI classes (e.g., drivers, connections). This #' is a virtual Class: No objects may be created from it. #' #' More generally, the DBI defines a very small set of classes and generics that #' allows users and applications access DBMS with a common interface. The #' virtual classes are `DBIDriver` that individual drivers extend, #' `DBIConnection` that represent instances of DBMS connections, and #' `DBIResult` that represent the result of a DBMS statement. These three #' classes extend the basic class of `DBIObject`, which serves as the root #' or parent of the class hierarchy. #' #' @section Implementation notes: #' An implementation MUST provide methods for the following generics: #' #' \itemize{ #' \item [dbGetInfo()]. #' } #' #' It MAY also provide methods for: #' #' \itemize{ #' \item [summary()]. Print a concise description of the #' object. The default method invokes `dbGetInfo(dbObj)` and prints #' the name-value pairs one per line. Individual implementations may #' tailor this appropriately. #' } #' #' @docType class #' @family DBI classes #' @examples #' drv <- RSQLite::SQLite() #' con <- dbConnect(drv) #' #' rs <- dbSendQuery(con, "SELECT 1") #' is(drv, "DBIObject") ## True #' is(con, "DBIObject") ## True #' is(rs, "DBIObject") #' #' dbClearResult(rs) #' dbDisconnect(con) #' @export #' @name DBIObject-class setClass("DBIObject", "VIRTUAL") #' Get DBMS metadata #' #' Retrieves information on objects of class [DBIDriver-class], #' [DBIConnection-class] or [DBIResult-class]. #' #' @param dbObj An object inheriting from [DBIObject-class], #' i.e. [DBIDriver-class], [DBIConnection-class], #' or a [DBIResult-class] #' @param ... Other arguments to methods. #' @family DBIDriver generics #' @family DBIConnection generics #' @family DBIResult generics #' @inherit DBItest::spec_get_info return #' @export setGeneric("dbGetInfo", def = function(dbObj, ...) standardGeneric("dbGetInfo") ) #' Is this DBMS object still valid? #' #' This generic tests whether a database object is still valid (i.e. it hasn't #' been disconnected or cleared). #' #' @template methods #' @templateVar method_name dbIsValid #' #' @inherit DBItest::spec_meta_is_valid return #' #' @inheritParams dbGetInfo #' @family DBIDriver generics #' @family DBIConnection generics #' @family DBIResult generics #' @export #' @examples #' dbIsValid(RSQLite::SQLite()) #' #' con <- dbConnect(RSQLite::SQLite(), ":memory:") #' dbIsValid(con) #' #' rs <- dbSendQuery(con, "SELECT 1") #' dbIsValid(rs) #' #' dbClearResult(rs) #' dbIsValid(rs) #' #' dbDisconnect(con) #' dbIsValid(con) setGeneric("dbIsValid", def = function(dbObj, ...) standardGeneric("dbIsValid"), valueClass = "logical" ) #' Is this DBMS object read only? #' #' This generic tests whether a database object is read only. #' #' @inheritParams dbGetInfo #' @family DBIDriver generics #' @family DBIConnection generics #' @family DBIResult generics #' @family DBIConnector generics #' @export #' @examples #' dbIsReadOnly(ANSI()) setGeneric("dbIsReadOnly", def = function(dbObj, ...) standardGeneric("dbIsReadOnly"), valueClass = "logical") #' @rdname hidden_aliases setMethod("dbIsReadOnly", "DBIObject", function(dbObj, ...) { FALSE }) setGeneric("summary") setMethod("summary", "DBIObject", function(object, ...) { info <- dbGetInfo(dbObj = object, ...) cat(class(object), "\n") print_list_pairs(info) invisible(info) }) DBI/NEWS.md0000644000176200001440000004061413575275076011774 0ustar liggesusers# DBI 1.1.0 ## New features - New `DBIConnector` class (#280). - Specify `immediate` argument to `dbSendQuery()`, `dbGetQuery()`, `dbSendStatement()` and `dbExecute()` (#268). - Use specification for `dbGetInfo()` (#271). - `dbUnquoteIdentifier()` now supports `Id()` objects with `catalog` members (#266, @raffscallion). It also handles unquoted identifiers of the form `table`, `schema.table` or `catalog.schema.table`, for compatibility with dbplyr. ## Documentation - New DBI intro article (#286, @cutterkom). - Add pkgdown reference index (#288). - DBI specification on https://dbi.r-dbi.org/dev/articles/spec now comes with a table of contents and code formatting. - Update examples to refer to `params` instead of `param` (#235). - Improved documentation for `sqlInterpolate()` (#100). Add usage of `SQL()` to `sqlInterpolate()` examples (#259, @renkun-ken). - Improve documentation for `Id`. ## Internal - Add tests for `dbUnquoteIdentifier()` (#279, @baileych). - `sqlInterpolate()` uses `dbQuoteLiteral()` instead of checking the type of the input. - Avoid partial argument match in `dbWriteTable()` (#246, @richfitz). # DBI 1.0.0 (2018-05-02) ## New generics - New `dbAppendTable()` that by default calls `sqlAppendTableTemplate()` and then `dbExecute()` with a `param` argument, without support for `row.names` argument (#74). - New `dbCreateTable()` that by default calls `sqlCreateTable()` and then `dbExecute()`, without support for `row.names` argument (#74). - New `dbCanConnect()` generic with default implementation (#87). - New `dbIsReadOnly()` generic with default implementation (#190, @anhqle). ## Changes - `sqlAppendTable()` now accepts lists for the `values` argument, to support lists of `SQL` objects in R 3.1. - Add default implementation for `dbListFields(DBIConnection, Id)`, this relies on `dbQuoteIdentifier(DBIConnection, Id)` (#75). ## Documentation updates - The DBI specification vignette is rendered correctly from the installed package (#234). - Update docs on how to cope with stored procedures (#242, @aryoda). - Add "Additional arguments" sections and more examples for `dbGetQuery()`, `dbSendQuery()`, `dbExecute()` and `dbSendStatement()`. - The `dbColumnInfo()` method is now fully specified (#75). - The `dbListFields()` method is now fully specified (#75). - The dynamic list of methods in help pages doesn't contain methods in DBI anymore. ## Bug fixes - Pass missing `value` argument to secondary `dbWriteTable()` call (#737, @jimhester). - The `Id` class now uses `` and not `` when printing. - The default `dbUnquoteIdentifier()` implementation now complies to the spec. # DBI 0.8 (2018-02-24) Breaking changes ---------------- - `SQL()` now strips the names from the output if the `names` argument is unset. - The `dbReadTable()`, `dbWriteTable()`, `dbExistsTable()`, `dbRemoveTable()`, and `dbListFields()` generics now specialize over the first two arguments to support implementations with the `Id` S4 class as type for the second argument. Some packages may need to update their documentation to satisfy R CMD check again. New generics ------------ - Schema support: Export `Id()`, new generics `dbListObjects()` and `dbUnquoteIdentifier()`, methods for `Id` that call `dbQuoteIdentifier()` and then forward (#220). - New `dbQuoteLiteral()` generic. The default implementation uses switchpatch to avoid dispatch ambiguities, and forwards to `dbQuoteString()` for character vectors. Backends may override methods that also dispatch on the second argument, but in this case also an override for the `"SQL"` class is necessary (#172). Default implementations ----------------------- - Default implementations of `dbQuoteIdentifier()` and `dbQuoteLiteral()` preserve names, default implementation of `dbQuoteString()` strips names (#173). - Specialized methods for `dbQuoteString()` and `dbQuoteIdentifier()` are available again, for compatibility with clients that use `getMethod()` to access them (#218). - Add default implementation of `dbListFields()`. - The default implementation of `dbReadTable()` now has `row.names = FALSE` as default and also supports `row.names = NULL` (#186). API changes ----------- - The `SQL()` function gains an optional `names` argument which can be used to assign names to SQL strings. Deprecated generics ------------------- - `dbListConnections()` is soft-deprecated by documentation. - `dbListResults()` is deprecated by documentation (#58). - `dbGetException()` is soft-deprecated by documentation (#51). - The deprecated `print.list.pairs()` has been removed. Bug fixes --------- - Fix `dbDataType()` for `AsIs` object (#198, @yutannihilation). - Fix `dbQuoteString()` and `dbQuoteIdentifier()` to ignore invalid UTF-8 strings (r-dbi/DBItest#156). Documentation ------------- - Help pages for generics now contain a dynamic list of methods implemented by DBI backends (#162). - `sqlInterpolate()` now supports both named and positional variables (#216, @hannesmuehleisen). - Point to db.rstudio.com (@wibeasley, #209). - Reflect new 'r-dbi' organization in `DESCRIPTION` (@wibeasley, #207). Internal -------- - Using switchpatch on the second argument for default implementations of `dbQuoteString()` and `dbQuoteIdentifier()`. # DBI 0.7 (2017-06-17) - Import updated specs from `DBItest`. - The default implementation of `dbGetQuery()` now accepts an `n` argument and forwards it to `dbFetch()`. No warning about pending rows is issued anymore (#76). - Require R >= 3.0.0 (for `slots` argument of `setClass()`) (#169, @mvkorpel). # DBI 0.6-1 (2017-04-01) - Fix `dbReadTable()` for backends that do not provide their own implementation (#171). # DBI 0.6 (2017-03-08) - Interface changes - Deprecated `dbDriver()` and `dbUnloadDriver()` by documentation (#21). - Renamed arguments to `sqlInterpolate()` and `sqlParseVariables()` to be more consistent with the rest of the interface, and added `.dots` argument to `sqlParseVariables`. DBI drivers are now expected to implement `sqlParseVariables(conn, sql, ..., .dots)` and `sqlInterpolate(conn, sql, ...)` (#147). - Interface enhancements - Removed `valueClass = "logical"` for those generics where the return value is meaningless, to allow backends to return invisibly (#135). - Avoiding using braces in the definitions of generics if possible, so that standard generics can be detected (#146). - Added default implementation for `dbReadTable()`. - All standard generics are required to have an ellipsis (with test), for future extensibility. - Improved default implementation of `dbQuoteString()` and `dbQuoteIdentifier()` (#77). - Removed `tryCatch()` call in `dbGetQuery()` (#113). - Documentation improvements - Finalized first draft of DBI specification, now in a vignette. - Most methods now draw documentation from `DBItest`, only those where the behavior is not finally decided don't do this yet yet. - Removed `max.connections` requirement from documentation (#56). - Improved `dbBind()` documentation and example (#136). - Change `omegahat.org` URL to `omegahat.net`, the particular document still doesn't exist below the new domain. - Internal - Use roxygen2 inheritance to copy DBI specification to this package. - Use `tic` package for building documentation. - Use markdown in documentation. # DBI 0.5-1 (2016-09-09) - Documentation and example updates. # DBI 0.5 (2016-08-11, CRAN release) - Interface changes - `dbDataType()` maps `character` values to `"TEXT"` by default (#102). - The default implementation of `dbQuoteString()` doesn't call `encodeString()` anymore: Neither SQLite nor Postgres understand e.g. `\n` in a string literal, and all of SQLite, Postgres, and MySQL accept an embedded newline (#121). - Interface enhancements - New `dbSendStatement()` generic, forwards to `dbSendQuery()` by default (#20, #132). - New `dbExecute()`, calls `dbSendStatement()` by default (#109, @bborgesr). - New `dbWithTransaction()` that calls `dbBegin()` and `dbCommit()`, and `dbRollback()` on failure (#110, @bborgesr). - New `dbBreak()` function which allows aborting from within `dbWithTransaction()` (#115, #133). - Export `dbFetch()` and `dbQuoteString()` methods. - Documentation improvements: - One example per function (except functions scheduled for deprecation) (#67). - Consistent layout and identifier naming. - Better documentation of generics by adding links to the class and related generics in the "See also" section under "Other DBI... generics" (#130). S4 documentation is directed to a hidden page to unclutter documentation index (#59). - Fix two minor vignette typos (#124, @mdsumner). - Add package documentation. - Remove misleading parts in `dbConnect()` documentation (#118). - Remove misleading link in `dbDataType()` documentation. - Remove full stop from documentation titles. - New help topic "DBIspec" that contains the full DBI specification (currently work in progress) (#129). - HTML documentation generated by `staticdocs` is now uploaded to http://rstats-db.github.io/DBI for each build of the "production" branch (#131). - Further minor changes and fixes. - Internal - Use `contains` argument instead of `representation()` to denote base classes (#93). - Remove redundant declaration of transaction methods (#110, @bborgesr). # DBI 0.4-1 (2016-05-07, CRAN release) - The default `show()` implementations silently ignore all errors. Some DBI drivers (e.g., RPostgreSQL) might fail to implement `dbIsValid()` or the other methods used. # DBI 0.4 (2016-04-30) * New package maintainer: Kirill Müller. * `dbGetInfo()` gains a default method that extracts the information from `dbGetStatement()`, `dbGetRowsAffected()`, `dbHasCompleted()`, and `dbGetRowCount()`. This means that most drivers should no longer need to implement `dbGetInfo()` (which may be deprecated anyway at some point) (#55). * `dbDataType()` and `dbQuoteString()` are now properly exported. * The default implementation for `dbDataType()` (powered by `dbiDataType()`) now also supports `difftime` and `AsIs` objects and lists of `raw` (#70). * Default `dbGetQuery()` method now always calls `dbFetch()`, in a `tryCatch()` block. * New generic `dbBind()` for binding values to a parameterised query. * DBI gains a number of SQL generation functions. These make it easier to write backends by implementing common operations that are slightly tricky to do absolutely correctly. * `sqlCreateTable()` and `sqlAppendTable()` create tables from a data frame and insert rows into an existing table. These will power most implementations of `dbWriteTable()`. `sqlAppendTable()` is useful for databases that support parameterised queries. * `sqlRownamesToColumn()` and `sqlColumnToRownames()` provide a standard way of translating row names to and from the database. * `sqlInterpolate()` and `sqlParseVariables()` allows databases without native parameterised queries to use parameterised queries to avoid SQL injection attacks. * `sqlData()` is a new generic that converts a data frame into a data frame suitable for sending to the database. This is used to (e.g.) ensure all character vectors are encoded as UTF-8, or to convert R varible types (like factor) to types supported by the database. * The `sqlParseVariablesImpl()` is now implemented purely in R, with full test coverage (#83, @hannesmuehleisen). * `dbiCheckCompliance()` has been removed, the functionality is now available in the `DBItest` package (#80). * Added default `show()` methods for driver, connection and results. * New concrete `ANSIConnection` class and `ANSI()` function to generate a dummy ANSI compliant connection useful for testing. * Default `dbQuoteString()` and `dbQuoteIdentifer()` methods now use `encodeString()` so that special characters like `\n` are correctly escaped. `dbQuoteString()` converts `NA` to (unquoted) NULL. * The initial DBI proposal and DBI version 1 specification are now included as a vignette. These are there mostly for historical interest. * The new `DBItest` package is described in the vignette. * Deprecated `print.list.pairs()`. * Removed unused `dbi_dep()`. # Version 0.3.1 * Actually export `dbIsValid()` :/ * `dbGetQuery()` uses `dbFetch()` in the default implementation. # Version 0.3.0 ## New and enhanced generics * `dbIsValid()` returns a logical value describing whether a connection or result set (or other object) is still valid. (#12). * `dbQuoteString()` and `dbQuoteIdentifier()` to implement database specific quoting mechanisms. * `dbFetch()` added as alias to `fetch()` to provide consistent name. Implementers should define methods for both `fetch()` and `dbFetch()` until `fetch()` is deprecated in 2015. For now, the default method for `dbFetch()` calls `fetch()`. * `dbBegin()` begins a transaction (#17). If not supported, DB specific methods should throw an error (as should `dbCommit()` and `dbRollback()`). ## New default methods * `dbGetStatement()`, `dbGetRowsAffected()`, `dbHasCompleted()`, and `dbGetRowCount()` gain default methods that extract the appropriate elements from `dbGetInfo()`. This means that most drivers should no longer need to implement these methods (#13). * `dbGetQuery()` gains a default method for `DBIConnection` which uses `dbSendQuery()`, `fetch()` and `dbClearResult()`. ## Deprecated features * The following functions are soft-deprecated. They are going away, and developers who use the DBI should begin preparing. The formal deprecation process will begin in July 2015, where these function will emit warnings on use. * `fetch()` is replaced by `dbFetch()`. * `make.db.names()`, `isSQLKeyword()` and `SQLKeywords()`: a black list based approach is fundamentally flawed; instead quote strings and identifiers with `dbQuoteIdentifier()` and `dbQuoteString()`. * `dbGetDBIVersion()` is deprecated since it's now just a thin wrapper around `packageVersion("DBI")`. * `dbSetDataMappings()` (#9) and `dbCallProc()` (#7) are deprecated as no implementations were ever provided. ## Other improvements * `dbiCheckCompliance()` makes it easier for implementors to check that their package is in compliance with the DBI specification. * All examples now use the RSQLite package so that you can easily try out the code samples (#4). * `dbDriver()` gains a more effective search mechanism that doesn't rely on packages being loaded (#1). * DBI has been converted to use roxygen2 for documentation, and now most functions have their own documentation files. I would love your feedback on how we could make the documentation better! # Version 0.2-7 * Trivial changes (updated package fields, daj) # Version 0.2-6 * Removed deprecated \synopsis in some Rd files (thanks to Prof. Ripley) # Version 0.2-5 * Code cleanups contributed by Matthias Burger: avoid partial argument name matching and use TRUE/FALSE, not T/F. * Change behavior of make.db.names.default to quote SQL keywords if allow.keywords is FALSE. Previously, SQL keywords would be name mangled with underscores and a digit. Now they are quoted using '"'. # Version 0.2-4 * Changed license from GPL to LPGL * Fixed a trivial typo in documentation # Version 0.1-10 * Fixed documentation typos. # Version 0.1-9 * Trivial changes. # Version 0.1-8 * A trivial change due to package.description() being deprecated in 1.9.0. # Version 0.1-7 * Had to do a substantial re-formatting of the documentation due to incompatibilities introduced in 1.8.0 S4 method documentation. The contents were not changed (modulo fixing a few typos). Thanks to Kurt Hornik and John Chambers for their help. # Version 0.1-6 * Trivial documentation changes (for R CMD check's sake) # Version 0.1-5 * Removed duplicated setGeneric("dbSetDataMappings") # Version 0.1-4 * Removed the "valueClass" from some generic functions, namely, dbListConnections, dbListResults, dbGetException, dbGetQuery, and dbGetInfo. The reason is that methods for these generics could potentially return different classes of objects (e.g., the call dbGetInfo(res) could return a list of name-value pairs, while dbGetInfo(res, "statement") could be a character vector). * Added 00Index to inst/doc * Added dbGetDBIVersion() (simple wrapper to package.description). # Version 0.1-3 * ??? Minor changes? # Version 0.1-2 * An implementation based on version 4 classes and methods. * Incorporated (mostly Tim Keitt's) comments. DBI/MD50000644000176200001440000001417513575400712011174 0ustar liggesusers64718d0b197eb0261b81a89340eec094 *DESCRIPTION 6ff765dc8e0e65b47031bdff02969b04 *NAMESPACE b12c60d33bdc1b88d98df3af3c80dca3 *NEWS.md ad3465328a15b041adf2793563ab965e *R/ANSI.R 2c4ebab19c96cb56407c63c33e2720aa *R/DBConnection.R abfe2db6166441801b3b3d31247ce29e *R/DBConnector.R 1fb1a0eb1bc6ac9c1420ad65e1d70414 *R/DBDriver.R 457c8422b7fcb9172f307c3b9794116a *R/DBI-package.R fc74463a26bade06faaf5df398eb5e19 *R/DBObject.R 98fbf4a6e7cf7f0d50ad1fc36ab6e727 *R/DBResult.R 2fd78e2475713854b489a8d6ff51f8ba *R/data-types.R 7235ef4ac2c64b927b6d353bb98adf60 *R/data.R 2aea7480d7f66d5684fd3ad40affa497 *R/deprecated.R 3eedf8c52b5d232851009a9c9cef14f9 *R/hidden.R 67791a0515899f17546c1f451a25ab75 *R/interpolate.R ea5100994bf62e79c9134e99fe8c4865 *R/list-pairs.R 1358b1888794597f2f785c44eb2c655e *R/quote.R 0e73095a9a1792df2f068b63e1753a26 *R/rd.R ef367483cb2eb34b90a0a945531d2dfe *R/rownames.R 8665475ab17795ac363cb2a5c1b77974 *R/table-create.R f769ed3fa029780798abd8e563c840bd *R/table-insert.R c65eef36ad546b9e77bc67703f1993c7 *R/table.R 68be46429f97f4244aef4bd4190ac2fa *R/transactions.R 3aff3aa2278150c26679cde6073e4036 *README.md 3141a411d32dfd7c48b0d70cb4a9e386 *build/DBI.pdf 510b55af317ca59e24b6b79fcd223066 *build/vignette.rds 2a9b8778d24d15329d70d85d014c4054 *inst/doc/DBI-1.Rmd 48067d60bec280239e2200d99061a9cd *inst/doc/DBI-1.html 26290ffdc6e37a65296d8040944439e5 *inst/doc/DBI-history.Rmd 639b0b06c267d3d366632c3252dd16a1 *inst/doc/DBI-history.html f65e1d2d58e032ebc2c5a30c71183730 *inst/doc/DBI-proposal.Rmd 123d47145a2f0c822e254f9fdca65430 *inst/doc/DBI-proposal.html a87a0d5a2a4f2863a06d433d27dd52f6 *inst/doc/DBI.R faa2fa7989d6d6942d650cbe48fc1760 *inst/doc/DBI.Rmd 558a97959fc227e06f06a0df30dfab9a *inst/doc/DBI.html 63d354b5539a6ab5399d712ddad6bfed *inst/doc/backend.R 25aacc0265fabe384cd5096e2d646d45 *inst/doc/backend.Rmd 2a0c1a035edcc80392600ab0a1ff30a3 *inst/doc/backend.html df611430ec1e229d85ad309d4d6e854c *inst/doc/spec.R efcfaed48eff1d28486573a4b59e0e6f *inst/doc/spec.Rmd 8f6b3992dfbe35a2afc23cdc2db03556 *inst/doc/spec.html 4354c7d19733ce8222bb9c06ef0db20d *man/ANSI.Rd 78ac8f113a64575cf06fd724c43a95c0 *man/DBI-package.Rd 8aabaac90276c4b8804802d0fd4257ae *man/DBIConnection-class.Rd 244f0ff4b4e8207fcafdffa805a80882 *man/DBIConnector-class.Rd b0be5cf4edb9168b2bd55122c6152921 *man/DBIDriver-class.Rd cfff0d2d5910dabcbc2fbd78d45de1d5 *man/DBIObject-class.Rd 0a75ad4672ed04fb03685b8e64213ee0 *man/DBIResult-class.Rd 920abb3028bde9aea3f561a8760f0e89 *man/Id.Rd c4df8d562fbde04c536856c43d659464 *man/SQL.Rd 88b3ef53b807d9e4ca5bb62914cc635a *man/dbAppendTable.Rd 3fd03df49b0314979b787ea696d18475 *man/dbBind.Rd 845b9522a468729129d1103071f995c4 *man/dbCallProc.Rd e18824902a0660666ddb9ecac073aca2 *man/dbCanConnect.Rd b6cd7109a37ccab3100adf15671ddbdb *man/dbClearResult.Rd 14fe7c98f52de0c0188d0d51f009593e *man/dbColumnInfo.Rd 9b3cac63eb881703e1a316b8d6820094 *man/dbConnect.Rd 298868a5b9d620254c7425e39cd6bb8f *man/dbCreateTable.Rd 99147aa62980082e44962398f99feb01 *man/dbDataType.Rd 56d03414b153c44df30c9f3f9e3c22ff *man/dbDisconnect.Rd 397230749aeb58d5ad395ae829f4cbda *man/dbDriver.Rd 0756f416a37a9125f2375c604cd25d62 *man/dbExecute.Rd f713d662b791973b57c98d65578ecfd7 *man/dbExistsTable.Rd a7cb423a28a0dab947077bc344990187 *man/dbFetch.Rd f8667b3e887ee7df2d6e59624a2569fe *man/dbGetConnectArgs.Rd 600709b1318e882e99b98e90fa8ba7e7 *man/dbGetDBIVersion.Rd 669d063e60b67c8ba2c29100173bca79 *man/dbGetException.Rd 21f83984ecb13bd8dc10d540306e39f3 *man/dbGetInfo.Rd 1a4b60306d4702fe7e76f24306eecdf5 *man/dbGetQuery.Rd 08394ee9913237c56fdab5da59d939a4 *man/dbGetRowCount.Rd 419a302c4d71bf24433d9ff7a43ee7de *man/dbGetRowsAffected.Rd 9acb994c1fea38a81eeb9304fc88800a *man/dbGetStatement.Rd f3e8044d7e7935a304889b72b292e309 *man/dbHasCompleted.Rd e96dd3bf17816ddbdf2e0a0f87810dae *man/dbIsReadOnly.Rd 1b4ed7853d347b176166f38c1053bbd4 *man/dbIsValid.Rd 6613ae5a587c09717f4feccb0d40cf86 *man/dbListConnections.Rd 2d39b73737c3d7dcc0659095fe448871 *man/dbListFields.Rd f945ea4069c197f52d5f4e3bde18425e *man/dbListObjects.Rd a246db3810aa73623e209a9202393e35 *man/dbListResults.Rd 2e215f0c569ad277ffaab958d9e04372 *man/dbListTables.Rd 3fb50032ef8ef6a5171ca62fd52e13dc *man/dbQuoteIdentifier.Rd 4fa823c8d5b494604d47d3466122fb47 *man/dbQuoteLiteral.Rd 0c87d070ddf2a6b64c32f5ee732a5176 *man/dbQuoteString.Rd c63c7370f6ce9f6e23e1a39b333c78f7 *man/dbReadTable.Rd 947d6e686cc9295af93df87802ecc0f8 *man/dbRemoveTable.Rd e7ab8701ff7b306df8a9e5196cade840 *man/dbSendQuery.Rd 61d60cafadb8d359d3d370ba50c7570b *man/dbSendStatement.Rd efc9ad682c86a680573d3f05e3b88abb *man/dbSetDataMappings.Rd 018f2aac0317ec85d0e57b76bd0a1428 *man/dbUnquoteIdentifier.Rd 5181a02e89bfc5f2e24a05c212c8587d *man/dbWithTransaction.Rd edc9104d99facff7d2ab9746e358e3d7 *man/dbWriteTable.Rd 0f4c48035d655816d03564976f3a0748 *man/hidden_aliases.Rd c749fdc57374b7d5f474e88f09923f70 *man/make.db.names.Rd 5b606a6756e9d24b3341551233fb7e84 *man/rownames.Rd dc3fae909644db067e31be734bba5229 *man/sqlAppendTable.Rd 442c3bd5b87ff035aab47d9d63b6e446 *man/sqlCreateTable.Rd 7a34ae1f8e0f1ad0a810893017037400 *man/sqlData.Rd 7afda76417f9e177d52a528882b61256 *man/sqlInterpolate.Rd 56c07fe390b61c5aba464061b4cb2181 *man/sqlParseVariables.Rd efac8184a153435b3d1f146ab8e2134d *man/transactions.Rd a4fe1ddf5f03bdcb9a22c2674a266e9e *tests/testthat.R a0e8f9eb80974345f902b315a0409281 *tests/testthat/helper-dummy.R 4baa6d1e48c09444fa8a3087f6ea812f *tests/testthat/test-data-type.R 46fbb731a9df9ff4384288b2e7722deb *tests/testthat/test-interpolate.R 58549e35e48e852f047d0c6296608ac2 *tests/testthat/test-methods.R 2f999830d52cd8d7cd35d881d3ab1f94 *tests/testthat/test-quote.R e8afe06a3e597ec1063be9f351b63a6c *tests/testthat/test-quoting.R 936863cb0e7bb14bf6f3e913d28a77d1 *tests/testthat/test-rownames.R 793d64584aa74172076b4d3f3b67bd12 *tests/testthat/test-sql-df.R 2a9b8778d24d15329d70d85d014c4054 *vignettes/DBI-1.Rmd 26290ffdc6e37a65296d8040944439e5 *vignettes/DBI-history.Rmd f65e1d2d58e032ebc2c5a30c71183730 *vignettes/DBI-proposal.Rmd faa2fa7989d6d6942d650cbe48fc1760 *vignettes/DBI.Rmd 25aacc0265fabe384cd5096e2d646d45 *vignettes/backend.Rmd c63a631c86125636916478bb0b682e2c *vignettes/biblio.bib 16facd043de5250ab88f5b3badef9ab0 *vignettes/hierarchy.png efcfaed48eff1d28486573a4b59e0e6f *vignettes/spec.Rmd DBI/inst/0000755000176200001440000000000013575372776011653 5ustar liggesusersDBI/inst/doc/0000755000176200001440000000000013575372776012420 5ustar liggesusersDBI/inst/doc/backend.html0000644000176200001440000007060513575372774014703 0ustar liggesusersImplementing a new backend

Implementing a new backend

Hadley Wickham

The goal of this document is to help you implement a new backend for DBI.

If you are writing a package that connects a database to R, I highly recommend that you make it DBI compatible because it makes your life easier by spelling out exactly what you need to do. The consistent interface provided by DBI makes it easier for you to implement the package (because you have fewer arbitrary choices to make), and easier for your users (because it follows a familiar pattern). In addition, the DBItest package provides test cases which you can easily incorporate in your package.

I’ll illustrate the process using a fictional database called Kazam.

Getting started

Start by creating a package. It’s up to you what to call the package, but following the existing pattern of RSQLite, RMySQL, RPostgres and ROracle will make it easier for people to find it. For this example, I’ll call my package RKazam.

In your DESCRIPTION, make sure to include:

Importing DBI is fine, because your users are not supposed to attach your package anyway; the preferred method is to attach DBI and use explicit qualification via :: to access the driver in your package (which needs to be done only once).

Testing

Why testing at this early stage? Because testing should be an integral part of the software development cycle. Test right from the start, add automated tests as you go, finish faster (because tests are automated) while maintaining superb code quality (because tests also check corner cases that you might not be aware of). Don’t worry: if some test cases are difficult or impossible to satisfy, or take too long to run, you can just turn them off.

Take the time now to head over to the DBItest vignette. You will find a vast amount of ready-to-use test cases that will help you in the process of implementing your new DBI backend.

Add custom tests that are not covered by DBItest at your discretion, or enhance DBItest and file a pull request if the test is generic enough to be useful for many DBI backends.

Driver

Start by making a driver class which inherits from DBIDriver. This class doesn’t need to do anything, it’s just used to dispatch other generics to the right method. Users don’t need to know about this, so you can remove it from the default help listing with @keywords internal:

The driver class was more important in older versions of DBI, so you should also provide a dummy dbUnloadDriver() method.

If your package needs global setup or tear down, do this in the .onLoad() and .onUnload() functions.

You might also want to add a show method so the object prints nicely:

Next create Kazam() which instantiates this class.

Connection

Next create a connection class that inherits from DBIConnection. This should store all the information needed to connect to the database. If you’re talking to a C api, this will include a slot that holds an external pointer.

Now you have some of the boilerplate out of the way, you can start work on the connection. The most important method here is dbConnect() which allows you to connect to a specified instance of the database. Note the use of @rdname Kazam. This ensures that Kazam() and the connect method are documented together.

  • Replace ... with the arguments needed to connect to your database. You’ll always need to include ... in the arguments, even if you don’t use it, for compatibility with the generic.

  • This is likely to be where people first come for help, so the examples should show how to connect to the database, and how to query it. (Obviously these examples won’t work yet.) Ideally, include examples that can be run right away (perhaps relying on a publicly hosted database), but failing that surround in \dontrun{} so people can at least see the code.

Next, implement show() and dbDisconnect() methods.

Results

Finally, you’re ready to implement the meat of the system: fetching results of a query into a data frame. First define a results class:

Then write a dbSendQuery() method. This takes a connection and SQL string as arguments, and returns a result object. Again ... is needed for compatibility with the generic, but you can add other arguments if you need them.

Next, implement dbClearResult(), which should close the result set and free all resources associated with it:

The hardest part of every DBI package is writing the dbFetch() method. This needs to take a result set and (optionally) number of records to return, and create a dataframe. Mapping R’s data types to those of your database may require a custom implementation of the dbDataType() method for your connection class:

Next, implement dbHasCompleted() which should return a logical indicating if there are any rows remaining to be fetched.

With these four methods in place, you can now use the default dbGetQuery() to send a query to the database, retrieve results if available and then clean up. Spend some time now making sure this works with an existing database, or relax and let the DBItest package do the work for you.

SQL methods

You’re now on the home stretch, and can make your wrapper substantially more useful by implementing methods that wrap around variations in SQL across databases:

  • dbQuoteString() and dbQuoteIdentifer() are used to safely quote strings and identifiers to avoid SQL injection attacks. Note that the former must be vectorized, but not the latter.

  • dbWriteTable() creates a database table given an R dataframe. I’d recommend using the functions prefixed with sql in this package to generate the SQL. These functions are still a work in progress so please let me know if you have problems.

  • dbReadTable(): a simple wrapper around SELECT * FROM table. Use dbQuoteIdentifer() to safely quote the table name and prevent mismatches between the names allowed by R and the database.

  • dbListTables() and dbExistsTable() let you determine what tables are available. If not provided by your database’s API, you may need to generate sql that inspects the system tables.

  • dbListFields() shows which fields are available in a given table.

  • dbRemoveTable() wraps around DROP TABLE. Start with SQL::sqlTableDrop().

  • dbBegin(), dbCommit() and dbRollback(): implement these three functions to provide basic transaction support. This functionality is currently not tested in the DBItest package.

Metadata methods

There are a lot of extra metadata methods for result sets (and one for the connection) that you might want to implement. They are described in the following.

  • dbIsValid() returns if a connection or a result set is open (TRUE) or closed (FALSE). All further methods in this section are valid for result sets only.

  • dbGetStatement() returns the issued query as a character value.

  • dbColumnInfo() lists the names and types of the result set’s columns.

  • dbGetRowCount() and dbGetRowsAffected() returns the number of rows returned or altered in a SELECT or INSERT/UPDATE query, respectively.

  • dbBind() allows using parametrised queries. Take a look at sqlInterpolate() and sqlParseVariables() if your SQL engine doesn’t offer native parametrised queries.

Full DBI compliance

By now, your package should implement all methods defined in the DBI specification. If you want to walk the extra mile, offer a read-only mode that allows your users to be sure that their valuable data doesn’t get destroyed inadvertently.

DBI/inst/doc/DBI.R0000644000176200001440000000257713575372773013151 0ustar liggesusers## ----setup, include=FALSE----------------------------------------------------- knitr::opts_chunk$set(echo = TRUE) ## ----------------------------------------------------------------------------- library(DBI) con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:") con ## ----------------------------------------------------------------------------- dbListTables(con) ## ----------------------------------------------------------------------------- dbWriteTable(con, "mtcars", mtcars) dbListTables(con) ## ----------------------------------------------------------------------------- dbListFields(con, "mtcars") ## ----------------------------------------------------------------------------- dbReadTable(con, "mtcars") ## ----------------------------------------------------------------------------- df <- dbGetQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df ## ----------------------------------------------------------------------------- res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df <- dbFetch(res) dbClearResult(res) df ## ----------------------------------------------------------------------------- res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") while(!dbHasCompleted(res)){ chunk <- dbFetch(res, n = 5) print(nrow(chunk)) } ## ----------------------------------------------------------------------------- dbClearResult(res) dbDisconnect(con) DBI/inst/doc/DBI-1.Rmd0000644000176200001440000006002013550573553013603 0ustar liggesusers--- title: "A Common Database Interface (DBI)" author: "R-Databases Special Interest Group" date: "16 June 2003" output: rmarkdown::html_vignette bibliography: biblio.bib vignette: > %\VignetteIndexEntry{A Common Database Interface (DBI)} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- This document describes a common interface between the S language (in its R and S-Plus implementations) and database management systems (DBMS). The interface defines a small set of classes and methods similar in spirit to Perl’s DBI, Java’s JDBC, Python’s DB-API, and Microsoft’s ODBC. # Version {#sec:version} This document describes version 0.1-6 of the database interface API (application programming interface). # Introduction {#sec:intro} The database interface (DBI) separates the connectivity to the DBMS into a “front-end” and a “back-end”. Applications use only the exposed “front-end” API. The facilities that communicate with specific DBMS (Oracle, PostgreSQL, etc.) are provided by “device drivers” that get invoked automatically by the S language evaluator. The following example illustrates some of the DBI capabilities: ```R ## Choose the proper DBMS driver and connect to the server drv <- dbDriver("ODBC") con <- dbConnect(drv, "dsn", "usr", "pwd") ## The interface can work at a higher level importing tables ## as data.frames and exporting data.frames as DBMS tables. dbListTables(con) dbListFields(con, "quakes") if(dbExistsTable(con, "new_results")) dbRemoveTable(con, "new_results") dbWriteTable(con, "new_results", new.output) ## The interface allows lower-level interface to the DBMS res <- dbSendQuery(con, paste( "SELECT g.id, g.mirror, g.diam, e.voltage", "FROM geom_table as g, elec_measures as e", "WHERE g.id = e.id and g.mirrortype = 'inside'", "ORDER BY g.diam")) out <- NULL while(!dbHasCompleted(res)){ chunk <- fetch(res, n = 10000) out <- c(out, doit(chunk)) } ## Free up resources dbClearResult(res) dbDisconnect(con) dbUnloadDriver(drv) ``` (only the first 2 expressions are DBMS-specific – all others are independent of the database engine itself). Individual DBI drivers need not implement all the features we list below (we indicate those that are optional). Furthermore, drivers may extend the core DBI facilities, but we suggest to have these extensions clearly indicated and documented. The following are the elements of the DBI: 1. A set of classes and methods (Section [sec:DBIClasses]) that defines what operations are possible and how they are defined, e.g.: - connect/disconnect to the DBMS - create and execute statements in the DBMS - extract results/output from statements - error/exception handling - information (meta-data) from database objects - transaction management (optional) Some things are left explicitly unspecified, e.g., authentication and even the query language, although it is hard to avoid references to SQL and relational database management systems (RDBMS). 2. Drivers Drivers are collection of functions that implement the functionality defined above in the context of specific DBMS, e.g., mSQL, Informix. 3. Data type mappings (Section [sec:data-mappings].) Mappings and conversions between DBMS data types and R/S objects. All drivers should implement the “basic” primitives (see below), but may chose to add user-defined conversion function to handle more generic objects (e.g., factors, ordered factors, time series, arrays, images). 4. Utilities (Section [sec:utilities].) These facilities help with details such as mapping of identifiers between S and DBMS (e.g., `_` is illegal in R/S names, and `.` is used for constructing compound SQL identifiers), etc. # DBI Classes and Methods {#sec:DBIClasses} The following are the main DBI classes. They need to be extended by individual database back-ends (Sybase, Oracle, etc.) Individual drivers need to provide methods for the generic functions listed here (those methods that are optional are so indicated). *Note: Although R releases prior to 1.4 do not have a formal concept of classes, we will use the syntax of the S Version 4 classes and methods (available in R releases 1.4 and later as library `methods`) to convey precisely the DBI class hierarchy, its methods, and intended behavior.* The DBI classes are `DBIObject`, `DBIDriver`, `DBIConnection` and `DBIResult`. All these are *virtual* classes. Drivers define new classes that extend these, e.g., `PgSQLDriver`, `PgSQLConnection`, and so on. ![Class hierarchy for the DBI. The top two layers are comprised of virtual classes and each lower layer represents a set of driver-specific implementation classes that provide the functionality defined by the virtual classes above.](hierarchy.png) `DBIObject`: : Virtual class[^1] that groups all other DBI classes. `DBIDriver`: : Virtual class that groups all DBMS drivers. Each DBMS driver extends this class. Typically generator functions instantiate the actual driver objects, e.g., `PgSQL`, `HDF5`, `BerkeleyDB`. `DBIConnection`: : Virtual class that encapsulates connections to DBMS. `DBIResult`: : Virtual class that describes the result of a DBMS query or statement. [Q: Should we distinguish between a simple result of DBMS statements e.g., as `delete` from DBMS queries (i.e., those that generate data).] The methods `format`, `print`, `show`, `dbGetInfo`, and `summary` are defined (and *implemented* in the `DBI` package) for the `DBIObject` base class, thus available to all implementations; individual drivers, however, are free to override them as they see fit. `format(x, ...)`: : produces a concise character representation (label) for the `DBIObject` `x`. `print(x, ...)`/`show(x)`: : prints a one-line identification of the object `x`. `summary(object, ...)`: : produces a concise description of the object. The default method for `DBIObject` simply invokes `dbGetInfo(dbObj)` and prints the name-value pairs one per line. Individual implementations may tailor this appropriately. `dbGetInfo(dbObj, ...)`: : extracts information (meta-data) relevant for the `DBIObject` `dbObj`. It may return a list of key/value pairs, individual meta-data if supplied in the call, or `NULL` if the requested meta-data is not available. *Hint:* Driver implementations may choose to allow an argument `what` to specify individual meta-data, e.g., `dbGetInfo(drv, what = max.connections)`. In the next few sub-sections we describe in detail each of these classes and their methods. ## Class `DBIObject` {#sec:DBIObject} This class simply groups all DBI classes, and thus all extend it. ## Class `DBIDriver` {#sec:DBIDriver} This class identifies the database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.) The DBI provides the generator `dbDriver(driverName)` which simply invokes the function `driverName`, which in turn instantiates the corresponding driver object. The `DBIDriver` class defines the following methods: `driverName`: : [meth:driverName] initializes the driver code. The name `driverName` refers to the actual generator function for the DBMS, e.g., `RPgSQL`, `RODBC`, `HDF5`. The driver instance object is used with `dbConnect` (see page ) for opening one or possibly more connections to one or more DBMS. `dbListConnections(drv, ...)`: : list of current connections being handled by the `drv` driver. May be `NULL` if there are no open connections. Drivers that do not support multiple connections may return the one open connection. `dbGetInfo(dbObj, ...)`: : returns a list of name-value pairs of information about the driver. *Hint:* Useful entries could include `name`: : the driver name (e.g., `RODBC`, `RPgSQL`); `driver.version`: : version of the driver; `DBI.version`: : the version of the DBI that the driver implements, e.g., `0.1-2`; `client.version`: : of the client DBMS libraries (e.g., version of the `libpq` library in the case of `RPgSQL`); `max.connections`: : maximum number of simultaneous connections; plus any other relevant information about the implementation, for instance, how the driver handles upper/lower case in identifiers. `dbUnloadDriver(driverName)` (optional): : frees all resources (local and remote) used by the driver. Returns a logical to indicate if it succeeded or not. ## Class `DBIConnection` {#sec:DBIConnection} This virtual class encapsulates the connection to a DBMS, and it provides access to dynamic queries, result sets, DBMS session management (transactions), etc. *Note:* Individual drivers are free to implement single or multiple simultaneous connections. The methods defined by the `DBIConnection` class include: `dbConnect(drv, ...)`: : [meth:dbConnect] creates and opens a connection to the database implemented by the driver `drv` (see Section [sec:DBIDriver]). Each driver will define what other arguments are required, e.g., `dbname` or `dsn` for the database name, `user`, and `password`. It returns an object that extends `DBIConnection` in a driver-specific manner (e.g., the MySQL implementation could create an object of class `MySQLConnection` that extends `DBIConnection`). `dbDisconnect(conn, ...)`: : closes the connection, discards all pending work, and frees resources (e.g., memory, sockets). Returns a logical indicating whether it succeeded or not. `dbSendQuery(conn, statement, ...)`: : submits one statement to the DBMS. It returns a `DBIResult` object. This object is needed for fetching data in case the statement generates output (see `fetch` on page ), and it may be used for querying the state of the operation; see `dbGetInfo` and other meta-data methods on page . `dbGetQuery(conn, statement, ...)`: : submit, execute, and extract output in one operation. The resulting object may be a `data.frame` if the `statement` generates output. Otherwise the return value should be a logical indicating whether the query succeeded or not. `dbGetException(conn, ...)`: : returns a list with elements `errNum` and `errMsg` with the status of the last DBMS statement sent on a given connection (this information may also be provided by the `dbGetInfo` meta-data function on the `conn` object. *Hint:* The ANSI SQL-92 defines both a status code and an status message that could be return as members of the list. `dbGetInfo(dbObj, ...)`: : returns a list of name-value pairs describing the state of the connection; it may return one or more meta-data, the actual driver method allows to specify individual pieces of meta-data (e.g., maximum number of open results/cursors). *Hint:* Useful entries could include `dbname`: : the name of the database in use; `db.version`: : the DBMS server version (e.g., “Oracle 8.1.7 on Solaris”; `host`: : host where the database server resides; `user`: : user name; `password`: : password (is this safe?); plus any other arguments related to the connection (e.g., thread id, socket or TCP connection type). `dbListResults(conn, ...)`: : list of `DBIResult` objects currently active on the connection `conn`. May be `NULL` if no result set is active on `conn`. Drivers that implement only one result set per connection could return that one object (no need to wrap it in a list). *Note: The following are convenience methods that simplify the import/export of (mainly) data.frames. The first five methods implement the core methods needed to `attach` remote DBMS to the S search path. (For details, see @data-management:1991 [@database-classes:1999].)* *Hint:* For relational DBMS these methods may be easily implemented using the core DBI methods `dbConnect`, `dbSendQuery`, and `fetch`, due to SQL reflectance (i.e., one easily gets this meta-data by querying the appropriate tables on the RDBMS). `dbListTables(conn, ...)`: : returns a character vector (possibly of zero-length) of object (table) names available on the `conn` connection. `dbReadTable(conn, name, ...)`: : imports the data stored remotely in the table `name` on connection `conn`. Use the field `row.names` as the `row.names` attribute of the output data.frame. Returns a `data.frame`. [Q: should we spell out how row.names should be created? E.g., use a field (with unique values) as row.names? Also, should `dbReadTable` reproduce a data.frame exported with `dbWriteTable`?] `dbWriteTable(conn, name, value, ...)`: : write the object `value` (perhaps after coercing it to data.frame) into the remote object `name` in connection `conn`. Returns a logical indicating whether the operation succeeded or not. `dbExistsTable(conn, name, ...)`: : does remote object `name` exist on `conn`? Returns a logical. `dbRemoveTable(conn, name, ...)`: : removes remote object `name` on connection `conn`. Returns a logical indicating whether the operation succeeded or not. `dbListFields(conn, name, ...)`: : returns a character vector listing the field names of the remote table `name` on connection `conn` (see `dbColumnInfo()` for extracting data type on a table). *Note: The following methods deal with transactions and stored procedures. All these functions are optional.* `dbCommit(conn, ...)`(optional): : commits pending transaction on the connection and returns `TRUE` or `FALSE` depending on whether the operation succeeded or not. `dbRollback(conn, ...)`(optional): : undoes current transaction on the connection and returns `TRUE` or `FALSE` depending on whether the operation succeeded or not. `dbCallProc(conn, storedProc, ...)`(optional): : invokes a stored procedure in the DBMS and returns a `DBIResult` object. [Stored procedures are *not* part of the ANSI SQL-92 standard and vary substantially from one RDBMS to another.] **Deprecated since 2014:** The recommended way of calling a stored procedure is now - `dbGetQuery` if a result set is returned and - `dbExecute` for data manipulation and other cases that do not return a result set. ## Class `DBIResult` {#sec:DBIResult} This virtual class describes the result and state of execution of a DBMS statement (any statement, query or non-query). The result set `res` keeps track of whether the statement produces output for R/S, how many rows were affected by the operation, how many rows have been fetched (if statement is a query), whether there are more rows to fetch, etc. *Note: Individual drivers are free to allow single or multiple active results per connection.* [Q: Should we distinguish between results that return no data from those that return data?] The class `DBIResult` defines the following methods: `fetch(res, n, ...)`: : [meth:fetch] fetches the next `n` elements (rows) from the result set `res` and return them as a data.frame. A value of `n=-1` is interpreted as “return all elements/rows”. `dbClearResult(res, ...)`: : flushes any pending data and frees all resources (local and remote) used by the object `res` on both sides of the connection. Returns a logical indicating success or not. `dbGetInfo(dbObj, ...)`: : returns a name-value list with the state of the result set. *Hint:* Useful entries could include `statement`: : a character string representation of the statement being executed; `rows.affected`: : number of affected records (changed, deleted, inserted, or extracted); `row.count`: : number of rows fetched so far; `has.completed`: : has the statement (query) finished? `is.select`: : a logical describing whether or not the statement generates output; plus any other relevant driver-specific meta-data. `dbColumnInfo(res, ...)`: : produces a data.frame that describes the output of a query. The data.frame should have as many rows as there are output fields in the result set, and each column in the data.frame should describe an aspect of the result set field (field name, type, etc.) *Hint:* The data.frame columns could include `field.name`: : DBMS field label; `field.type`: : DBMS field type (implementation-specific); `data.type`: : corresponding R/S data type, e.g., `integer`; `precision`/`scale`: : (as in ODBC terminology), display width and number of decimal digits, respectively; `nullable`: : whether the corresponding field may contain (DBMS) `NULL` values; plus other driver-specific information. `dbSetDataMappings(flds, ...)`(optional): : defines a conversion between internal DBMS data types and R/S classes. We expect the default mappings (see Section [sec:data-mappings]) to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. [This topic needs further discussion.] *Note: The following are convenience methods that extract information from the result object (they may be implemented by invoking `dbGetInfo` with appropriate arguments).* `dbGetStatement(res, ...)`(optional): : returns the DBMS statement (as a character string) associated with the result `res`. `dbGetRowsAffected(res, ...)`(optional): : returns the number of rows affected by the executed statement (number of records deleted, modified, extracted, etc.) `dbHasCompleted(res, ...)`(optional): : returns a logical that indicates whether the operation has been completed (e.g., are there more records to be fetched?). `dbGetRowCount(res, ...)`(optional): : returns the number of rows fetched so far. # Data Type Mappings {#sec:data-mappings} The data types supported by databases are different than the data types in R and S, but the mapping between the “primitive” types is straightforward: Any of the many fixed and varying length character types are mapped to R/S `character`. Fixed-precision (non-IEEE) numbers are mapped into either doubles (`numeric`) or long (`integer`). Notice that many DBMS do not follow the so-called IEEE arithmetic, so there are potential problems with under/overflows and loss of precision, but given the R/S primitive types we cannot do too much but identify these situations and warn the application (how?). By default dates and date-time objects are mapped to character using the appropriate `TO_CHAR` function in the DBMS (which should take care of any locale information). Some RDBMS support the type `CURRENCY` or `MONEY` which should be mapped to `numeric` (again with potential round off errors). Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion (as has been done in other inter-systems packages [^2]). Specifying user-defined conversion functions still needs to be defined. # Utilities {#sec:utilities} The core DBI implementation should make available to all drivers some common basic utilities. For instance: `dbGetDBIVersion`: : returns the version of the currently attached DBI as a string. `dbDataType(dbObj, obj, ...)`: : returns a string with the (approximately) appropriate data type for the R/S object `obj`. The DBI can implement this following the ANSI-92 standard, but individual drivers may want/need to extend it to make use of DBMS-specific types. `make.db.names(dbObj, snames, ...)`: : maps R/S names (identifiers) to SQL identifiers replacing illegal characters (as `.`) by the legal SQL `_`. `SQLKeywords(dbObj, ...)`: : returns a character vector of SQL keywords (reserved words). The default method returns the list of `.SQL92Keywords`, but drivers should update this vector with the DBMS-specific additional reserved words. `isSQLKeyword(dbObj, name, ...)`: : for each element in the character vector `name` determine whether or not it is an SQL keyword, as reported by the generic function `SQLKeywords`. Returns a logical vector parallel to the input object `name`. # Open Issues and Limitations {#sec:open-issues} There are a number of issues and limitations that the current DBI conscientiously does not address on the interest of simplicity. We do list here the most important ones. Non-SQL: : Is it realistic to attempt to encompass non-relational databases, like HDF5, Berkeley DB, etc.? Security: : allowing users to specify their passwords on R/S scripts may be unacceptable for some applications. We need to consider alternatives where users could store authentication on files (perhaps similar to ODBC’s `odbc.ini`) with more stringent permissions. Exceptions: : the exception mechanism is a bit too simple, and it does not provide for information when problems stem from the DBMS interface itself. For instance, under/overflow or loss of precision as we move numeric data from DBMS to the more limited primitives in R/S. Asynchronous communication: : most DBMS support both synchronous and asynchronous communications, allowing applications to submit a query and proceed while the database server process the query. The application is then notified (or it may need to poll the server) when the query has completed. For large computations, this could be very useful, but the DBI would need to specify how to interrupt the server (if necessary) plus other details. Also, some DBMS require applications to use threads to implement asynchronous communication, something that neither R nor S-Plus currently addresses. SQL scripts: : the DBI only defines how to execute one SQL statement at a time, forcing users to split SQL scripts into individual statements. We need a mechanism by which users can submit SQL scripts that could possibly generate multiple result sets; in this case we may need to introduce new methods to loop over multiple results (similar to Python’s `nextResultSet`). BLOBS/CLOBS: : large objects (both character and binary) present some challenges both to R and S-Plus. It is becoming more common to store images, sounds, and other data types as binary objects in DBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects. Transactions: : transaction management is not fully described. Additional methods: : Do we need any additional methods? (e.g., `dbListDatabases(conn)`, `dbListTableIndices(conn, name)`, how do we list all available drivers?) Bind variables: : the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of R/S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement /* SQL */ SELECT * from emp_table where emp_id = :sampleEmployee would take the vector `sampleEmployee` and iterate over each of its elements to get the result. Perhaps the DBI could at some point in the future implement this feature. # Resources {#sec:resources} The idea of a common interface to databases has been successfully implemented in various environments, for instance: Java’s Database Connectivity (JDBC) ([www.javasoft.com](http://www.javasoft.com/products/jdbc/index.html)). In C through the Open Database Connectivity (ODBC) ([www.unixodbc.org](http://www.unixodbc.org/)). Python’s Database Application Programming Interface ([www.python.org](http://www.python.org/topics/database)). Perl’s Database Interface ([dbi.perl.org](http://dbi.perl.org)). [^1]: A virtual class allows us to group classes that share some common characteristics, even if their implementations are radically different. [^2]: Duncan Temple Lang has volunteered to port the data conversion code found in R-Java, R-Perl, and R-Python packages to the DBI DBI/inst/doc/spec.html0000644000176200001440000046603713575372776014260 0ustar liggesusersDBI specification

DBI specification

Kirill Müller

Abstract

The DBI package defines the generic DataBase Interface for R. The connection to individual DBMS is provided by other packages that import DBI (so-called DBI backends). This document formalizes the behavior expected by the methods declared in DBI and implemented by the individual backends. To ensure maximum portability and exchangeability, and to reduce the effort for implementing a new DBI backend, the DBItest package defines a comprehensive set of test cases that test conformance to the DBI specification. This document is derived from comments in the test definitions of the DBItest package. Any extensions or updates to the tests will be reflected in this document.

DBI: R Database Interface

DBI defines an interface for communication between R and relational database management systems. All classes in this package are virtual and need to be extended by the various R/DBMS implementations (so-called DBI backends).

Definition

A DBI backend is an R package which imports the DBI and methods packages. For better or worse, the names of many existing backends start with ‘R’, e.g., RSQLite, RMySQL, RSQLServer; it is up to the backend author to adopt this convention or not.

DBI classes and methods

A backend defines three classes, which are subclasses of DBIDriver, DBIConnection, and DBIResult. The backend provides implementation for all methods of these base classes that are defined but not implemented by DBI. All methods defined in DBI are reexported (so that the package can be used without having to attach DBI), and have an ellipsis ... in their formals for extensibility.

Construction of the DBIDriver object

The backend must support creation of an instance of its DBIDriver subclass with a constructor function. By default, its name is the package name without the leading ‘R’ (if it exists), e.g., SQLite for the RSQLite package. However, backend authors may choose a different name. The constructor must be exported, and it must be a function that is callable without arguments. DBI recommends to define a constructor with an empty argument list.

Determine the SQL data type of an object

This section describes the behavior of the following method:

Description

Returns an SQL string that describes the SQL data type to be used for an object. The default implementation of this generic determines the SQL type of an R object according to the SQL 92 specification, which may serve as a starting point for driver implementations. DBI also provides an implementation for data.frame which will return a character vector giving the type for each column in the dataframe.

Methods in other packages

  • RSQLite::dbDataType("SQLiteConnection")

  • RSQLite::dbDataType("SQLiteDriver")

Arguments

dbObj A object inheriting from DBIDriver or DBIConnection
obj An R object whose SQL type we want to determine.
... Other arguments passed on to methods.

Details

The data types supported by databases are different than the data types in R, but the mapping between the primitive types is straightforward:

  • Any of the many fixed and varying length character types are mapped to character vectors

  • Fixed-precision (non-IEEE) numbers are mapped into either numeric or integer vectors.

Notice that many DBMS do not follow IEEE arithmetic, so there are potential problems with under/overflows and loss of precision.

Value

dbDataType() returns the SQL type that corresponds to the obj argument as a non-empty character string. For data frames, a character vector with one element per column is returned. An error is raised for invalid values for the obj argument such as a NULL value.

Specification

The backend can override the dbDataType() generic for its driver class.

This generic expects an arbitrary object as second argument. To query the values returned by the default implementation, run example(dbDataType, package = "DBI"). If the backend needs to override this generic, it must accept all basic R data types as its second argument, namely logical, integer, numeric, character, dates (see Dates), date-time (see DateTimeClasses), and difftime. If the database supports blobs, this method also must accept lists of raw vectors, and blob::blob objects. As-is objects (i.e., wrapped by I()) must be supported and return the same results as their unwrapped counterparts. The SQL data type for factor and ordered is the same as for character. The behavior for other object types is not specified.

All data types returned by dbDataType() are usable in an SQL statement of the form "CREATE TABLE test (a ...)".

Create a connection to a DBMS

This section describes the behavior of the following method:

Description

Connect to a DBMS going through the appropriate authentication procedure. Some implementations may allow you to have multiple connections open, so you may invoke this function repeatedly assigning its output to different objects. The authentication mechanism is left unspecified, so check the documentation of individual drivers for details. Use dbCanConnect() to check if a connection can be established.

Methods in other packages

  • RSQLite::dbConnect("SQLiteConnection")

  • RSQLite::dbConnect("SQLiteDriver")

Arguments

drv an object that inherits from DBIDriver, or an existing DBIConnection object (in order to clone an existing connection).
... authentication arguments needed by the DBMS instance; these typically include user, password, host, port, dbname, etc. For details see the appropriate DBIDriver.

Value

dbConnect() returns an S4 object that inherits from DBIConnection. This object is used to communicate with the database engine.

A format() method is defined for the connection object. It returns a string that consists of a single line of text.

Specification

DBI recommends using the following argument names for authentication parameters, with NULL default:

  • user for the user name (default: current user)

  • password for the password

  • host for the host name (default: local connection)

  • port for the port number (default: local connection)

  • dbname for the name of the database on the host, or the database file name

The defaults should provide reasonable behavior, in particular a local connection for host = NULL. For some DBMS (e.g., PostgreSQL), this is different to a TCP/IP connection to localhost.

In addition, DBI supports the bigint argument that governs how 64-bit integer data is returned. The following values are supported:

  • "integer": always return as integer, silently overflow

  • "numeric": always return as numeric, silently round

  • "character": always return the decimal representation as character

  • "integer64": return as a data type that can be coerced using as.integer() (with warning on overflow), as.numeric() and as.character()

Disconnect (close) a connection

This section describes the behavior of the following method:

Description

This closes the connection, discards all pending work, and frees resources (e.g., memory, sockets).

Methods in other packages

  • RSQLite::dbDisconnect("SQLiteConnection")

Arguments

conn A DBIConnection object, as returned by dbConnect().
... Other parameters passed on to methods.

Value

dbDisconnect() returns TRUE, invisibly.

Specification

A warning is issued on garbage collection when a connection has been released without calling dbDisconnect(), but this cannot be tested automatically. A warning is issued immediately when calling dbDisconnect() on an already disconnected or invalid connection.

Execute a query on a given database connection

This section describes the behavior of the following method:

Description

The dbSendQuery() method only submits and synchronously executes the SQL query to the database engine. It does not extract any records — for that you need to use the dbFetch() method, and then you must call dbClearResult() when you finish fetching the records you need. For interactive use, you should almost always prefer dbGetQuery().

Methods in other packages

  • RSQLite::dbSendQuery("SQLiteConnection", "character")

Arguments

conn A DBIConnection object, as returned by dbConnect().
statement a character string containing SQL.
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbSendQuery() generic (to improve compatibility across backends) but are part of the DBI specification:

  • params (default: NULL)

  • immediate (default: NULL)

They must be provided as named arguments. See the “Specification” sections for details on their usage.

Specification

No warnings occur under normal conditions. When done, the DBIResult object must be cleared with a call to dbClearResult(). Failure to clear the result set leads to a warning when the connection is closed.

If the backend supports only one open result set per connection, issuing a second query invalidates an already open result set and raises a warning. The newly opened result set is valid and must be cleared with dbClearResult().

The param argument allows passing query parameters, see dbBind() for details.

Specification for the immediate argument

The immediate argument supports distinguishing between “direct” and “prepared” APIs offered by many database drivers. Passing immediate = TRUE leads to immediate execution of the query or statement, via the “direct” API (if supported by the driver). The default NULL means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct immediate argument. Examples for possible behaviors:

  1. DBI backend defaults to immediate = TRUE internally

    1. A query without parameters is passed: query is executed

    2. A query with parameters is passed:

      1. params not given: rejected immediately by the database because of a syntax error in the query, the backend tries immediate = FALSE (and gives a message)

      2. params given: query is executed using immediate = FALSE

  2. DBI backend defaults to immediate = FALSE internally

    1. A query without parameters is passed:

      1. simple query: query is executed

      2. “special” query (such as setting a config options): fails, the backend tries immediate = TRUE (and gives a message)

    2. A query with parameters is passed:

      1. params not given: waiting for parameters via dbBind()

      2. params given: query is executed

Details

This method is for SELECT queries only. Some backends may support data manipulation queries through this method for compatibility reasons. However, callers are strongly encouraged to use dbSendStatement() for data manipulation statements.

The query is submitted to the database server and the DBMS executes it, possibly generating vast amounts of data. Where these data live is driver-specific: some drivers may choose to leave the output on the server and transfer them piecemeal to R, others may transfer all the data to the client – but not necessarily to the memory that R manages. See individual drivers’ dbSendQuery() documentation for details.

Value

dbSendQuery() returns an S4 object that inherits from DBIResult. The result set can be used with dbFetch() to extract records. Once you have finished using a result, make sure to clear it with dbClearResult(). An error is raised when issuing a query over a closed or invalid connection, or if the query is not a non-NA string. An error is also raised if the syntax of the query is invalid and all query parameters are given (by passing the params argument) or the immediate argument is set to TRUE.

Fetch records from a previously executed query

This section describes the behavior of the following methods:

Description

Fetch the next n elements (rows) from the result set and return them as a data.frame.

Methods in other packages

  • RSQLite::dbFetch("SQLiteResult")

Arguments

res An object inheriting from DBIResult, created by dbSendQuery().
n maximum number of records to retrieve per fetch. Use n = -1 or n = Inf to retrieve all pending records. Some implementations may recognize other special values.
... Other arguments passed on to methods.

Details

fetch() is provided for compatibility with older DBI clients - for all new code you are strongly encouraged to use dbFetch(). The default implementation for dbFetch() calls fetch() so that it is compatible with existing code. Modern backends should implement for dbFetch() only.

Value

dbFetch() always returns a data.frame with as many rows as records were fetched and as many columns as fields in the result set, even if the result is a single value or has one or zero rows. An attempt to fetch from a closed result set raises an error. If the n argument is not an atomic whole number greater or equal to -1 or Inf, an error is raised, but a subsequent call to dbFetch() with proper n argument succeeds. Calling dbFetch() on a result set from a data manipulation query created by dbSendStatement() can be fetched and return an empty data frame, with a warning.

Specification

Fetching multi-row queries with one or more columns by default returns the entire result. Multi-row queries can also be fetched progressively by passing a whole number (integer or numeric) as the n argument. A value of Inf for the n argument is supported and also returns the full result. If more rows than available are fetched, the result is returned in full without warning. If fewer rows than requested are returned, further fetches will return a data frame with zero rows. If zero rows are fetched, the columns of the data frame are still fully typed. Fetching fewer rows than available is permitted, no warning is issued when clearing the result set.

A column named row_names is treated like any other column.

The column types of the returned data frame depend on the data returned:

  • integer (or coercible to an integer) for integer values between -2^31 and 2^31 - 1, with NA for SQL NULL values

  • numeric for numbers with a fractional component, with NA for SQL NULL values

  • logical for Boolean values (some backends may return an integer); with NA for SQL NULL values

  • character for text, with NA for SQL NULL values

  • lists of raw for blobs with NULL entries for SQL NULL values

  • coercible using as.Date() for dates, with NA for SQL NULL values (also applies to the return value of the SQL function current_date)

  • coercible using hms::as_hms() for times, with NA for SQL NULL values (also applies to the return value of the SQL function current_time)

  • coercible using as.POSIXct() for timestamps, with NA for SQL NULL values (also applies to the return value of the SQL function current_timestamp)

If dates and timestamps are supported by the backend, the following R types are used:

  • Date for dates (also applies to the return value of the SQL function current_date)

  • POSIXct for timestamps (also applies to the return value of the SQL function current_timestamp)

R has no built-in type with lossless support for the full range of 64-bit or larger integers. If 64-bit integers are returned from a query, the following rules apply:

  • Values are returned in a container with support for the full range of valid 64-bit values (such as the integer64 class of the bit64 package)

  • Coercion to numeric always returns a number that is as close as possible to the true value

  • Loss of precision when converting to numeric gives a warning

  • Conversion to character always returns a lossless decimal representation of the data

Clear a result set

This section describes the behavior of the following method:

Description

Frees all resources (local and remote) associated with a result set. In some cases (e.g., very large result sets) this can be a critical step to avoid exhausting resources (memory, file descriptors, etc.)

Methods in other packages

  • RSQLite::dbClearResult("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbClearResult() returns TRUE, invisibly, for result sets obtained from both dbSendQuery() and dbSendStatement(). An attempt to close an already closed result set issues a warning in both cases.

Specification

dbClearResult() frees all resources associated with retrieving the result of a query or update operation. The DBI backend can expect a call to dbClearResult() for each dbSendQuery() or dbSendStatement() call.

Bind values to a parameterized/prepared statement

This section describes the behavior of the following method:

Description

For parametrized or prepared statements, the dbSendQuery() and dbSendStatement() functions can be called with statements that contain placeholders for values. The dbBind() function binds these placeholders to actual values, and is intended to be called on the result set before calling dbFetch() or dbGetRowsAffected().

Methods in other packages

  • RSQLite::dbBind("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
params A list of bindings, named or unnamed.
... Other arguments passed on to methods.

Details

DBI supports parametrized (or prepared) queries and statements via the dbBind() generic. Parametrized queries are different from normal queries in that they allow an arbitrary number of placeholders, which are later substituted by actual values. Parametrized queries (and statements) serve two purposes:

  • The same query can be executed more than once with different values. The DBMS may cache intermediate information for the query, such as the execution plan, and execute it faster.

  • Separation of query syntax and parameters protects against SQL injection.

The placeholder format is currently not specified by DBI; in the future, a uniform placeholder syntax may be supported. Consult the backend documentation for the supported formats. For automated testing, backend authors specify the placeholder syntax with the placeholder_pattern tweak. Known examples are:

  • ? (positional matching in order of appearance) in RMySQL and RSQLite

  • \$1 (positional matching by index) in RPostgres and RSQLite

  • :name and \$name (named matching) in RSQLite

Value

dbBind() returns the result set, invisibly, for queries issued by dbSendQuery() and also for data manipulation statements issued by dbSendStatement(). Calling dbBind() for a query without parameters raises an error. Binding too many or not enough values, or parameters with wrong names or unequal length, also raises an error. If the placeholders in the query are named, all parameter values must have names (which must not be empty or NA), and vice versa, otherwise an error is raised. The behavior for mixing placeholders of different types (in particular mixing positional and named placeholders) is not specified.

Calling dbBind() on a result set already cleared by dbClearResult() also raises an error.

Specification

DBI clients execute parametrized statements as follows:

  1. Call dbSendQuery() or dbSendStatement() with a query or statement that contains placeholders, store the returned DBIResult object in a variable. Mixing placeholders (in particular, named and unnamed ones) is not recommended. It is good practice to register a call to dbClearResult() via on.exit() right after calling dbSendQuery() or dbSendStatement() (see the last enumeration item). Until dbBind() has been called, the returned result set object has the following behavior:

    • dbFetch() raises an error (for dbSendQuery())

    • dbGetRowCount() returns zero (for dbSendQuery())

    • dbGetRowsAffected() returns an integer NA (for dbSendStatement())

    • dbIsValid() returns TRUE

    • dbHasCompleted() returns FALSE

  2. Construct a list with parameters that specify actual values for the placeholders. The list must be named or unnamed, depending on the kind of placeholders used. Named values are matched to named parameters, unnamed values are matched by position in the list of parameters. All elements in this list must have the same lengths and contain values supported by the backend; a data.frame is internally stored as such a list. The parameter list is passed to a call to dbBind() on the DBIResult object.

  3. Retrieve the data or the number of affected rows from the DBIResult object.

    • For queries issued by dbSendQuery(), call dbFetch().

    • For statements issued by dbSendStatements(), call dbGetRowsAffected(). (Execution begins immediately after the dbBind() call, the statement is processed entirely before the function returns.)

  4. Repeat 2. and 3. as necessary.

  5. Close the result set via dbClearResult().

The elements of the params argument do not need to be scalars, vectors of arbitrary length (including length 0) are supported. For queries, calling dbFetch() binding such parameters returns concatenated results, equivalent to binding and fetching for each set of values and connecting via rbind(). For data manipulation statements, dbGetRowsAffected() returns the total number of rows affected if binding non-scalar parameters. dbBind() also accepts repeated calls on the same result set for both queries and data manipulation statements, even if no results are fetched between calls to dbBind().

If the placeholders in the query are named, their order in the params argument is not important.

At least the following data types are accepted on input (including NA):

  • integer

  • numeric

  • logical for Boolean values

  • character

  • factor (bound as character, with warning)

  • Date

  • POSIXct timestamps

  • POSIXlt timestamps

  • lists of raw for blobs (with NULL entries for SQL NULL values)

  • objects of type blob::blob

Send query, retrieve results and then clear result set

This section describes the behavior of the following method:

Description

Returns the result of a query as a data frame. dbGetQuery() comes with a default implementation (which should work with most backends) that calls dbSendQuery(), then dbFetch(), ensuring that the result is always free-d by dbClearResult().

Arguments

conn A DBIConnection object, as returned by dbConnect().
statement a character string containing SQL.
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbGetQuery() generic (to improve compatibility across backends) but are part of the DBI specification:

  • n (default: -1)

  • params (default: NULL)

  • immediate (default: NULL)

They must be provided as named arguments. See the “Specification” and “Value” sections for details on their usage.

Specification

A column named row_names is treated like any other column.

The n argument specifies the number of rows to be fetched. If omitted, fetching multi-row queries with one or more columns returns the entire result. A value of Inf for the n argument is supported and also returns the full result. If more rows than available are fetched (by passing a too large value for n), the result is returned in full without warning. If zero rows are requested, the columns of the data frame are still fully typed. Fetching fewer rows than available is permitted, no warning is issued.

The param argument allows passing query parameters, see dbBind() for details.

Specification for the immediate argument

The immediate argument supports distinguishing between “direct” and “prepared” APIs offered by many database drivers. Passing immediate = TRUE leads to immediate execution of the query or statement, via the “direct” API (if supported by the driver). The default NULL means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct immediate argument. Examples for possible behaviors:

  1. DBI backend defaults to immediate = TRUE internally

    1. A query without parameters is passed: query is executed

    2. A query with parameters is passed:

      1. params not given: rejected immediately by the database because of a syntax error in the query, the backend tries immediate = FALSE (and gives a message)

      2. params given: query is executed using immediate = FALSE

  2. DBI backend defaults to immediate = FALSE internally

    1. A query without parameters is passed:

      1. simple query: query is executed

      2. “special” query (such as setting a config options): fails, the backend tries immediate = TRUE (and gives a message)

    2. A query with parameters is passed:

      1. params not given: waiting for parameters via dbBind()

      2. params given: query is executed

Details

This method is for SELECT queries only (incl. other SQL statements that return a SELECT-alike result, e. g. execution of a stored procedure).

To execute a stored procedure that does not return a result set, use dbExecute().

Some backends may support data manipulation statements through this method for compatibility reasons. However, callers are strongly advised to use dbExecute() for data manipulation statements.

Value

dbGetQuery() always returns a data.frame with as many rows as records were fetched and as many columns as fields in the result set, even if the result is a single value or has one or zero rows. An error is raised when issuing a query over a closed or invalid connection, if the syntax of the query is invalid, or if the query is not a non-NA string. If the n argument is not an atomic whole number greater or equal to -1 or Inf, an error is raised, but a subsequent call to dbGetQuery() with proper n argument succeeds.

Implementation notes

Subclasses should override this method only if they provide some sort of performance optimization.

Execute a data manipulation statement on a given database connection

This section describes the behavior of the following method:

Description

The dbSendStatement() method only submits and synchronously executes the SQL data manipulation statement (e.g., UPDATE, DELETE, INSERT INTO, DROP TABLE, …) to the database engine. To query the number of affected rows, call dbGetRowsAffected() on the returned result object. You must also call dbClearResult() after that. For interactive use, you should almost always prefer dbExecute().

Arguments

conn A DBIConnection object, as returned by dbConnect().
statement a character string containing SQL.
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbSendStatement() generic (to improve compatibility across backends) but are part of the DBI specification:

  • params (default: NULL)

  • immediate (default: NULL)

They must be provided as named arguments. See the “Specification” sections for details on their usage.

Specification

No warnings occur under normal conditions. When done, the DBIResult object must be cleared with a call to dbClearResult(). Failure to clear the result set leads to a warning when the connection is closed. If the backend supports only one open result set per connection, issuing a second query invalidates an already open result set and raises a warning. The newly opened result set is valid and must be cleared with dbClearResult().

The param argument allows passing query parameters, see dbBind() for details.

Specification for the immediate argument

The immediate argument supports distinguishing between “direct” and “prepared” APIs offered by many database drivers. Passing immediate = TRUE leads to immediate execution of the query or statement, via the “direct” API (if supported by the driver). The default NULL means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct immediate argument. Examples for possible behaviors:

  1. DBI backend defaults to immediate = TRUE internally

    1. A query without parameters is passed: query is executed

    2. A query with parameters is passed:

      1. params not given: rejected immediately by the database because of a syntax error in the query, the backend tries immediate = FALSE (and gives a message)

      2. params given: query is executed using immediate = FALSE

  2. DBI backend defaults to immediate = FALSE internally

    1. A query without parameters is passed:

      1. simple query: query is executed

      2. “special” query (such as setting a config options): fails, the backend tries immediate = TRUE (and gives a message)

    2. A query with parameters is passed:

      1. params not given: waiting for parameters via dbBind()

      2. params given: query is executed

Details

dbSendStatement() comes with a default implementation that simply forwards to dbSendQuery(), to support backends that only implement the latter.

Value

dbSendStatement() returns an S4 object that inherits from DBIResult. The result set can be used with dbGetRowsAffected() to determine the number of rows affected by the query. Once you have finished using a result, make sure to clear it with dbClearResult(). An error is raised when issuing a statement over a closed or invalid connection, or if the statement is not a non-NA string. An error is also raised if the syntax of the query is invalid and all query parameters are given (by passing the params argument) or the immediate argument is set to TRUE.

Execute an update statement, query number of rows affected, and then close result set

This section describes the behavior of the following method:

Description

Executes a statement and returns the number of rows affected. dbExecute() comes with a default implementation (which should work with most backends) that calls dbSendStatement(), then dbGetRowsAffected(), ensuring that the result is always free-d by dbClearResult().

Arguments

conn A DBIConnection object, as returned by dbConnect().
statement a character string containing SQL.
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbExecute() generic (to improve compatibility across backends) but are part of the DBI specification:

  • params (default: NULL)

  • immediate (default: NULL)

They must be provided as named arguments. See the “Specification” sections for details on their usage.

Specification

The param argument allows passing query parameters, see dbBind() for details.

Specification for the immediate argument

The immediate argument supports distinguishing between “direct” and “prepared” APIs offered by many database drivers. Passing immediate = TRUE leads to immediate execution of the query or statement, via the “direct” API (if supported by the driver). The default NULL means that the backend should choose whatever API makes the most sense for the database, and (if relevant) tries the other API if the first attempt fails. A successful second attempt should result in a message that suggests passing the correct immediate argument. Examples for possible behaviors:

  1. DBI backend defaults to immediate = TRUE internally

    1. A query without parameters is passed: query is executed

    2. A query with parameters is passed:

      1. params not given: rejected immediately by the database because of a syntax error in the query, the backend tries immediate = FALSE (and gives a message)

      2. params given: query is executed using immediate = FALSE

  2. DBI backend defaults to immediate = FALSE internally

    1. A query without parameters is passed:

      1. simple query: query is executed

      2. “special” query (such as setting a config options): fails, the backend tries immediate = TRUE (and gives a message)

    2. A query with parameters is passed:

      1. params not given: waiting for parameters via dbBind()

      2. params given: query is executed

Details

You can also use dbExecute() to call a stored procedure that performs data manipulation or other actions that do not return a result set. To execute a stored procedure that returns a result set use dbGetQuery() instead.

Value

dbExecute() always returns a scalar numeric that specifies the number of rows affected by the statement. An error is raised when issuing a statement over a closed or invalid connection, if the syntax of the statement is invalid, or if the statement is not a non-NA string.

Implementation notes

Subclasses should override this method only if they provide some sort of performance optimization.

Quote literal strings

This section describes the behavior of the following method:

Description

Call this method to generate a string that is suitable for use in a query as a string literal, to make sure that you generate valid SQL and protect against SQL injection attacks.

Arguments

conn A DBIConnection object, as returned by dbConnect().
x A character vector to quote as string.
... Other arguments passed on to methods.

Value

dbQuoteString() returns an object that can be coerced to character, of the same length as the input. For an empty character vector this function returns a length-0 object.

When passing the returned object again to dbQuoteString() as x argument, it is returned unchanged. Passing objects of class SQL should also return them unchanged. (For backends it may be most convenient to return SQL objects to achieve this behavior, but this is not required.)

Specification

The returned expression can be used in a SELECT ... query, and for any scalar character x the value of dbGetQuery(paste0("SELECT ", dbQuoteString(x)))[[1]] must be identical to x, even if x contains spaces, tabs, quotes (single or double), backticks, or newlines (in any combination) or is itself the result of a dbQuoteString() call coerced back to character (even repeatedly). If x is NA, the result must merely satisfy is.na(). The strings "NA" or "NULL" are not treated specially.

NA should be translated to an unquoted SQL NULL, so that the query SELECT * FROM (SELECT 1) a WHERE ... IS NULL returns one row.

Passing a numeric, integer, logical, or raw vector, or a list for the x argument raises an error.

Quote identifiers

This section describes the behavior of the following method:

Description

Call this method to generate a string that is suitable for use in a query as a column or table name, to make sure that you generate valid SQL and protect against SQL injection attacks. The inverse operation is dbUnquoteIdentifier().

Methods in other packages

  • RSQLite::dbQuoteIdentifier("SQLiteConnection", "SQL")

  • RSQLite::dbQuoteIdentifier("SQLiteConnection", "character")

Arguments

conn A DBIConnection object, as returned by dbConnect().
x A character vector, SQL or Id object to quote as identifier.
... Other arguments passed on to methods.

Value

dbQuoteIdentifier() returns an object that can be coerced to character, of the same length as the input. For an empty character vector this function returns a length-0 object. The names of the input argument are preserved in the output. When passing the returned object again to dbQuoteIdentifier() as x argument, it is returned unchanged. Passing objects of class SQL should also return them unchanged. (For backends it may be most convenient to return SQL objects to achieve this behavior, but this is not required.)

An error is raised if the input contains NA, but not for an empty string.

Specification

Calling dbGetQuery() for a query of the format SELECT 1 AS ... returns a data frame with the identifier, unquoted, as column name. Quoted identifiers can be used as table and column names in SQL queries, in particular in queries like SELECT 1 AS ... and SELECT * FROM (SELECT 1) .... The method must use a quoting mechanism that is unambiguously different from the quoting mechanism used for strings, so that a query like SELECT ... FROM (SELECT 1 AS ...) throws an error if the column names do not match.

The method can quote column names that contain special characters such as a space, a dot, a comma, or quotes used to mark strings or identifiers, if the database supports this. In any case, checking the validity of the identifier should be performed only when executing a query, and not by dbQuoteIdentifier().

Copy data frames from database tables

This section describes the behavior of the following method:

Description

Reads a database table to a data frame, optionally converting a column to row names and converting the column names to valid R identifiers.

Methods in other packages

  • RSQLite::dbReadTable("SQLiteConnection", "character")

Arguments

conn A DBIConnection object, as returned by dbConnect().
name A character string specifying the unquoted DBMS table name, or the result of a call to dbQuoteIdentifier().
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbReadTable() generic (to improve compatibility across backends) but are part of the DBI specification:

  • row.names (default: FALSE)

  • check.names

They must be provided as named arguments. See the “Value” section for details on their usage.

Specification

The name argument is processed as follows, to support databases that allow non-syntactic names for their objects:

  • If an unquoted table name as string: dbReadTable() will do the quoting, perhaps by calling dbQuoteIdentifier(conn, x = name)

  • If the result of a call to dbQuoteIdentifier(): no more quoting is done

Value

dbReadTable() returns a data frame that contains the complete data from the remote table, effectively the result of calling dbGetQuery() with SELECT * FROM <name>. An error is raised if the table does not exist. An empty table is returned as a data frame with zero rows.

The presence of rownames depends on the row.names argument, see sqlColumnToRownames() for details:

  • If FALSE or NULL, the returned data frame doesn’t have row names.

  • If TRUE, a column named “row_names” is converted to row names, an error is raised if no such column exists.

  • If NA, a column named “row_names” is converted to row names if it exists, otherwise no translation occurs.

  • If a string, this specifies the name of the column in the remote table that contains the row names, an error is raised if no such column exists.

The default is row.names = FALSE.

If the database supports identifiers with special characters, the columns in the returned data frame are converted to valid R identifiers if the check.names argument is TRUE, otherwise non-syntactic column names can be returned unquoted.

An error is raised when calling this method for a closed or invalid connection. An error is raised if name cannot be processed with dbQuoteIdentifier() or if this results in a non-scalar. Unsupported values for row.names and check.names (non-scalars, unsupported data types, NA for check.names) also raise an error.

Copy data frames to database tables

This section describes the behavior of the following method:

Description

Writes, overwrites or appends a data frame to a database table, optionally converting row names to a column and specifying SQL data types for fields. New code should prefer dbCreateTable() and dbAppendTable().

Methods in other packages

  • RSQLite::dbWriteTable("SQLiteConnection", "character", "character")

  • RSQLite::dbWriteTable("SQLiteConnection", "character", "data.frame")

Arguments

conn A DBIConnection object, as returned by dbConnect().
name A character string specifying the unquoted DBMS table name, or the result of a call to dbQuoteIdentifier().
value a data.frame (or coercible to data.frame).
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbWriteTable() generic (to improve compatibility across backends) but are part of the DBI specification:

  • row.names (default: FALSE)

  • overwrite (default: FALSE)

  • append (default: FALSE)

  • field.types (default: NULL)

  • temporary (default: FALSE)

They must be provided as named arguments. See the “Specification” and “Value” sections for details on their usage.

Specification

The name argument is processed as follows, to support databases that allow non-syntactic names for their objects:

  • If an unquoted table name as string: dbWriteTable() will do the quoting, perhaps by calling dbQuoteIdentifier(conn, x = name)

  • If the result of a call to dbQuoteIdentifier(): no more quoting is done

If the overwrite argument is TRUE, an existing table of the same name will be overwritten. This argument doesn’t change behavior if the table does not exist yet.

If the append argument is TRUE, the rows in an existing table are preserved, and the new data are appended. If the table doesn’t exist yet, it is created.

If the temporary argument is TRUE, the table is not available in a second connection and is gone after reconnecting. Not all backends support this argument. A regular, non-temporary table is visible in a second connection and after reconnecting to the database.

SQL keywords can be used freely in table names, column names, and data. Quotes, commas, and spaces can also be used in the data, and, if the database supports non-syntactic identifiers, also for table names and column names.

The following data types must be supported at least, and be read identically with dbReadTable():

  • integer

  • numeric (the behavior for Inf and NaN is not specified)

  • logical

  • NA as NULL

  • 64-bit values (using "bigint" as field type); the result can be

    • converted to a numeric, which may lose precision,

    • converted a character vector, which gives the full decimal representation

    • written to another table and read again unchanged

  • character (in both UTF-8 and native encodings), supporting empty strings

  • factor (returned as character)

  • list of raw (if supported by the database)

  • objects of type blob::blob (if supported by the database)

  • date (if supported by the database; returned as Date)

  • time (if supported by the database; returned as objects that inherit from difftime)

  • timestamp (if supported by the database; returned as POSIXct respecting the time zone but not necessarily preserving the input time zone)

Mixing column types in the same table is supported.

The field.types argument must be a named character vector with at most one entry for each column. It indicates the SQL data type to be used for a new column. If a column is missed from field.types, the type is inferred from the input data with dbDataType().

The interpretation of rownames depends on the row.names argument, see sqlRownamesToColumn() for details:

  • If FALSE or NULL, row names are ignored.

  • If TRUE, row names are converted to a column named “row_names”, even if the input data frame only has natural row names from 1 to nrow(...).

  • If NA, a column named “row_names” is created if the data has custom row names, no extra column is created in the case of natural row names.

  • If a string, this specifies the name of the column in the remote table that contains the row names, even if the input data frame only has natural row names.

The default is row.names = FALSE.

Value

dbWriteTable() returns TRUE, invisibly. If the table exists, and both append and overwrite arguments are unset, or append = TRUE and the data frame with the new data has different column names, an error is raised; the remote table remains unchanged.

An error is raised when calling this method for a closed or invalid connection. An error is also raised if name cannot be processed with dbQuoteIdentifier() or if this results in a non-scalar. Invalid values for the additional arguments row.names, overwrite, append, field.types, and temporary (non-scalars, unsupported data types, NA, incompatible values, duplicate or missing names, incompatible columns) also raise an error.

List remote tables

This section describes the behavior of the following method:

Description

Returns the unquoted names of remote tables accessible through this connection. This should include views and temporary objects, but not all database backends (in particular RMariaDB and RMySQL) support this.

Methods in other packages

  • RSQLite::dbListTables("SQLiteConnection")

Arguments

conn A DBIConnection object, as returned by dbConnect().
... Other parameters passed on to methods.

Value

dbListTables() returns a character vector that enumerates all tables and views in the database. Tables added with dbWriteTable() are part of the list, including temporary tables if supported by the database. As soon a table is removed from the database, it is also removed from the list of database tables.

The returned names are suitable for quoting with dbQuoteIdentifier(). An error is raised when calling this method for a closed or invalid connection.

Does a table exist?

This section describes the behavior of the following method:

Description

Returns if a table given by name exists in the database.

Methods in other packages

  • RSQLite::dbExistsTable("SQLiteConnection", "character")

Arguments

conn A DBIConnection object, as returned by dbConnect().
name A character string specifying a DBMS table name.
... Other parameters passed on to methods.

Value

dbExistsTable() returns a logical scalar, TRUE if the table or view specified by the name argument exists, FALSE otherwise. This includes temporary tables if supported by the database.

An error is raised when calling this method for a closed or invalid connection. An error is also raised if name cannot be processed with dbQuoteIdentifier() or if this results in a non-scalar.

Specification

The name argument is processed as follows, to support databases that allow non-syntactic names for their objects:

  • If an unquoted table name as string: dbExistsTable() will do the quoting, perhaps by calling dbQuoteIdentifier(conn, x = name)

  • If the result of a call to dbQuoteIdentifier(): no more quoting is done

For all tables listed by dbListTables(), dbExistsTable() returns TRUE.

Remove a table from the database

This section describes the behavior of the following method:

Description

Remove a remote table (e.g., created by dbWriteTable()) from the database.

Methods in other packages

  • RSQLite::dbRemoveTable("SQLiteConnection", "character")

Arguments

conn A DBIConnection object, as returned by dbConnect().
name A character string specifying a DBMS table name.
... Other parameters passed on to methods.

Additional arguments

The following arguments are not part of the dbRemoveTable() generic (to improve compatibility across backends) but are part of the DBI specification:

  • temporary (default: FALSE)

  • fail_if_missing (default: TRUE)

These arguments must be provided as named arguments.

If temporary is TRUE, the call to dbRemoveTable() will consider only temporary tables. Not all backends support this argument. In particular, permanent tables of the same name are left untouched.

If fail_if_missing is FALSE, the call to dbRemoveTable() succeeds if the table does not exist.

Specification

A table removed by dbRemoveTable() doesn’t appear in the list of tables returned by dbListTables(), and dbExistsTable() returns FALSE. The removal propagates immediately to other connections to the same database. This function can also be used to remove a temporary table.

The name argument is processed as follows, to support databases that allow non-syntactic names for their objects:

  • If an unquoted table name as string: dbRemoveTable() will do the quoting, perhaps by calling dbQuoteIdentifier(conn, x = name)

  • If the result of a call to dbQuoteIdentifier(): no more quoting is done

Value

dbRemoveTable() returns TRUE, invisibly. If the table does not exist, an error is raised. An attempt to remove a view with this function may result in an error.

An error is raised when calling this method for a closed or invalid connection. An error is also raised if name cannot be processed with dbQuoteIdentifier() or if this results in a non-scalar.

List field names of a remote table

This section describes the behavior of the following method:

Description

List field names of a remote table

Arguments

conn A DBIConnection object, as returned by dbConnect().
name a character string with the name of the remote table.
... Other parameters passed on to methods.

Value

dbListFields() returns a character vector that enumerates all fields in the table in the correct order. This also works for temporary tables if supported by the database. The returned names are suitable for quoting with dbQuoteIdentifier(). If the table does not exist, an error is raised. Invalid types for the name argument (e.g., character of length not equal to one, or numeric) lead to an error. An error is also raised when calling this method for a closed or invalid connection.

Specification

The name argument can be

  • a string

  • the return value of dbQuoteIdentifier()

  • a value from the table column from the return value of dbListObjects() where is_prefix is FALSE

A column named row_names is treated like any other column.

Is this DBMS object still valid?

This section describes the behavior of the following method:

Description

This generic tests whether a database object is still valid (i.e. it hasn’t been disconnected or cleared).

Methods in other packages

  • RSQLite::dbIsValid("SQLiteConnection")

  • RSQLite::dbIsValid("SQLiteDriver")

  • RSQLite::dbIsValid("SQLiteResult")

Arguments

dbObj An object inheriting from DBIObject, i.e. DBIDriver, DBIConnection, or a DBIResult
... Other arguments to methods.

Value

dbIsValid() returns a logical scalar, TRUE if the object specified by dbObj is valid, FALSE otherwise. A DBIConnection object is initially valid, and becomes invalid after disconnecting with dbDisconnect(). For an invalid connection object (e.g., for some drivers if the object is saved to a file and then restored), the method also returns FALSE. A DBIResult object is valid after a call to dbSendQuery(), and stays valid even after all rows have been fetched; only clearing it with dbClearResult() invalidates it. A DBIResult object is also valid after a call to dbSendStatement(), and stays valid after querying the number of rows affected; only clearing it with dbClearResult() invalidates it. If the connection to the database system is dropped (e.g., due to connectivity problems, server failure, etc.), dbIsValid() should return FALSE. This is not tested automatically.

Completion status

This section describes the behavior of the following method:

Description

This method returns if the operation has completed. A SELECT query is completed if all rows have been fetched. A data manipulation statement is always completed.

Methods in other packages

  • RSQLite::dbHasCompleted("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbHasCompleted() returns a logical scalar. For a query initiated by dbSendQuery() with non-empty result set, dbHasCompleted() returns FALSE initially and TRUE after calling dbFetch() without limit. For a query initiated by dbSendStatement(), dbHasCompleted() always returns TRUE. Attempting to query completion status for a result set cleared with dbClearResult() gives an error.

Specification

The completion status for a query is only guaranteed to be set to FALSE after attempting to fetch past the end of the entire result. Therefore, for a query with an empty result set, the initial return value is unspecified, but the result value is TRUE after trying to fetch only one row. Similarly, for a query with a result set of length n, the return value is unspecified after fetching n rows, but the result value is TRUE after trying to fetch only one more row.

Get the statement associated with a result set

This section describes the behavior of the following method:

Description

Returns the statement that was passed to dbSendQuery() or dbSendStatement().

Methods in other packages

  • RSQLite::dbGetStatement("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbGetStatement() returns a string, the query used in either dbSendQuery() or dbSendStatement(). Attempting to query the statement for a result set cleared with dbClearResult() gives an error.

The number of rows fetched so far

This section describes the behavior of the following method:

Description

Returns the total number of rows actually fetched with calls to dbFetch() for this result set.

Methods in other packages

  • RSQLite::dbGetRowCount("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbGetRowCount() returns a scalar number (integer or numeric), the number of rows fetched so far. After calling dbSendQuery(), the row count is initially zero. After a call to dbFetch() without limit, the row count matches the total number of rows returned. Fetching a limited number of rows increases the number of rows by the number of rows returned, even if fetching past the end of the result set. For queries with an empty result set, zero is returned even after fetching. For data manipulation statements issued with dbSendStatement(), zero is returned before and after calling dbFetch(). Attempting to get the row count for a result set cleared with dbClearResult() gives an error.

The number of rows affected

This section describes the behavior of the following method:

Description

This method returns the number of rows that were added, deleted, or updated by a data manipulation statement.

Methods in other packages

  • RSQLite::dbGetRowsAffected("SQLiteResult")

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbGetRowsAffected() returns a scalar number (integer or numeric), the number of rows affected by a data manipulation statement issued with dbSendStatement(). The value is available directly after the call and does not change after calling dbFetch(). For queries issued with dbSendQuery(), zero is returned before and after the call to dbFetch(). Attempting to get the rows affected for a result set cleared with dbClearResult() gives an error.

Information about result types

This section describes the behavior of the following method:

Description

Produces a data.frame that describes the output of a query. The data.frame should have as many rows as there are output fields in the result set, and each column in the data.frame describes an aspect of the result set field (field name, type, etc.)

Arguments

res An object inheriting from DBIResult.
... Other arguments passed on to methods.

Value

dbColumnInfo() returns a data frame with at least two columns "name" and "type" (in that order) (and optional columns that start with a dot). The "name" and "type" columns contain the names and types of the R columns of the data frame that is returned from dbFetch(). The "type" column is of type character and only for information. Do not compute on the "type" column, instead use dbFetch(res, n = 0) to create a zero-row data frame initialized with the correct data types.

An attempt to query columns for a closed result set raises an error.

Specification

A column named row_names is treated like any other column.

The column names are always consistent with the data returned by dbFetch(). If the query returns unnamed columns, unique non-empty and non-NA names are assigned. In the case of a duplicate column name, the first occurrence retains the original name, and unique names are assigned for the other occurrences. Column names that correspond to SQL or R keywords are left unchanged.

Begin/commit/rollback SQL transactions

This section describes the behavior of the following methods:

Description

A transaction encapsulates several SQL statements in an atomic unit. It is initiated with dbBegin() and either made persistent with dbCommit() or undone with dbRollback(). In any case, the DBMS guarantees that either all or none of the statements have a permanent effect. This helps ensuring consistency of write operations to multiple tables.

Methods in other packages

  • RSQLite::dbBegin("SQLiteConnection")

  • RSQLite::dbCommit("SQLiteConnection")

  • RSQLite::dbRollback("SQLiteConnection")

Arguments

conn A DBIConnection object, as returned by dbConnect().
... Other parameters passed on to methods.

Details

Not all database engines implement transaction management, in which case these methods should not be implemented for the specific DBIConnection subclass.

Value

dbBegin(), dbCommit() and dbRollback() return TRUE, invisibly. The implementations are expected to raise an error in case of failure, but this is not tested. In any way, all generics throw an error with a closed or invalid connection. In addition, a call to dbCommit() or dbRollback() without a prior call to dbBegin() raises an error. Nested transactions are not supported by DBI, an attempt to call dbBegin() twice yields an error.

Specification

Actual support for transactions may vary between backends. A transaction is initiated by a call to dbBegin() and committed by a call to dbCommit(). Data written in a transaction must persist after the transaction is committed. For example, a record that is missing when the transaction is started but is created during the transaction must exist both during and after the transaction, and also in a new connection.

A transaction can also be aborted with dbRollback(). All data written in such a transaction must be removed after the transaction is rolled back. For example, a record that is missing when the transaction is started but is created during the transaction must not exist anymore after the rollback.

Disconnection from a connection with an open transaction effectively rolls back the transaction. All data written in such a transaction must be removed after the transaction is rolled back.

The behavior is not specified if other arguments are passed to these functions. In particular, RSQLite issues named transactions with support for nesting if the name argument is set.

The transaction isolation level is not specified by DBI.

Self-contained SQL transactions

This section describes the behavior of the following methods:

Description

Given that transactions are implemented, this function allows you to pass in code that is run in a transaction. The default method of dbWithTransaction() calls dbBegin() before executing the code, and dbCommit() after successful completion, or dbRollback() in case of an error. The advantage is that you don’t have to remember to do dbBegin() and dbCommit() or dbRollback() – that is all taken care of. The special function dbBreak() allows an early exit with rollback, it can be called only inside dbWithTransaction().

Arguments

conn A DBIConnection object, as returned by dbConnect().
code An arbitrary block of R code.
... Other parameters passed on to methods.

Details

DBI implements dbWithTransaction(), backends should need to override this generic only if they implement specialized handling.

Value

dbWithTransaction() returns the value of the executed code. Failure to initiate the transaction (e.g., if the connection is closed or invalid of if dbBegin() has been called already) gives an error.

Specification

dbWithTransaction() initiates a transaction with dbBegin(), executes the code given in the code argument, and commits the transaction with dbCommit(). If the code raises an error, the transaction is instead aborted with dbRollback(), and the error is propagated. If the code calls dbBreak(), execution of the code stops and the transaction is silently aborted. All side effects caused by the code (such as the creation of new variables) propagate to the calling environment.

DBI/inst/doc/DBI-1.html0000644000176200001440000042324013575372772014043 0ustar liggesusers A Common Database Interface (DBI)

A Common Database Interface (DBI)

R-Databases Special Interest Group

16 June 2003

This document describes a common interface between the S language (in its R and S-Plus implementations) and database management systems (DBMS). The interface defines a small set of classes and methods similar in spirit to Perl’s DBI, Java’s JDBC, Python’s DB-API, and Microsoft’s ODBC.

Version

This document describes version 0.1-6 of the database interface API (application programming interface).

Introduction

The database interface (DBI) separates the connectivity to the DBMS into a “front-end” and a “back-end”. Applications use only the exposed “front-end” API. The facilities that communicate with specific DBMS (Oracle, PostgreSQL, etc.) are provided by “device drivers” that get invoked automatically by the S language evaluator. The following example illustrates some of the DBI capabilities:

(only the first 2 expressions are DBMS-specific – all others are independent of the database engine itself).

Individual DBI drivers need not implement all the features we list below (we indicate those that are optional). Furthermore, drivers may extend the core DBI facilities, but we suggest to have these extensions clearly indicated and documented.

The following are the elements of the DBI:

  1. A set of classes and methods (Section [sec:DBIClasses]) that defines what operations are possible and how they are defined, e.g.:

    • connect/disconnect to the DBMS

    • create and execute statements in the DBMS

    • extract results/output from statements

    • error/exception handling

    • information (meta-data) from database objects

    • transaction management (optional)

    Some things are left explicitly unspecified, e.g., authentication and even the query language, although it is hard to avoid references to SQL and relational database management systems (RDBMS).

  2. Drivers

    Drivers are collection of functions that implement the functionality defined above in the context of specific DBMS, e.g., mSQL, Informix.

  3. Data type mappings (Section [sec:data-mappings].)

    Mappings and conversions between DBMS data types and R/S objects. All drivers should implement the “basic” primitives (see below), but may chose to add user-defined conversion function to handle more generic objects (e.g., factors, ordered factors, time series, arrays, images).

  4. Utilities (Section [sec:utilities].)

    These facilities help with details such as mapping of identifiers between S and DBMS (e.g., _ is illegal in R/S names, and . is used for constructing compound SQL identifiers), etc.

DBI Classes and Methods

The following are the main DBI classes. They need to be extended by individual database back-ends (Sybase, Oracle, etc.) Individual drivers need to provide methods for the generic functions listed here (those methods that are optional are so indicated).

Note: Although R releases prior to 1.4 do not have a formal concept of classes, we will use the syntax of the S Version 4 classes and methods (available in R releases 1.4 and later as library methods) to convey precisely the DBI class hierarchy, its methods, and intended behavior.

The DBI classes are DBIObject, DBIDriver, DBIConnection and DBIResult. All these are virtual classes. Drivers define new classes that extend these, e.g., PgSQLDriver, PgSQLConnection, and so on.

Class hierarchy for the DBI. The top two layers are comprised of virtual classes and each lower layer represents a set of driver-specific implementation classes that provide the functionality defined by the virtual classes above.

Class hierarchy for the DBI. The top two layers are comprised of virtual classes and each lower layer represents a set of driver-specific implementation classes that provide the functionality defined by the virtual classes above.

DBIObject:

Virtual class1 that groups all other DBI classes.

DBIDriver:

Virtual class that groups all DBMS drivers. Each DBMS driver extends this class. Typically generator functions instantiate the actual driver objects, e.g., PgSQL, HDF5, BerkeleyDB.

DBIConnection:

Virtual class that encapsulates connections to DBMS.

DBIResult:

Virtual class that describes the result of a DBMS query or statement.

[Q: Should we distinguish between a simple result of DBMS statements e.g., as delete from DBMS queries (i.e., those that generate data).]

The methods format, print, show, dbGetInfo, and summary are defined (and implemented in the DBI package) for the DBIObject base class, thus available to all implementations; individual drivers, however, are free to override them as they see fit.

format(x, ...):

produces a concise character representation (label) for the DBIObject x.

print(x, ...)/show(x):

prints a one-line identification of the object x.

summary(object, ...):

produces a concise description of the object. The default method for DBIObject simply invokes dbGetInfo(dbObj) and prints the name-value pairs one per line. Individual implementations may tailor this appropriately.

dbGetInfo(dbObj, ...):

extracts information (meta-data) relevant for the DBIObject dbObj. It may return a list of key/value pairs, individual meta-data if supplied in the call, or NULL if the requested meta-data is not available.

Hint: Driver implementations may choose to allow an argument what to specify individual meta-data, e.g., dbGetInfo(drv, what = max.connections).

In the next few sub-sections we describe in detail each of these classes and their methods.

Class DBIObject

This class simply groups all DBI classes, and thus all extend it.

Class DBIDriver

This class identifies the database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.)

The DBI provides the generator dbDriver(driverName) which simply invokes the function driverName, which in turn instantiates the corresponding driver object.

The DBIDriver class defines the following methods:

driverName:

[meth:driverName] initializes the driver code. The name driverName refers to the actual generator function for the DBMS, e.g., RPgSQL, RODBC, HDF5. The driver instance object is used with dbConnect (see page ) for opening one or possibly more connections to one or more DBMS.

dbListConnections(drv, ...):

list of current connections being handled by the drv driver. May be NULL if there are no open connections. Drivers that do not support multiple connections may return the one open connection.

dbGetInfo(dbObj, ...):

returns a list of name-value pairs of information about the driver.

Hint: Useful entries could include

name:

the driver name (e.g., RODBC, RPgSQL);

driver.version:

version of the driver;

DBI.version:

the version of the DBI that the driver implements, e.g., 0.1-2;

client.version:

of the client DBMS libraries (e.g., version of the libpq library in the case of RPgSQL);

max.connections:

maximum number of simultaneous connections;

plus any other relevant information about the implementation, for instance, how the driver handles upper/lower case in identifiers.

dbUnloadDriver(driverName) (optional):

frees all resources (local and remote) used by the driver. Returns a logical to indicate if it succeeded or not.

Class DBIConnection

This virtual class encapsulates the connection to a DBMS, and it provides access to dynamic queries, result sets, DBMS session management (transactions), etc.

Note: Individual drivers are free to implement single or multiple simultaneous connections.

The methods defined by the DBIConnection class include:

dbConnect(drv, ...):

[meth:dbConnect] creates and opens a connection to the database implemented by the driver drv (see Section [sec:DBIDriver]). Each driver will define what other arguments are required, e.g., dbname or dsn for the database name, user, and password. It returns an object that extends DBIConnection in a driver-specific manner (e.g., the MySQL implementation could create an object of class MySQLConnection that extends DBIConnection).

dbDisconnect(conn, ...):

closes the connection, discards all pending work, and frees resources (e.g., memory, sockets). Returns a logical indicating whether it succeeded or not.

dbSendQuery(conn, statement, ...):

submits one statement to the DBMS. It returns a DBIResult object. This object is needed for fetching data in case the statement generates output (see fetch on page ), and it may be used for querying the state of the operation; see dbGetInfo and other meta-data methods on page .

dbGetQuery(conn, statement, ...):

submit, execute, and extract output in one operation. The resulting object may be a data.frame if the statement generates output. Otherwise the return value should be a logical indicating whether the query succeeded or not.

dbGetException(conn, ...):

returns a list with elements errNum and errMsg with the status of the last DBMS statement sent on a given connection (this information may also be provided by the dbGetInfo meta-data function on the conn object.

Hint: The ANSI SQL-92 defines both a status code and an status message that could be return as members of the list.

dbGetInfo(dbObj, ...):

returns a list of name-value pairs describing the state of the connection; it may return one or more meta-data, the actual driver method allows to specify individual pieces of meta-data (e.g., maximum number of open results/cursors).

Hint: Useful entries could include

dbname:

the name of the database in use;

db.version:

the DBMS server version (e.g., “Oracle 8.1.7 on Solaris”;

host:

host where the database server resides;

user:

user name;

password:

password (is this safe?);

plus any other arguments related to the connection (e.g., thread id, socket or TCP connection type).

dbListResults(conn, ...):

list of DBIResult objects currently active on the connection conn. May be NULL if no result set is active on conn. Drivers that implement only one result set per connection could return that one object (no need to wrap it in a list).

Note: The following are convenience methods that simplify the import/export of (mainly) data.frames. The first five methods implement the core methods needed to attach remote DBMS to the S search path. (For details, see Chambers (1991, 1998).)

Hint: For relational DBMS these methods may be easily implemented using the core DBI methods dbConnect, dbSendQuery, and fetch, due to SQL reflectance (i.e., one easily gets this meta-data by querying the appropriate tables on the RDBMS).

dbListTables(conn, ...):

returns a character vector (possibly of zero-length) of object (table) names available on the conn connection.

dbReadTable(conn, name, ...):

imports the data stored remotely in the table name on connection conn. Use the field row.names as the row.names attribute of the output data.frame. Returns a data.frame.

[Q: should we spell out how row.names should be created? E.g., use a field (with unique values) as row.names? Also, should dbReadTable reproduce a data.frame exported with dbWriteTable?]

dbWriteTable(conn, name, value, ...):

write the object value (perhaps after coercing it to data.frame) into the remote object name in connection conn. Returns a logical indicating whether the operation succeeded or not.

dbExistsTable(conn, name, ...):

does remote object name exist on conn? Returns a logical.

dbRemoveTable(conn, name, ...):

removes remote object name on connection conn. Returns a logical indicating whether the operation succeeded or not.

dbListFields(conn, name, ...):

returns a character vector listing the field names of the remote table name on connection conn (see dbColumnInfo() for extracting data type on a table).

Note: The following methods deal with transactions and stored procedures. All these functions are optional.

dbCommit(conn, ...)(optional):

commits pending transaction on the connection and returns TRUE or FALSE depending on whether the operation succeeded or not.

dbRollback(conn, ...)(optional):

undoes current transaction on the connection and returns TRUE or FALSE depending on whether the operation succeeded or not.

dbCallProc(conn, storedProc, ...)(optional):

invokes a stored procedure in the DBMS and returns a DBIResult object.

[Stored procedures are not part of the ANSI SQL-92 standard and vary substantially from one RDBMS to another.]

Deprecated since 2014:

The recommended way of calling a stored procedure is now

  • dbGetQuery if a result set is returned and
  • dbExecute for data manipulation and other cases that do not return a result set.

Class DBIResult

This virtual class describes the result and state of execution of a DBMS statement (any statement, query or non-query). The result set res keeps track of whether the statement produces output for R/S, how many rows were affected by the operation, how many rows have been fetched (if statement is a query), whether there are more rows to fetch, etc.

Note: Individual drivers are free to allow single or multiple active results per connection.

[Q: Should we distinguish between results that return no data from those that return data?]

The class DBIResult defines the following methods:

fetch(res, n, ...):

[meth:fetch] fetches the next n elements (rows) from the result set res and return them as a data.frame. A value of n=-1 is interpreted as “return all elements/rows”.

dbClearResult(res, ...):

flushes any pending data and frees all resources (local and remote) used by the object res on both sides of the connection. Returns a logical indicating success or not.

dbGetInfo(dbObj, ...):

returns a name-value list with the state of the result set.

Hint: Useful entries could include

statement:

a character string representation of the statement being executed;

rows.affected:

number of affected records (changed, deleted, inserted, or extracted);

row.count:

number of rows fetched so far;

has.completed:

has the statement (query) finished?

is.select:

a logical describing whether or not the statement generates output;

plus any other relevant driver-specific meta-data.

dbColumnInfo(res, ...):

produces a data.frame that describes the output of a query. The data.frame should have as many rows as there are output fields in the result set, and each column in the data.frame should describe an aspect of the result set field (field name, type, etc.)

Hint: The data.frame columns could include

field.name:

DBMS field label;

field.type:

DBMS field type (implementation-specific);

data.type:

corresponding R/S data type, e.g., integer;

precision/scale:

(as in ODBC terminology), display width and number of decimal digits, respectively;

nullable:

whether the corresponding field may contain (DBMS) NULL values;

plus other driver-specific information.

dbSetDataMappings(flds, ...)(optional):

defines a conversion between internal DBMS data types and R/S classes. We expect the default mappings (see Section [sec:data-mappings]) to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. [This topic needs further discussion.]

Note: The following are convenience methods that extract information from the result object (they may be implemented by invoking dbGetInfo with appropriate arguments).

dbGetStatement(res, ...)(optional):

returns the DBMS statement (as a character string) associated with the result res.

dbGetRowsAffected(res, ...)(optional):

returns the number of rows affected by the executed statement (number of records deleted, modified, extracted, etc.)

dbHasCompleted(res, ...)(optional):

returns a logical that indicates whether the operation has been completed (e.g., are there more records to be fetched?).

dbGetRowCount(res, ...)(optional):

returns the number of rows fetched so far.

Data Type Mappings

The data types supported by databases are different than the data types in R and S, but the mapping between the “primitive” types is straightforward: Any of the many fixed and varying length character types are mapped to R/S character. Fixed-precision (non-IEEE) numbers are mapped into either doubles (numeric) or long (integer). Notice that many DBMS do not follow the so-called IEEE arithmetic, so there are potential problems with under/overflows and loss of precision, but given the R/S primitive types we cannot do too much but identify these situations and warn the application (how?).

By default dates and date-time objects are mapped to character using the appropriate TO_CHAR function in the DBMS (which should take care of any locale information). Some RDBMS support the type CURRENCY or MONEY which should be mapped to numeric (again with potential round off errors). Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion (as has been done in other inter-systems packages2).

Specifying user-defined conversion functions still needs to be defined.

Utilities

The core DBI implementation should make available to all drivers some common basic utilities. For instance:

dbGetDBIVersion:

returns the version of the currently attached DBI as a string.

dbDataType(dbObj, obj, ...):

returns a string with the (approximately) appropriate data type for the R/S object obj. The DBI can implement this following the ANSI-92 standard, but individual drivers may want/need to extend it to make use of DBMS-specific types.

make.db.names(dbObj, snames, ...):

maps R/S names (identifiers) to SQL identifiers replacing illegal characters (as .) by the legal SQL _.

SQLKeywords(dbObj, ...):

returns a character vector of SQL keywords (reserved words). The default method returns the list of .SQL92Keywords, but drivers should update this vector with the DBMS-specific additional reserved words.

isSQLKeyword(dbObj, name, ...):

for each element in the character vector name determine whether or not it is an SQL keyword, as reported by the generic function SQLKeywords. Returns a logical vector parallel to the input object name.

Open Issues and Limitations

There are a number of issues and limitations that the current DBI conscientiously does not address on the interest of simplicity. We do list here the most important ones.

Non-SQL:

Is it realistic to attempt to encompass non-relational databases, like HDF5, Berkeley DB, etc.?

Security:

allowing users to specify their passwords on R/S scripts may be unacceptable for some applications. We need to consider alternatives where users could store authentication on files (perhaps similar to ODBC’s odbc.ini) with more stringent permissions.

Exceptions:

the exception mechanism is a bit too simple, and it does not provide for information when problems stem from the DBMS interface itself. For instance, under/overflow or loss of precision as we move numeric data from DBMS to the more limited primitives in R/S.

Asynchronous communication:

most DBMS support both synchronous and asynchronous communications, allowing applications to submit a query and proceed while the database server process the query. The application is then notified (or it may need to poll the server) when the query has completed. For large computations, this could be very useful, but the DBI would need to specify how to interrupt the server (if necessary) plus other details. Also, some DBMS require applications to use threads to implement asynchronous communication, something that neither R nor S-Plus currently addresses.

SQL scripts:

the DBI only defines how to execute one SQL statement at a time, forcing users to split SQL scripts into individual statements. We need a mechanism by which users can submit SQL scripts that could possibly generate multiple result sets; in this case we may need to introduce new methods to loop over multiple results (similar to Python’s nextResultSet).

BLOBS/CLOBS:

large objects (both character and binary) present some challenges both to R and S-Plus. It is becoming more common to store images, sounds, and other data types as binary objects in DBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects.

Transactions:

transaction management is not fully described.

Additional methods:

Do we need any additional methods? (e.g., dbListDatabases(conn), dbListTableIndices(conn, name), how do we list all available drivers?)

Bind variables:

the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of R/S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement

  /* SQL */
  SELECT * from emp_table where emp_id = :sampleEmployee

would take the vector sampleEmployee and iterate over each of its elements to get the result. Perhaps the DBI could at some point in the future implement this feature.

Resources

The idea of a common interface to databases has been successfully implemented in various environments, for instance:

Java’s Database Connectivity (JDBC) (www.javasoft.com).

In C through the Open Database Connectivity (ODBC) (www.unixodbc.org).

Python’s Database Application Programming Interface (www.python.org).

Perl’s Database Interface (dbi.perl.org).

Chambers, John M. 1991. “Data Management in S.” Bell Labs, Lucent Technologies.

———. 1998. “Database Classes.” Bell Labs, Lucent Technologies.


  1. A virtual class allows us to group classes that share some common characteristics, even if their implementations are radically different.

  2. Duncan Temple Lang has volunteered to port the data conversion code found in R-Java, R-Perl, and R-Python packages to the DBI

DBI/inst/doc/DBI-proposal.Rmd0000644000176200001440000006646313054310030015275 0ustar liggesusers--- title: "A Common Interface to Relational Databases from R and S -- A Proposal" author: "David James" date: "March 16, 2000" output: rmarkdown::html_vignette bibliography: biblio.bib vignette: > %\VignetteIndexEntry{A Common Interface to Relational Databases from R and S -- A Proposal} %\VignetteEngine{knitr::rmarkdown} --- For too long S and similar data analysis environments have lacked good interfaces to relational database systems (RDBMS). For the last twenty years or so these RDBMS have evolved into highly optimized client-server systems for data storage and manipulation, and currently they serve as repositories for most of the business, industrial, and research “raw” data that analysts work with. Other analysis packages, such as SAS, have traditionally provided good data connectivity, but S and GNU R have relied on intermediate text files as means of importing data (but see @R.imp-exp and @R-dbms.) Although this simple approach works well for relatively modest amounts of mostly static data, it does not scale up to larger amounts of data distributed over machines and locations, nor does it scale up to data that is highly dynamic – situations that are becoming increasingly common. We want to propose a common interface between R/S and RDBMS that would allow users to access data stored on database servers in a uniform and predictable manner irrespective of the database engine. The interface defines a small set of classes and methods similar in spirit to Python’s DB-API, Java’s JDBC, Microsoft’s ODBC, Perl’s DBI, etc., but it conforms to the “whole-object” philosophy so natural in S and R. # Computing with Distributed Data {#sec:distr} As data analysts, we are increasingly faced with the challenge of larger data sources distributed over machines and locations; most of these data sources reside in relational database management systems (RDBMS). These relational databases represent a mature client-server distributed technology that we as analysts could be exploiting more that we’ve done in the past. The relational technology provides a well-defined standard, the ANSI SQL-92 @sql92, both for defining and manipulating data in a highly optimized fashion from virtually any application. In contrast, S and Splus have provided somewhat limited tools for coping with the challenges of larger and distributed data sets (Splus does provide an `import` function to import from databases, but it is quite limited in terms of SQL facilities). The R community has been more resourceful and has developed a number of good libraries for connecting to mSQL, MySQL, PostgreSQL, and ODBC; each library, however, has defined its own interface to each database engine a bit differently. We think it would be to everybody’s advantage to coordinate the definition of a common interface, an effort not unlike those taken in the Python and Perl communities. The goal of a common, seamless access to distributed data is a modest one in our evolution towards a fully distributed computing environment. We recognize the greater goal of distributed computing as the means to fully integrate diverse systems – not just databases – into a truly flexible analysis environment. Good connectivity to databases, however, is of immediate necessity both in practical terms and as a means to help us transition from monolithic, self-contained systems to those in which computations, not only the data, can be carried out in parallel over a wide number of computers and/or systems @duncan2000. Issues of reliability, security, location transparency, persistence, etc., will be new to most of us and working with distributed data may provide a more gradual change to ease in the ultimate goal of full distributed computing. # A Common Interface {#sec:rs-dbi} We believe that a common interface to databases can help users easily access data stored in RDBMS. A common interface would describe, in a uniform way, how to connect to RDBMS, extract meta-data (such as list of available databases, tables, etc.) as well as a uniform way to execute SQL statements and import their output into R and S. The current emphasis is on querying databases and not so much in a full low-level interface for database development as in JDBC or ODBC, but unlike these, we want to approach the interface from the “whole-object” perspective @S4 so natural to R/S and Python – for instance, by fetching all fields and records simultaneously into a single object. The basic idea is to split the interface into a front-end consisting of a few classes and generic functions that users invoke and a back-end set of database-specific classes and methods that implement the actual communication. (This is a very well-known pattern in software engineering, and another good verbatim is the device-independent graphics in R/S where graphics functions produce similar output on a variety of different devices, such X displays, Postscript, etc.) The following verbatim shows the front-end: ``` > mgr <- dbManager("Oracle") > con <- dbConnect(mgr, user = "user", passwd = "passwd") > rs <- dbExecStatement(con, "select fld1, fld2, fld3 from MY_TABLE") > tbls <- fetch(rs, n = 100) > hasCompleted(rs) [1] T > close(rs) > rs <- dbExecStatement(con, "select id_name, q25, q50 from liv2") > res <- fetch(rs) > getRowCount(rs) [1] 73 > close(con) ``` Such scripts should work with other RDBMS (say, MySQL) by replacing the first line with ``` > mgr <- dbManager("MySQL") ``` ## Interface Classes {#sec:rs-dbi-classes} The following are the main RS-DBI classes. They need to be extended by individual database back-ends (MySQL, Oracle, etc.) `dbManager` : Virtual class[^2] extended by actual database managers, e.g., Oracle, MySQL, Informix. `dbConnection` : Virtual class that captures a connection to a database instance[^3]. `dbResult` : Virtual class that describes the result of an SQL statement. `dbResultSet` : Virtual class, extends `dbResult` to fully describe the output of those statements that produce output records, i.e., `SELECT` (or `SELECT`-like) SQL statement. All these classes should implement the methods `show`, `describe`, and `getInfo`: `show` : (`print` in R) prints a one-line identification of the object. `describe` : prints a short summary of the meta-data of the specified object (like `summary` in R/S). `getInfo` : takes an object of one of the above classes and a string specifying a meta-data item, and it returns the corresponding information (`NULL` if unavailable). > mgr <- dbManager("MySQL") > getInfo(mgr, "version") > con <- dbConnect(mgr, ...) > getInfo(con, "type") The reason we implement the meta-data through `getInfo` in this way is to simplify the writing of database back-ends. We don’t want to overwhelm the developers of drivers (ourselves, most likely) with hundreds of methods as in the case of JDBC. In addition, the following methods should also be implemented: `getDatabases` : lists all available databases known to the `dbManager`. `getTables` : lists tables in a database. `getTableFields` : lists the fields in a table in a database. `getTableIndices` : lists the indices defined for a table in a database. These methods may be implemented using the appropriate `getInfo` method above. In the next few sections we describe in detail each of these classes and their methods. ### Class `dbManager` {#sec:dbManager} This class identifies the relational database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.) The `dbManager` class defines the following methods: `load` : initializes the driver code. We suggest having the generator, `dbManager(driver)`, automatically load the driver. `unload` : releases whatever resources the driver is using. `getVersion` : returns the version of the RS-DBI currently implemented, plus any other relevant information about the implementation itself and the RDBMS being used. ### Class `dbConnection` {#sec:dbConnection} This virtual class captures a connection to a RDBMS, and it provides access to dynamic SQL, result sets, RDBMS session management (transactions), etc. Note that the `dbManager` may or may not allow multiple simultaneous connections. The methods it defines include: `dbConnect` : opens a connection to the database `dbname`. Other likely arguments include `host`, `user`, and `password`. It returns an object that extends `dbConnection` in a driver-specific manner (e.g., the MySQL implementation creates a connection of class `MySQLConnection` that extends `dbConnection`). Note that we could separate the steps of connecting to a RDBMS and opening a database there (i.e., opening an *instance*). For simplicity we do the 2 steps in this method. If the user needs to open another instance in the same RDBMS, just open a new connection. `close` : closes the connection and discards all pending work. `dbExecStatement` : submits one SQL statement. It returns a `dbResult` object, and in the case of a `SELECT` statement, the object also inherits from `dbResultSet`. This `dbResultSet` object is needed for fetching the output rows of `SELECT` statements. The result of a non-`SELECT` statement (e.g., `UPDATE, DELETE, CREATE, ALTER`, ...) is defined as the number of rows affected (this seems to be common among RDBMS). `commit` : commits pending transaction (optional). `rollback` : undoes current transaction (optional). `callProc` : invokes a stored procedure in the RDBMS (tentative). Stored procedures are *not* part of the ANSI SQL-92 standard and possibly vary substantially from one RDBMS to another. For instance, Oracle seems to have a fairly decent implementation of stored procedures, but MySQL currently does not support them. `dbExec` : submit an SQL “script” (multiple statements). May be implemented by looping with `dbExecStatement`. `dbNextResultSet` : When running SQL scripts (multiple statements), it closes the current result set in the `dbConnection`, executes the next statement and returns its result set. ### Class `dbResult` {#sec:dbResult} This virtual class describes the result of an SQL statement (any statement) and the state of the operation. Non-query statements (e.g., `CREATE`, `UPDATE`, `DELETE`) set the “completed” state to 1, while `SELECT` statements to 0. Error conditions set this slot to a negative number. The `dbResult` class defines the following methods: `getStatement` : returns the SQL statement associated with the result set. `getDBConnection` : returns the `dbConnection` associated with the result set. `getRowsAffected` : returns the number of rows affected by the operation. `hasCompleted` : was the operation completed? `SELECT`’s, for instance, are not completed until their output rows are all fetched. `getException` : returns the status of the last SQL statement on a given connection as a list with two members, status code and status description. ### Class `dbResultSet` {#sec:dbResultSet} This virtual class extends `dbResult`, and it describes additional information from the result of a `SELECT` statement and the state of the operation. The `completed` state is set to 0 so long as there are pending rows to fetch. The `dbResultSet` class defines the following additional methods: `getRowCount` : returns the number of rows fetched so far. `getNullOk` : returns a logical vector with as many elements as there are fields in the result set, each element describing whether the corresponding field accepts `NULL` values. `getFields` : describes the `SELECT`ed fields. The description includes field names, RDBMS internal data types, internal length, internal precision and scale, null flag (i.e., column allows `NULL`’s), and corresponding S classes (which can be over-ridden with user-provided classes). The current MySQL and Oracle implementations define a `dbResultSet` as a named list with the following elements: `connection`: : the connection object associated with this result set; `statement`: : a string with the SQL statement being processed; `description`: : a field description `data.frame` with as many rows as there are fields in the `SELECT` output, and columns specifying the `name`, `type`, `length`, `precision`, `scale`, `Sclass` of the corresponding output field. `rowsAffected`: : the number of rows that were affected; `rowCount`: : the number of rows so far fetched; `completed`: : a logical value describing whether the operation has completed or not. `nullOk`: : a logical vector specifying whether the corresponding column may take NULL values. The methods above are implemented as accessor functions to this list in the obvious way. `setDataMappings` : defines a conversion between internal RDBMS data types and R/S classes. We expect the default mappings to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. (See Section [sec:mappings] for details.) `close` : closes the result set and frees resources both in R/S and the RDBMS. `fetch` : extracts the next `max.rec` records (-1 means all). ## Data Type Mappings {#sec:mappings} The data types supported by databases are slightly different than the data types in R and S, but the mapping between them is straightforward: Any of the many fixed and varying length character types are mapped to R/S `character`. Fixed-precision (non-IEEE) numbers are mapped into either doubles (`numeric`) or long (`integer`). Dates are mapped to character using the appropriate `TO_CHAR` function in the RDBMS (which should take care of any locale information). Some RDBMS support the type `CURRENCY` or `MONEY` which should be mapped to `numeric`. Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion as follows: 1. run the query (either with `dbExec` or `dbExecStatement`): > rs <- dbExecStatement(con, "select whatever-You-need") 2. extract the output field definitions > flds <- getFields(rs) 3. replace the class generator in the, say 3rd field, by the user own generator: > flds[3, "Sclass"] # default mapping [1] "character" by > flds[3, "Sclass"] <- "myOwnGeneratorFunction" 4. set the new data mapping prior to fetching > setDataMappings(resutlSet, flds) 5. fetch the rows and store in a `data.frame` > data <- fetch(resultSet) ## Open Issues {#sec:open-issues} We may need to provide some additional utilities, for instance to convert dates, to escape characters such as quotes and slashes in query strings, to strip excessive blanks from some character fields, etc. We need to decide whether we provide hooks so these conversions are done at the C level, or do all the post-processing in R or S. Another issue is what kind of data object is the output of an SQL query. Currently the MySQL and Oracle implementations return data as a `data.frame`; data frames have the slight inconvenience that they automatically re-label the fields according to R/S syntax, changing the actual RDBMS labels of the variables; the issue of non-numeric data being coerced into factors automatically “at the drop of a hat” (as someone in s-news wrote) is also annoying. The execution of SQL scripts is not fully described. The method that executes scripts could run individual statements without returning until it encounters a query (`SELECT`-like) statement. At that point it could return that one result set. The application is then responsible for fetching these rows, and then for invoking `dbNextResultSet` on the opened `dbConnection` object to repeat the `dbExec`/`fetch` loop until it encounters the next `dbResultSet`. And so on. Another (potentially very expensive) alternative would be to run all statements sequentially and return a list of `data.frame`s, each element of the list storing the result of each statement. Binary objects and large objects present some challenges both to R and S. It is becoming more common to store images, sounds, and other data types as binary objects in RDBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects – perhaps tentatively not in full generality. Large objects could be fetched by repeatedly invoking a specified R/S function that takes as argument chunks of a specified number of raw bytes. In the case of S4 (and Splus5.x) the RS-DBI implementation can write into an opened connection for which the user has defined a reader (but can we guarantee that we won’t overflow the connection?). In the case of R it is not clear what data type binary large objects (BLOB) should be mapped into. ## Limitations {#sec:limitations} These are some of the limitations of the current interface definition: - we only allow one SQL statement at a time, forcing users to split SQL scripts into individual statements; - transaction management is not fully described; - the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement /* SQL */ SELECT * from emp_table where emp_id = :sampleEmployee would take the vector `sampleEmployee` and iterate over each of its elements to get the result. Perhaps RS-DBI could at some point in the future implement this feature. # Other Approaches The high-level, front-end description of RS-DBI is the more critical aspect of the interface. Details on how to actually implement this interface may change over time. The approach described in this document based on one back-end driver per RDBMS is reasonable, but not the only approach – we simply felt that a simpler approach based on well-understood and self-contained tools (R, S, and C API’s) would be a better start. Nevertheless we want to briefly mention a few alternatives that we considered and tentatively decided against, but may quite possibly re-visit in the near future. ## Open Database Connectivity (ODBC) {#sec:odbc} The ODBC protocol was developed by Microsoft to allow connectivity among C/C++ applications and RDBMS. As you would expect, originally implementations of the ODBC were only available under Windows environments. There are various effort to create a Unix implementation (see [the Unix ODBC](http://www.unixodbc.org/) web-site and @odbc.lj). This approach looks promising because it allows us to write only one back-end, instead of one per RDBMS. Since most RDBMS already provide ODBC drivers, this could greatly simplify development. Unfortunately, the Unix implementation of ODBC was not mature enough at the time we looked at it, a situation we expect will change in the next year or so. At that point we will need to re-evaluate it to make sure that such an ODBC interface does not penalize the interface in terms of performance, ease of use, portability among the various Unix versions, etc. ## Java Database Connectivity (JDBC) {#sec:jdbc} Another protocol, the Java database connectivity, is very well-done and supported by just about every RDBMS. The issue with JDBC is that as of today neither S nor R (which are written in C) interfaces cleanly with Java. There are several efforts (some in a quite fairly advanced state) to allow S and R to invoke Java methods. Once this interface is widely available in Splus5x and R we will need to re-visit this issue again and study the performance, usability, etc., of JDBC as a common back-end to the RS-DBI. ## CORBA and a 3-tier Architecture {#sec:corba} Yet another approach is to move the interface to RDBMS out of R and S altogether into a separate system or server that would serve as a proxy between R/S and databases. The communication to this middle-layer proxy could be done through CORBA [@s-corba.98, @corba:siegel.96], Java’s RMI, or some other similar technology. Such a design could be very flexible, but the CORBA facilities both in R and S are not widely available yet, and we do not know whether this will be made available to Splus5 users from MathSoft. Also, my experience with this technology is rather limited. On the other hand, this 3-tier architecture seem to offer the most flexibility to cope with very large distributed databases, not necessarily relational. # Resources {#sec:resources} The latest documentation and software on the RS-DBI was available at www.omegahat.net (link dead now: `http://www.omegahat.net/contrib/RS-DBI/index.html`). The R community has developed interfaces to some databases: [RmSQL](https://cran.r-project.org/src/contrib/Archive/RmSQL/) is an interface to the [mSQL](http://www.Hughes.com.au) database written by Torsten Hothorn; [RPgSQL](http://www.nceas.ucsb.edu/~keitt/R) is an interface to [PostgreSQL](http://www.postgreSQL.org) and was written by Timothy H. Keitt; [RODBC](http://www.stats.ox.ac.uk/pub/bdr) is an interface to ODBC, and it was written by [Michael Lapsley](mailto:mlapsley@sthelier.sghms.ac.uk). (For more details on all these see @R.imp-exp.) The are R and S-Plus interfaces to [MySQL](http://www.mysql.org) that follow the propose RS-DBI API described here; also, there’s an S-Plus interface SOracle @RS-Oracle to [Oracle](http://www.oracle.com) (we expect to have an R implementation soon.) The idea of a common interface to databases has been successfully implemented in Java’s Database Connectivity (JDBC) ([www.javasoft.com](http://www.javasoft.com/products/jdbc/index.html)), in C through the Open Database Connectivity (ODBC) ([www.unixodbc.org](http://www.unixodbc.org/)), in Python’s Database Application Programming Interface ([www.python.org](http://www.python.org)), and in Perl’s Database Interface ([www.cpan.org](http://www.cpan.org)). # Acknowledgements The R/S database interface came about from suggestions, comments, and discussions with [John M. Chambers](mailto:jmc@research.bell-labs.com) and [Duncan Temple Lang](mailto:duncan@research.bell-labs.com) in the context of the Omega Project for Statistical Computing. [Doug Bates](mailto:bates@stat.wisc.edu) and [Saikat DebRoy](mailto:saikat@stat.wisc.edu) ported (and greatly improved) the first MySQL implementation to R. # The S Version 4 Definitions The following code is meant to serve as a detailed description of the R/S to database interface. We decided to use S4 (instead of R or S version 3) because its clean syntax help us to describe easily the classes and methods that form the RS-DBI, and also to convey the inter-class relationships. ```R ## Define all the classes and methods to be used by an ## implementation of the RS-DataBase Interface. Mostly, ## these classes are virtual and each driver should extend ## them to provide the actual implementation. ## Class: dbManager ## This class identifies the DataBase Management System ## (Oracle, MySQL, Informix, PostgreSQL, etc.) setClass("dbManager", VIRTUAL) setGeneric("load", def = function(dbMgr,...) standardGeneric("load") ) setGeneric("unload", def = function(dbMgr,...) standardGeneric("unload") ) setGeneric("getVersion", def = function(dbMgr,...) standardGeneric("getVersion") ) ## Class: dbConnections ## This class captures a connection to a database instance. setClass("dbConnection", VIRTUAL) setGeneric("dbConnection", def = function(dbMgr, ...) standardGeneric("dbConnection") ) setGeneric("dbConnect", def = function(dbMgr, ...) standardGeneric("dbConnect") ) setGeneric("dbExecStatement", def = function(con, statement, ...) standardGeneric("dbExecStatement") ) setGeneric("dbExec", def = function(con, statement, ...) standardGeneric("dbExec") ) setGeneric("getResultSet", def = function(con, ..) standardGeneric("getResultSet") ) setGeneric("commit", def = function(con, ...) standardGeneric("commit") ) setGeneric("rollback", def = function(con, ...) standardGeneric("rollback") ) setGeneric("callProc", def = function(con, ...) standardGeneric("callProc") ) setMethod("close", signature = list(con="dbConnection", type="missing"), def = function(con, type) NULL ) ## Class: dbResult ## This is a base class for arbitrary results from the RDBMS ## (INSERT, UPDATE, DELETE). SELECTs (and SELECT-like) ## statements produce "dbResultSet" objects, which extend ## dbResult. setClass("dbResult", VIRTUAL) setMethod("close", signature = list(con="dbResult", type="missing"), def = function(con, type) NULL ) ## Class: dbResultSet ## Note that we define a resultSet as the result of a ## SELECT SQL statement. setClass("dbResultSet", "dbResult") setGeneric("fetch", def = function(resultSet,n,...) standardGeneric("fetch") ) setGeneric("hasCompleted", def = function(object, ...) standardGeneric("hasCompleted") ) setGeneric("getException", def = function(object, ...) standardGeneric("getException") ) setGeneric("getDBconnection", def = function(object, ...) standardGeneric("getDBconnection") ) setGeneric("setDataMappings", def = function(resultSet, ...) standardGeneric("setDataMappings") ) setGeneric("getFields", def = function(object, table, dbname, ...) standardGeneric("getFields") ) setGeneric("getStatement", def = function(object, ...) standardGeneric("getStatement") ) setGeneric("getRowsAffected", def = function(object, ...) standardGeneric("getRowsAffected") ) setGeneric("getRowCount", def = function(object, ...) standardGeneric("getRowCount") ) setGeneric("getNullOk", def = function(object, ...) standardGeneric("getNullOk") ) ## Meta-data: setGeneric("getInfo", def = function(object, ...) standardGeneric("getInfo") ) setGeneric("describe", def = function(object, verbose=F, ...) standardGeneric("describe") ) setGeneric("getCurrentDatabase", def = function(object, ...) standardGeneric("getCurrentDatabase") ) setGeneric("getDatabases", def = function(object, ...) standardGeneric("getDatabases") ) setGeneric("getTables", def = function(object, dbname, ...) standardGeneric("getTables") ) setGeneric("getTableFields", def = function(object, table, dbname, ...) standardGeneric("getTableFields") ) setGeneric("getTableIndices", def = function(object, table, dbname, ...) standardGeneric("getTableIndices") ) ``` [^2]: A virtual class allows us to group classes that share some common functionality, e.g., the virtual class “`dbConnection`” groups all the connection implementations by Informix, Ingres, DB/2, Oracle, etc. Although the details will vary from one RDBMS to another, the defining characteristic of these objects is what a virtual class captures. R and S version 3 do not explicitly define virtual classes, but they can easily implement the idea through inheritance. [^3]: The term “database” is sometimes (confusingly) used both to denote the RDBMS, such as Oracle, MySQL, and also to denote a particular database instance under a RDBMS, such as “opto” or “sales” databases under the same RDBMS. DBI/inst/doc/backend.Rmd0000644000176200001440000002340513267404720014436 0ustar liggesusers --- title: "Implementing a new backend" author: "Hadley Wickham" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Implementing a new backend} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r, echo = FALSE} library(DBI) knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` The goal of this document is to help you implement a new backend for DBI. If you are writing a package that connects a database to R, I highly recommend that you make it DBI compatible because it makes your life easier by spelling out exactly what you need to do. The consistent interface provided by DBI makes it easier for you to implement the package (because you have fewer arbitrary choices to make), and easier for your users (because it follows a familiar pattern). In addition, the `DBItest` package provides test cases which you can easily incorporate in your package. I'll illustrate the process using a fictional database called Kazam. ## Getting started Start by creating a package. It's up to you what to call the package, but following the existing pattern of `RSQLite`, `RMySQL`, `RPostgres` and `ROracle` will make it easier for people to find it. For this example, I'll call my package `RKazam`. In your `DESCRIPTION`, make sure to include: ```yaml Imports: DBI (>= 0.3.0), methods Suggests: DBItest, testthat ``` Importing `DBI` is fine, because your users are not supposed to *attach* your package anyway; the preferred method is to attach `DBI` and use explicit qualification via `::` to access the driver in your package (which needs to be done only once). ## Testing Why testing at this early stage? Because testing should be an integral part of the software development cycle. Test right from the start, add automated tests as you go, finish faster (because tests are automated) while maintaining superb code quality (because tests also check corner cases that you might not be aware of). Don't worry: if some test cases are difficult or impossible to satisfy, or take too long to run, you can just turn them off. Take the time now to head over to the `DBItest` vignette. You will find a vast amount of ready-to-use test cases that will help you in the process of implementing your new DBI backend. ```r vignette("test", package = "DBItest") ``` Add custom tests that are not covered by `DBItest` at your discretion, or enhance `DBItest` and file a pull request if the test is generic enough to be useful for many DBI backends. ## Driver Start by making a driver class which inherits from `DBIDriver`. This class doesn't need to do anything, it's just used to dispatch other generics to the right method. Users don't need to know about this, so you can remove it from the default help listing with `@keywords internal`: ```{r} #' Driver for Kazam database. #' #' @keywords internal #' @export #' @import DBI #' @import methods setClass("KazamDriver", contains = "DBIDriver") ``` The driver class was more important in older versions of DBI, so you should also provide a dummy `dbUnloadDriver()` method. ```{r} #' @export #' @rdname Kazam-class setMethod("dbUnloadDriver", "KazamDriver", function(drv, ...) { TRUE }) ``` If your package needs global setup or tear down, do this in the `.onLoad()` and `.onUnload()` functions. You might also want to add a show method so the object prints nicely: ```{r} setMethod("show", "KazamDriver", function(object) { cat("\n") }) ``` Next create `Kazam()` which instantiates this class. ```{r} #' @export Kazam <- function() { new("KazamDriver") } Kazam() ``` ## Connection Next create a connection class that inherits from `DBIConnection`. This should store all the information needed to connect to the database. If you're talking to a C api, this will include a slot that holds an external pointer. ```{r} #' Kazam connection class. #' #' @export #' @keywords internal setClass("KazamConnection", contains = "DBIConnection", slots = list( host = "character", username = "character", # and so on ptr = "externalptr" ) ) ``` Now you have some of the boilerplate out of the way, you can start work on the connection. The most important method here is `dbConnect()` which allows you to connect to a specified instance of the database. Note the use of `@rdname Kazam`. This ensures that `Kazam()` and the connect method are documented together. ```{r} #' @param drv An object created by \code{Kazam()} #' @rdname Kazam #' @export #' @examples #' \dontrun{ #' db <- dbConnect(RKazam::Kazam()) #' dbWriteTable(db, "mtcars", mtcars) #' dbGetQuery(db, "SELECT * FROM mtcars WHERE cyl == 4") #' } setMethod("dbConnect", "KazamDriver", function(drv, ...) { # ... new("KazamConnection", host = host, ...) }) ``` * Replace `...` with the arguments needed to connect to your database. You'll always need to include `...` in the arguments, even if you don't use it, for compatibility with the generic. * This is likely to be where people first come for help, so the examples should show how to connect to the database, and how to query it. (Obviously these examples won't work yet.) Ideally, include examples that can be run right away (perhaps relying on a publicly hosted database), but failing that surround in `\dontrun{}` so people can at least see the code. Next, implement `show()` and `dbDisconnect()` methods. ## Results Finally, you're ready to implement the meat of the system: fetching results of a query into a data frame. First define a results class: ```{r} #' Kazam results class. #' #' @keywords internal #' @export setClass("KazamResult", contains = "DBIResult", slots = list(ptr = "externalptr") ) ``` Then write a `dbSendQuery()` method. This takes a connection and SQL string as arguments, and returns a result object. Again `...` is needed for compatibility with the generic, but you can add other arguments if you need them. ```{r} #' Send a query to Kazam. #' #' @export #' @examples #' # This is another good place to put examples setMethod("dbSendQuery", "KazamConnection", function(conn, statement, ...) { # some code new("KazamResult", ...) }) ``` Next, implement `dbClearResult()`, which should close the result set and free all resources associated with it: ```{r} #' @export setMethod("dbClearResult", "KazamResult", function(res, ...) { # free resources TRUE }) ``` The hardest part of every DBI package is writing the `dbFetch()` method. This needs to take a result set and (optionally) number of records to return, and create a dataframe. Mapping R's data types to those of your database may require a custom implementation of the `dbDataType()` method for your connection class: ```{r} #' Retrieve records from Kazam query #' @export setMethod("dbFetch", "KazamResult", function(res, n = -1, ...) { ... }) # (optionally) #' Find the database data type associated with an R object #' @export setMethod("dbDataType", "KazamConnection", function(dbObj, obj, ...) { ... }) ``` Next, implement `dbHasCompleted()` which should return a `logical` indicating if there are any rows remaining to be fetched. ```{r} #' @export setMethod("dbHasCompleted", "KazamResult", function(res, ...) { }) ``` With these four methods in place, you can now use the default `dbGetQuery()` to send a query to the database, retrieve results if available and then clean up. Spend some time now making sure this works with an existing database, or relax and let the `DBItest` package do the work for you. ## SQL methods You're now on the home stretch, and can make your wrapper substantially more useful by implementing methods that wrap around variations in SQL across databases: * `dbQuoteString()` and `dbQuoteIdentifer()` are used to safely quote strings and identifiers to avoid SQL injection attacks. Note that the former must be vectorized, but not the latter. * `dbWriteTable()` creates a database table given an R dataframe. I'd recommend using the functions prefixed with `sql` in this package to generate the SQL. These functions are still a work in progress so please let me know if you have problems. * `dbReadTable()`: a simple wrapper around `SELECT * FROM table`. Use `dbQuoteIdentifer()` to safely quote the table name and prevent mismatches between the names allowed by R and the database. * `dbListTables()` and `dbExistsTable()` let you determine what tables are available. If not provided by your database's API, you may need to generate sql that inspects the system tables. * `dbListFields()` shows which fields are available in a given table. * `dbRemoveTable()` wraps around `DROP TABLE`. Start with `SQL::sqlTableDrop()`. * `dbBegin()`, `dbCommit()` and `dbRollback()`: implement these three functions to provide basic transaction support. This functionality is currently not tested in the `DBItest` package. ## Metadata methods There are a lot of extra metadata methods for result sets (and one for the connection) that you might want to implement. They are described in the following. * `dbIsValid()` returns if a connection or a result set is open (`TRUE`) or closed (`FALSE`). All further methods in this section are valid for result sets only. * `dbGetStatement()` returns the issued query as a character value. * `dbColumnInfo()` lists the names and types of the result set's columns. * `dbGetRowCount()` and `dbGetRowsAffected()` returns the number of rows returned or altered in a `SELECT` or `INSERT`/`UPDATE` query, respectively. * `dbBind()` allows using parametrised queries. Take a look at `sqlInterpolate()` and `sqlParseVariables()` if your SQL engine doesn't offer native parametrised queries. ## Full DBI compliance By now, your package should implement all methods defined in the DBI specification. If you want to walk the extra mile, offer a read-only mode that allows your users to be sure that their valuable data doesn't get destroyed inadvertently. DBI/inst/doc/DBI.html0000644000176200001440000004551213575372774013711 0ustar liggesusers Introduction to DBI

Introduction to DBI

Katharina Brunner

14 October 2019

The {DBI} package defines a common interface between the R and database management systems (DBMS). Hence the name: DBI stands for database interface.

Using DBI, developers can focus on the functionalities of their code, instead of setting up the infrastructure depending on the underlying database. This DBMS-agnostic approach is possible, because DBI works best with several other packages that act as drivers to absorb the peculiarities of the specific DBMSs.

These packages import {DBI} and implement its methods depending on the specific database management system.

Currently, DBI works with the many different database management systems, e.g.:

  • MySQL, using the R-package RMySQL
  • MariaDB, using the R-package RMariaDB
  • Postgres, using and the R-package RPostgres
  • SQLite, using and the R-package RSQLite

DBI offers a set of classes and methods that define what operations are possible and how they are performed:

  • connect/disconnect to the DBMS
  • create and execute statements in the DBMS
  • extract results/output from statements
  • error/exception handling
  • information (meta-data) from database objects
  • transaction management (optional)

Examples

To showcase DBI capabilities, we create a in-memory RSQLite database

## <SQLiteConnection>
##   Path: :memory:
##   Extensions: TRUE

The function dbListTables() displays the names tables in the remote database. Since we haven’t pushed any data to the database, there are no tables to show.

## character(0)

We can write the famous data mtcars dataset to the remote database by using dbWriteTable(). Calling dbListTables() displays the table name:

## [1] "mtcars"

To get all columns names of a remote table, use dbListFields(). It returns a character vector with all column names in the same order as in the database:

##  [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
## [11] "carb"

If you want to import database table from the DBMS as a data frame, dbReadTable() helps to do that. Basically, it is the result of the most generic SQL call SELECT * FROM <name>.

##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Of course, you can run more specific SQL queries, too. dbGetQuery() is the function to send a query to a database and retrieve the result as a data frame. Especially when working with large datasets, it is important to free the resources associated with retrieving the result. dbGetQuery() cares about this, too.

##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 2  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 3  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 4  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 5  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 6  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 7  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 8  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 9  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 10 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 11 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Behind the scences, dbGetQuery() is a combination of dbSendQuery(), dbFetch() and dbClearResult(). The following snippet leads to the same result as dbGetQuery() above:

##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 2  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 3  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 4  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 5  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 6  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 7  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 8  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 9  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 10 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 11 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

When working with large datasets it might be smart to fetch the result step by step, not in one big chunk. This can be implemented with a while loop and a dbFetch() call that defines a maximum number of records to retrieve per fetch, here n = 5. There are eleven cars with four cylinders, so we expect two chunks of five rows and one chuck of one row:

## [1] 5
## [1] 5
## [1] 1

Again, call dbClearResult() and disconnect from the connection with dbDisconnect(), when you are done:

Further Reading

DBI/inst/doc/backend.R0000644000176200001440000000552213575372774014134 0ustar liggesusers## ---- echo = FALSE------------------------------------------------------------ library(DBI) knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ## ----------------------------------------------------------------------------- #' Driver for Kazam database. #' #' @keywords internal #' @export #' @import DBI #' @import methods setClass("KazamDriver", contains = "DBIDriver") ## ----------------------------------------------------------------------------- #' @export #' @rdname Kazam-class setMethod("dbUnloadDriver", "KazamDriver", function(drv, ...) { TRUE }) ## ----------------------------------------------------------------------------- setMethod("show", "KazamDriver", function(object) { cat("\n") }) ## ----------------------------------------------------------------------------- #' @export Kazam <- function() { new("KazamDriver") } Kazam() ## ----------------------------------------------------------------------------- #' Kazam connection class. #' #' @export #' @keywords internal setClass("KazamConnection", contains = "DBIConnection", slots = list( host = "character", username = "character", # and so on ptr = "externalptr" ) ) ## ----------------------------------------------------------------------------- #' @param drv An object created by \code{Kazam()} #' @rdname Kazam #' @export #' @examples #' \dontrun{ #' db <- dbConnect(RKazam::Kazam()) #' dbWriteTable(db, "mtcars", mtcars) #' dbGetQuery(db, "SELECT * FROM mtcars WHERE cyl == 4") #' } setMethod("dbConnect", "KazamDriver", function(drv, ...) { # ... new("KazamConnection", host = host, ...) }) ## ----------------------------------------------------------------------------- #' Kazam results class. #' #' @keywords internal #' @export setClass("KazamResult", contains = "DBIResult", slots = list(ptr = "externalptr") ) ## ----------------------------------------------------------------------------- #' Send a query to Kazam. #' #' @export #' @examples #' # This is another good place to put examples setMethod("dbSendQuery", "KazamConnection", function(conn, statement, ...) { # some code new("KazamResult", ...) }) ## ----------------------------------------------------------------------------- #' @export setMethod("dbClearResult", "KazamResult", function(res, ...) { # free resources TRUE }) ## ----------------------------------------------------------------------------- #' Retrieve records from Kazam query #' @export setMethod("dbFetch", "KazamResult", function(res, n = -1, ...) { ... }) # (optionally) #' Find the database data type associated with an R object #' @export setMethod("dbDataType", "KazamConnection", function(dbObj, obj, ...) { ... }) ## ----------------------------------------------------------------------------- #' @export setMethod("dbHasCompleted", "KazamResult", function(res, ...) { }) DBI/inst/doc/spec.R0000644000176200001440000001025713575372776013502 0ustar liggesusers## ----echo = FALSE------------------------------------------------------------- library(magrittr) library(xml2) knitr::opts_chunk$set(echo = FALSE) r <- rprojroot::is_r_package$make_fix_file() ## ----error=TRUE--------------------------------------------------------------- rd_db <- tools::Rd_db(dir = r()) Links <- tools::findHTMLlinks() html_topic <- function(name) { rd <- rd_db[[paste0(name, ".Rd")]] conn <- textConnection(NULL, "w") on.exit(close(conn)) #tools::Rd2HTML(rd, conn, Links = Links) tools::Rd2HTML(rd, conn) textConnectionValue(conn) } xml_topic <- function(name, patcher) { html <- html_topic(name) x <- read_html(paste(html, collapse = "\n")) # No idea why this is necessary when embedding HTML in Markdown codes <- x %>% xml_find_all("//code[contains(., '$')]") xml_text(codes) <- gsub("[$]", "\\\\$", xml_text(codes)) xx <- x %>% xml_find_first("/html/body") xx %>% xml_find_first("//table") %>% xml_remove() xx %>% xml_find_all("//pre") %>% xml_set_attr("class", "r") patcher(xx) } out_topic <- function(name, patcher = identity) { xml <- lapply(name, xml_topic, patcher = patcher) sapply(xml, as.character) %>% paste(collapse = "\n") } patch_package_doc <- function(x) { x %>% xml_find_first("//h3") %>% xml_remove remove_see_also_section(x) remove_authors_section(x) x } move_contents_of_usage_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 usage_contents <- x %>% xml_find_all( "//h3[.='Usage']/following-sibling::node() [not(self::h3)] [count(preceding-sibling::h3)=2]") usage_text <- usage_contents %>% xml_find_first("//pre") %>% xml_text h3 <- x %>% xml_find_first("//h3") intro_text <- read_xml( paste0( "

This section describes the behavior of the following method", if (length(grep("[(]", strsplit(usage_text, "\n")[[1]])) > 1) "s" else "", ":

") ) xml_add_sibling( h3, intro_text, .where = "before") lapply(usage_contents, xml_add_sibling, .x = h3, .copy = FALSE, .where = "before") x %>% xml_find_first("//h3[.='Usage']") %>% xml_remove x } move_additional_arguments_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error additional_arguments <- x %>% xml_find_all( "//h3[.='Additional arguments'] | //h3[.='Additional arguments']/following-sibling::node()[following-sibling::h3]") after_arg <- x %>% xml_find_first("//h3[text()='Arguments']/following-sibling::h3") lapply(additional_arguments, xml_add_sibling, .x = after_arg, .copy = FALSE, .where = "before") x } remove_see_also_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='See Also'] | //h3[.='See Also']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } remove_authors_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='Author(s)'] | //h3[.='Author(s)']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } patch_method_doc <- function(x) { move_contents_of_usage_section(x) remove_see_also_section(x) move_additional_arguments_section(x) x } topics <- c( "dbDataType", "dbConnect", "dbDisconnect", "dbSendQuery", "dbFetch", "dbClearResult", "dbBind", "dbGetQuery", "dbSendStatement", "dbExecute", "dbQuoteString", "dbQuoteIdentifier", "dbReadTable", "dbWriteTable", "dbListTables", "dbExistsTable", "dbRemoveTable", "dbListFields", "dbIsValid", "dbHasCompleted", "dbGetStatement", "dbGetRowCount", "dbGetRowsAffected", "dbColumnInfo", "transactions", "dbWithTransaction" ) html <- c( out_topic("DBI-package", patch_package_doc), out_topic(topics, patch_method_doc) ) temp_html <- tempfile(fileext = ".html") temp_md <- tempfile(fileext = ".md") #temp_html <- "out.html" #temp_md <- "out.md" #html <- '
\na\nb\n
' writeLines(html, temp_html) rmarkdown::pandoc_convert(temp_html, "gfm", verbose = FALSE, output = temp_md) knitr::asis_output(paste(readLines(temp_md), collapse = "\n")) DBI/inst/doc/spec.Rmd0000644000176200001440000001173413575266047014015 0ustar liggesusers--- title: "DBI specification" author: "Kirill Müller" output: rmarkdown::html_vignette abstract: > The DBI package defines the generic DataBase Interface for R. The connection to individual DBMS is provided by other packages that import DBI (so-called *DBI backends*). This document formalizes the behavior expected by the methods declared in DBI and implemented by the individual backends. To ensure maximum portability and exchangeability, and to reduce the effort for implementing a new DBI backend, the DBItest package defines a comprehensive set of test cases that test conformance to the DBI specification. This document is derived from comments in the test definitions of the DBItest package. Any extensions or updates to the tests will be reflected in this document. vignette: > %\VignetteIndexEntry{DBI specification} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r echo = FALSE} library(magrittr) library(xml2) knitr::opts_chunk$set(echo = FALSE) r <- rprojroot::is_r_package$make_fix_file() ``` ```{r error=TRUE} rd_db <- tools::Rd_db(dir = r()) Links <- tools::findHTMLlinks() html_topic <- function(name) { rd <- rd_db[[paste0(name, ".Rd")]] conn <- textConnection(NULL, "w") on.exit(close(conn)) #tools::Rd2HTML(rd, conn, Links = Links) tools::Rd2HTML(rd, conn) textConnectionValue(conn) } xml_topic <- function(name, patcher) { html <- html_topic(name) x <- read_html(paste(html, collapse = "\n")) # No idea why this is necessary when embedding HTML in Markdown codes <- x %>% xml_find_all("//code[contains(., '$')]") xml_text(codes) <- gsub("[$]", "\\\\$", xml_text(codes)) xx <- x %>% xml_find_first("/html/body") xx %>% xml_find_first("//table") %>% xml_remove() xx %>% xml_find_all("//pre") %>% xml_set_attr("class", "r") patcher(xx) } out_topic <- function(name, patcher = identity) { xml <- lapply(name, xml_topic, patcher = patcher) sapply(xml, as.character) %>% paste(collapse = "\n") } patch_package_doc <- function(x) { x %>% xml_find_first("//h3") %>% xml_remove remove_see_also_section(x) remove_authors_section(x) x } move_contents_of_usage_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 usage_contents <- x %>% xml_find_all( "//h3[.='Usage']/following-sibling::node() [not(self::h3)] [count(preceding-sibling::h3)=2]") usage_text <- usage_contents %>% xml_find_first("//pre") %>% xml_text h3 <- x %>% xml_find_first("//h3") intro_text <- read_xml( paste0( "

This section describes the behavior of the following method", if (length(grep("[(]", strsplit(usage_text, "\n")[[1]])) > 1) "s" else "", ":

") ) xml_add_sibling( h3, intro_text, .where = "before") lapply(usage_contents, xml_add_sibling, .x = h3, .copy = FALSE, .where = "before") x %>% xml_find_first("//h3[.='Usage']") %>% xml_remove x } move_additional_arguments_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error additional_arguments <- x %>% xml_find_all( "//h3[.='Additional arguments'] | //h3[.='Additional arguments']/following-sibling::node()[following-sibling::h3]") after_arg <- x %>% xml_find_first("//h3[text()='Arguments']/following-sibling::h3") lapply(additional_arguments, xml_add_sibling, .x = after_arg, .copy = FALSE, .where = "before") x } remove_see_also_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='See Also'] | //h3[.='See Also']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } remove_authors_section <- function(x) { # http://stackoverflow.com/a/3839299/946850 and some trial and error x %>% xml_find_all( "//h3[.='Author(s)'] | //h3[.='Author(s)']/following-sibling::node()[following-sibling::h3]") %>% xml_remove() x } patch_method_doc <- function(x) { move_contents_of_usage_section(x) remove_see_also_section(x) move_additional_arguments_section(x) x } topics <- c( "dbDataType", "dbConnect", "dbDisconnect", "dbSendQuery", "dbFetch", "dbClearResult", "dbBind", "dbGetQuery", "dbSendStatement", "dbExecute", "dbQuoteString", "dbQuoteIdentifier", "dbReadTable", "dbWriteTable", "dbListTables", "dbExistsTable", "dbRemoveTable", "dbListFields", "dbIsValid", "dbHasCompleted", "dbGetStatement", "dbGetRowCount", "dbGetRowsAffected", "dbColumnInfo", "transactions", "dbWithTransaction" ) html <- c( out_topic("DBI-package", patch_package_doc), out_topic(topics, patch_method_doc) ) temp_html <- tempfile(fileext = ".html") temp_md <- tempfile(fileext = ".md") #temp_html <- "out.html" #temp_md <- "out.md" #html <- '
\na\nb\n
' writeLines(html, temp_html) rmarkdown::pandoc_convert(temp_html, "gfm", verbose = FALSE, output = temp_md) knitr::asis_output(paste(readLines(temp_md), collapse = "\n")) ``` DBI/inst/doc/DBI-proposal.html0000644000176200001440000015713313575372773015550 0ustar liggesusers A Common Interface to Relational Databases from R and S – A Proposal

A Common Interface to Relational Databases from R and S – A Proposal

David James

March 16, 2000

For too long S and similar data analysis environments have lacked good interfaces to relational database systems (RDBMS). For the last twenty years or so these RDBMS have evolved into highly optimized client-server systems for data storage and manipulation, and currently they serve as repositories for most of the business, industrial, and research “raw” data that analysts work with. Other analysis packages, such as SAS, have traditionally provided good data connectivity, but S and GNU R have relied on intermediate text files as means of importing data (but see (R Data Import/Export 2001) and (Using Relational Database Systems with R 2000).) Although this simple approach works well for relatively modest amounts of mostly static data, it does not scale up to larger amounts of data distributed over machines and locations, nor does it scale up to data that is highly dynamic – situations that are becoming increasingly common.

We want to propose a common interface between R/S and RDBMS that would allow users to access data stored on database servers in a uniform and predictable manner irrespective of the database engine. The interface defines a small set of classes and methods similar in spirit to Python’s DB-API, Java’s JDBC, Microsoft’s ODBC, Perl’s DBI, etc., but it conforms to the “whole-object” philosophy so natural in S and R.

Computing with Distributed Data

As data analysts, we are increasingly faced with the challenge of larger data sources distributed over machines and locations; most of these data sources reside in relational database management systems (RDBMS). These relational databases represent a mature client-server distributed technology that we as analysts could be exploiting more that we’ve done in the past. The relational technology provides a well-defined standard, the ANSI SQL-92 (X/Open CAE Specification: SQL and RDA 1994), both for defining and manipulating data in a highly optimized fashion from virtually any application.

In contrast, S and Splus have provided somewhat limited tools for coping with the challenges of larger and distributed data sets (Splus does provide an import function to import from databases, but it is quite limited in terms of SQL facilities). The R community has been more resourceful and has developed a number of good libraries for connecting to mSQL, MySQL, PostgreSQL, and ODBC; each library, however, has defined its own interface to each database engine a bit differently. We think it would be to everybody’s advantage to coordinate the definition of a common interface, an effort not unlike those taken in the Python and Perl communities.

The goal of a common, seamless access to distributed data is a modest one in our evolution towards a fully distributed computing environment. We recognize the greater goal of distributed computing as the means to fully integrate diverse systems – not just databases – into a truly flexible analysis environment. Good connectivity to databases, however, is of immediate necessity both in practical terms and as a means to help us transition from monolithic, self-contained systems to those in which computations, not only the data, can be carried out in parallel over a wide number of computers and/or systems Temple Lang (2000). Issues of reliability, security, location transparency, persistence, etc., will be new to most of us and working with distributed data may provide a more gradual change to ease in the ultimate goal of full distributed computing.

A Common Interface

We believe that a common interface to databases can help users easily access data stored in RDBMS. A common interface would describe, in a uniform way, how to connect to RDBMS, extract meta-data (such as list of available databases, tables, etc.) as well as a uniform way to execute SQL statements and import their output into R and S. The current emphasis is on querying databases and not so much in a full low-level interface for database development as in JDBC or ODBC, but unlike these, we want to approach the interface from the “whole-object” perspective J. M. Chambers (1998) so natural to R/S and Python – for instance, by fetching all fields and records simultaneously into a single object.

The basic idea is to split the interface into a front-end consisting of a few classes and generic functions that users invoke and a back-end set of database-specific classes and methods that implement the actual communication. (This is a very well-known pattern in software engineering, and another good verbatim is the device-independent graphics in R/S where graphics functions produce similar output on a variety of different devices, such X displays, Postscript, etc.)

The following verbatim shows the front-end:

> mgr <- dbManager("Oracle")  
> con <- dbConnect(mgr, user = "user", passwd = "passwd")
> rs <- dbExecStatement(con, 
          "select fld1, fld2, fld3 from MY_TABLE")
> tbls <- fetch(rs, n = 100)
> hasCompleted(rs)
[1] T
> close(rs)
> rs <- dbExecStatement(con, 
          "select id_name, q25, q50 from liv2")
> res <- fetch(rs)
> getRowCount(rs)
[1] 73
> close(con)

Such scripts should work with other RDBMS (say, MySQL) by replacing the first line with

> mgr <- dbManager("MySQL")

Interface Classes

The following are the main RS-DBI classes. They need to be extended by individual database back-ends (MySQL, Oracle, etc.)

dbManager

Virtual class1 extended by actual database managers, e.g., Oracle, MySQL, Informix.

dbConnection

Virtual class that captures a connection to a database instance2.

dbResult

Virtual class that describes the result of an SQL statement.

dbResultSet

Virtual class, extends dbResult to fully describe the output of those statements that produce output records, i.e., SELECT (or SELECT-like) SQL statement.

All these classes should implement the methods show, describe, and getInfo:

show

(print in R) prints a one-line identification of the object.

describe

prints a short summary of the meta-data of the specified object (like summary in R/S).

getInfo

takes an object of one of the above classes and a string specifying a meta-data item, and it returns the corresponding information (NULL if unavailable).

> mgr <- dbManager("MySQL")
> getInfo(mgr, "version")
> con <- dbConnect(mgr, ...)
> getInfo(con, "type")

The reason we implement the meta-data through getInfo in this way is to simplify the writing of database back-ends. We don’t want to overwhelm the developers of drivers (ourselves, most likely) with hundreds of methods as in the case of JDBC.

In addition, the following methods should also be implemented:

getDatabases

lists all available databases known to the dbManager.

getTables

lists tables in a database.

getTableFields

lists the fields in a table in a database.

getTableIndices

lists the indices defined for a table in a database.

These methods may be implemented using the appropriate getInfo method above.

In the next few sections we describe in detail each of these classes and their methods.

Class dbManager

This class identifies the relational database management system. It needs to be extended by individual back-ends (Oracle, PostgreSQL, etc.) The dbManager class defines the following methods:

load

initializes the driver code. We suggest having the generator, dbManager(driver), automatically load the driver.

unload

releases whatever resources the driver is using.

getVersion

returns the version of the RS-DBI currently implemented, plus any other relevant information about the implementation itself and the RDBMS being used.

Class dbConnection

This virtual class captures a connection to a RDBMS, and it provides access to dynamic SQL, result sets, RDBMS session management (transactions), etc. Note that the dbManager may or may not allow multiple simultaneous connections. The methods it defines include:

dbConnect

opens a connection to the database dbname. Other likely arguments include host, user, and password. It returns an object that extends dbConnection in a driver-specific manner (e.g., the MySQL implementation creates a connection of class MySQLConnection that extends dbConnection). Note that we could separate the steps of connecting to a RDBMS and opening a database there (i.e., opening an instance). For simplicity we do the 2 steps in this method. If the user needs to open another instance in the same RDBMS, just open a new connection.

close

closes the connection and discards all pending work.

dbExecStatement

submits one SQL statement. It returns a dbResult object, and in the case of a SELECT statement, the object also inherits from dbResultSet. This dbResultSet object is needed for fetching the output rows of SELECT statements. The result of a non-SELECT statement (e.g., UPDATE, DELETE, CREATE, ALTER, …) is defined as the number of rows affected (this seems to be common among RDBMS).

commit

commits pending transaction (optional).

rollback

undoes current transaction (optional).

callProc

invokes a stored procedure in the RDBMS (tentative). Stored procedures are not part of the ANSI SQL-92 standard and possibly vary substantially from one RDBMS to another. For instance, Oracle seems to have a fairly decent implementation of stored procedures, but MySQL currently does not support them.

dbExec

submit an SQL “script” (multiple statements). May be implemented by looping with dbExecStatement.

dbNextResultSet

When running SQL scripts (multiple statements), it closes the current result set in the dbConnection, executes the next statement and returns its result set.

Class dbResult

This virtual class describes the result of an SQL statement (any statement) and the state of the operation. Non-query statements (e.g., CREATE, UPDATE, DELETE) set the “completed” state to 1, while SELECT statements to 0. Error conditions set this slot to a negative number. The dbResult class defines the following methods:

getStatement

returns the SQL statement associated with the result set.

getDBConnection

returns the dbConnection associated with the result set.

getRowsAffected

returns the number of rows affected by the operation.

hasCompleted

was the operation completed? SELECT’s, for instance, are not completed until their output rows are all fetched.

getException

returns the status of the last SQL statement on a given connection as a list with two members, status code and status description.

Class dbResultSet

This virtual class extends dbResult, and it describes additional information from the result of a SELECT statement and the state of the operation. The completed state is set to 0 so long as there are pending rows to fetch. The dbResultSet class defines the following additional methods:

getRowCount

returns the number of rows fetched so far.

getNullOk

returns a logical vector with as many elements as there are fields in the result set, each element describing whether the corresponding field accepts NULL values.

getFields

describes the SELECTed fields. The description includes field names, RDBMS internal data types, internal length, internal precision and scale, null flag (i.e., column allows NULL’s), and corresponding S classes (which can be over-ridden with user-provided classes). The current MySQL and Oracle implementations define a dbResultSet as a named list with the following elements:

connection:

the connection object associated with this result set;

statement:

a string with the SQL statement being processed;

description:

a field description data.frame with as many rows as there are fields in the SELECT output, and columns specifying the name, type, length, precision, scale, Sclass of the corresponding output field.

rowsAffected:

the number of rows that were affected;

rowCount:

the number of rows so far fetched;

completed:

a logical value describing whether the operation has completed or not.

nullOk:

a logical vector specifying whether the corresponding column may take NULL values.

The methods above are implemented as accessor functions to this list in the obvious way.

setDataMappings

defines a conversion between internal RDBMS data types and R/S classes. We expect the default mappings to be by far the most common ones, but users that need more control may specify a class generator for individual fields in the result set. (See Section [sec:mappings] for details.)

close

closes the result set and frees resources both in R/S and the RDBMS.

fetch

extracts the next max.rec records (-1 means all).

Data Type Mappings

The data types supported by databases are slightly different than the data types in R and S, but the mapping between them is straightforward: Any of the many fixed and varying length character types are mapped to R/S character. Fixed-precision (non-IEEE) numbers are mapped into either doubles (numeric) or long (integer). Dates are mapped to character using the appropriate TO_CHAR function in the RDBMS (which should take care of any locale information). Some RDBMS support the type CURRENCY or MONEY which should be mapped to numeric. Large objects (character, binary, file, etc.) also need to be mapped. User-defined functions may be specified to do the actual conversion as follows:

  1. run the query (either with dbExec or dbExecStatement):

    > rs <- dbExecStatement(con, "select whatever-You-need")
  2. extract the output field definitions

    > flds <- getFields(rs)
  3. replace the class generator in the, say 3rd field, by the user own generator:

    > flds[3, "Sclass"]            # default mapping
    [1] "character"

    by

    > flds[3, "Sclass"] <- "myOwnGeneratorFunction"
  4. set the new data mapping prior to fetching

    > setDataMappings(resutlSet, flds)
  5. fetch the rows and store in a data.frame

    > data <- fetch(resultSet)

Open Issues

We may need to provide some additional utilities, for instance to convert dates, to escape characters such as quotes and slashes in query strings, to strip excessive blanks from some character fields, etc. We need to decide whether we provide hooks so these conversions are done at the C level, or do all the post-processing in R or S.

Another issue is what kind of data object is the output of an SQL query. Currently the MySQL and Oracle implementations return data as a data.frame; data frames have the slight inconvenience that they automatically re-label the fields according to R/S syntax, changing the actual RDBMS labels of the variables; the issue of non-numeric data being coerced into factors automatically “at the drop of a hat” (as someone in s-news wrote) is also annoying.

The execution of SQL scripts is not fully described. The method that executes scripts could run individual statements without returning until it encounters a query (SELECT-like) statement. At that point it could return that one result set. The application is then responsible for fetching these rows, and then for invoking dbNextResultSet on the opened dbConnection object to repeat the dbExec/fetch loop until it encounters the next dbResultSet. And so on. Another (potentially very expensive) alternative would be to run all statements sequentially and return a list of data.frames, each element of the list storing the result of each statement.

Binary objects and large objects present some challenges both to R and S. It is becoming more common to store images, sounds, and other data types as binary objects in RDBMS, some of which can be in principle quite large. The SQL-92 ANSI standard allows up to 2 gigabytes for some of these objects. We need to carefully plan how to deal with binary objects – perhaps tentatively not in full generality. Large objects could be fetched by repeatedly invoking a specified R/S function that takes as argument chunks of a specified number of raw bytes. In the case of S4 (and Splus5.x) the RS-DBI implementation can write into an opened connection for which the user has defined a reader (but can we guarantee that we won’t overflow the connection?). In the case of R it is not clear what data type binary large objects (BLOB) should be mapped into.

Limitations

These are some of the limitations of the current interface definition:

  • we only allow one SQL statement at a time, forcing users to split SQL scripts into individual statements;

  • transaction management is not fully described;

  • the interface is heavily biased towards queries, as opposed to general purpose database development. In particular we made no attempt to define “bind variables”; this is a mechanism by which the contents of S objects are implicitly moved to the database during SQL execution. For instance, the following embedded SQL statement

      /* SQL */
      SELECT * from emp_table where emp_id = :sampleEmployee

    would take the vector sampleEmployee and iterate over each of its elements to get the result. Perhaps RS-DBI could at some point in the future implement this feature.

Other Approaches

The high-level, front-end description of RS-DBI is the more critical aspect of the interface. Details on how to actually implement this interface may change over time. The approach described in this document based on one back-end driver per RDBMS is reasonable, but not the only approach – we simply felt that a simpler approach based on well-understood and self-contained tools (R, S, and C API’s) would be a better start. Nevertheless we want to briefly mention a few alternatives that we considered and tentatively decided against, but may quite possibly re-visit in the near future.

Open Database Connectivity (ODBC)

The ODBC protocol was developed by Microsoft to allow connectivity among C/C++ applications and RDBMS. As you would expect, originally implementations of the ODBC were only available under Windows environments. There are various effort to create a Unix implementation (see the Unix ODBC web-site and Harvey (1999)). This approach looks promising because it allows us to write only one back-end, instead of one per RDBMS. Since most RDBMS already provide ODBC drivers, this could greatly simplify development. Unfortunately, the Unix implementation of ODBC was not mature enough at the time we looked at it, a situation we expect will change in the next year or so. At that point we will need to re-evaluate it to make sure that such an ODBC interface does not penalize the interface in terms of performance, ease of use, portability among the various Unix versions, etc.

Java Database Connectivity (JDBC)

Another protocol, the Java database connectivity, is very well-done and supported by just about every RDBMS. The issue with JDBC is that as of today neither S nor R (which are written in C) interfaces cleanly with Java. There are several efforts (some in a quite fairly advanced state) to allow S and R to invoke Java methods. Once this interface is widely available in Splus5x and R we will need to re-visit this issue again and study the performance, usability, etc., of JDBC as a common back-end to the RS-DBI.

CORBA and a 3-tier Architecture

Yet another approach is to move the interface to RDBMS out of R and S altogether into a separate system or server that would serve as a proxy between R/S and databases. The communication to this middle-layer proxy could be done through CORBA (John M. Chambers et al. 1998, @corba:siegel.96), Java’s RMI, or some other similar technology. Such a design could be very flexible, but the CORBA facilities both in R and S are not widely available yet, and we do not know whether this will be made available to Splus5 users from MathSoft. Also, my experience with this technology is rather limited.

On the other hand, this 3-tier architecture seem to offer the most flexibility to cope with very large distributed databases, not necessarily relational.

Resources

The latest documentation and software on the RS-DBI was available at www.omegahat.net (link dead now: http://www.omegahat.net/contrib/RS-DBI/index.html). The R community has developed interfaces to some databases: RmSQL is an interface to the mSQL database written by Torsten Hothorn; RPgSQL is an interface to PostgreSQL and was written by Timothy H. Keitt; RODBC is an interface to ODBC, and it was written by Michael Lapsley. (For more details on all these see (R Data Import/Export 2001).)

The are R and S-Plus interfaces to MySQL that follow the propose RS-DBI API described here; also, there’s an S-Plus interface SOracle James (n.d.) to Oracle (we expect to have an R implementation soon.)

The idea of a common interface to databases has been successfully implemented in Java’s Database Connectivity (JDBC) (www.javasoft.com), in C through the Open Database Connectivity (ODBC) (www.unixodbc.org), in Python’s Database Application Programming Interface (www.python.org), and in Perl’s Database Interface (www.cpan.org).

Acknowledgements

The R/S database interface came about from suggestions, comments, and discussions with John M. Chambers and Duncan Temple Lang in the context of the Omega Project for Statistical Computing. Doug Bates and Saikat DebRoy ported (and greatly improved) the first MySQL implementation to R.

The S Version 4 Definitions

The following code is meant to serve as a detailed description of the R/S to database interface. We decided to use S4 (instead of R or S version 3) because its clean syntax help us to describe easily the classes and methods that form the RS-DBI, and also to convey the inter-class relationships.

## Define all the classes and methods to be used by an
## implementation of the RS-DataBase Interface.  Mostly, 
## these classes are virtual and each driver should extend
## them to provide the actual implementation.

## Class: dbManager 
## This class identifies the DataBase Management System
## (Oracle, MySQL, Informix, PostgreSQL, etc.)

setClass("dbManager", VIRTUAL)

setGeneric("load", 
   def = function(dbMgr,...) 
   standardGeneric("load")
   )
setGeneric("unload", 
   def = function(dbMgr,...)
   standardGeneric("unload")
   )
setGeneric("getVersion", 
   def = function(dbMgr,...) 
   standardGeneric("getVersion")
   )

## Class: dbConnections 
## This class captures a connection to a database instance. 

setClass("dbConnection", VIRTUAL)

setGeneric("dbConnection", 
   def = function(dbMgr, ...) 
   standardGeneric("dbConnection")
   )
setGeneric("dbConnect", 
   def = function(dbMgr, ...) 
   standardGeneric("dbConnect")
   )
setGeneric("dbExecStatement", 
   def = function(con, statement, ...)
   standardGeneric("dbExecStatement")
   )
setGeneric("dbExec", 
   def = function(con, statement, ...) 
   standardGeneric("dbExec")
   )
setGeneric("getResultSet", 
   def = function(con, ..) 
   standardGeneric("getResultSet")
   )
setGeneric("commit", 
   def = function(con, ...) 
   standardGeneric("commit")
   )
setGeneric("rollback", 
   def = function(con, ...) 
   standardGeneric("rollback")
   )
setGeneric("callProc", 
   def = function(con, ...) 
   standardGeneric("callProc")
   )
setMethod("close", 
   signature = list(con="dbConnection", type="missing"),
   def = function(con, type) NULL
   )

## Class: dbResult
## This is a base class for arbitrary results from the RDBMS 
## (INSERT, UPDATE, DELETE).  SELECTs (and SELECT-like) 
## statements produce "dbResultSet" objects, which extend 
## dbResult.

setClass("dbResult", VIRTUAL)

setMethod("close", 
   signature = list(con="dbResult", type="missing"),
   def = function(con, type) NULL
   )

## Class: dbResultSet
## Note that we define a resultSet as the result of a 
## SELECT  SQL statement.

setClass("dbResultSet", "dbResult")

setGeneric("fetch", 
   def = function(resultSet,n,...) 
   standardGeneric("fetch")
   )
setGeneric("hasCompleted",
   def = function(object, ...) 
   standardGeneric("hasCompleted")
   )
setGeneric("getException",
   def = function(object, ...) 
   standardGeneric("getException")
   )
setGeneric("getDBconnection",
   def = function(object, ...) 
   standardGeneric("getDBconnection")
   )
setGeneric("setDataMappings", 
   def = function(resultSet, ...) 
   standardGeneric("setDataMappings")
   )
setGeneric("getFields",
   def = function(object, table, dbname,  ...) 
   standardGeneric("getFields")
   )
setGeneric("getStatement", 
   def = function(object, ...) 
   standardGeneric("getStatement")
   )
setGeneric("getRowsAffected",
   def = function(object, ...) 
   standardGeneric("getRowsAffected")
   )
setGeneric("getRowCount",
   def = function(object, ...) 
   standardGeneric("getRowCount")
   )
setGeneric("getNullOk",
   def = function(object, ...) 
   standardGeneric("getNullOk")
   )

## Meta-data: 
setGeneric("getInfo", 
   def = function(object, ...) 
   standardGeneric("getInfo")
   )
setGeneric("describe", 
   def = function(object, verbose=F, ...)
   standardGeneric("describe")
   )
setGeneric("getCurrentDatabase",
   def = function(object, ...)
   standardGeneric("getCurrentDatabase")
   )
setGeneric("getDatabases", 
   def = function(object, ...)
   standardGeneric("getDatabases")
   )
setGeneric("getTables", 
   def = function(object, dbname, ...)
   standardGeneric("getTables")
   )
setGeneric("getTableFields", 
   def = function(object, table, dbname, ...)
   standardGeneric("getTableFields")
   )
setGeneric("getTableIndices", 
   def = function(object, table, dbname, ...) 
   standardGeneric("getTableIndices")
   )

Chambers, J. M. 1998. Programming with Data: A Guide to the S Language. New York: Springer.

Chambers, John M., Mark H. Hansen, David A. James, and Duncan Temple Lang. 1998. “Distributed Computing with Data: A Corba-Based Approach.” In Computing Science and Statistics. Inteface Foundation of North America.

Harvey, Peter. 1999. “Open Database Connectivity.” Linux Journal Nov. (67): 68–72.

James, David A. n.d. “An R/S Interface to the Oracle Database.” www.omegahat.org: Bell Labs, Lucent Technologies.

R Data Import/Export. 2001. R-Development Core Team.

Siegel, Jon. 1996. CORBA Fundamentals and Programming. New York: Wiley.

Temple Lang, Duncan. 2000. “The Omegahat Environment: New Possibilities for Statistical Computing.” Journal of Computational and Graphical Statistics to appear.

Using Relational Database Systems with R. 2000. R-Developemt Core Team.

X/Open CAE Specification: SQL and RDA. 1994. Reading, UK: X/Open Company Ltd.


  1. A virtual class allows us to group classes that share some common functionality, e.g., the virtual class “dbConnection” groups all the connection implementations by Informix, Ingres, DB/2, Oracle, etc. Although the details will vary from one RDBMS to another, the defining characteristic of these objects is what a virtual class captures. R and S version 3 do not explicitly define virtual classes, but they can easily implement the idea through inheritance.

  2. The term “database” is sometimes (confusingly) used both to denote the RDBMS, such as Oracle, MySQL, and also to denote a particular database instance under a RDBMS, such as “opto” or “sales” databases under the same RDBMS.

DBI/inst/doc/DBI-history.Rmd0000644000176200001440000001221413575266047015152 0ustar liggesusers--- title: "History of DBI" author: "David James" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{"History of DBI"} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The following history of DBI was contributed by David James, the driving force behind the development of DBI, and many of the packages that implement it. The idea/work of interfacing S (originally S3 and S4) to RDBMS goes back to the mid- and late 1990's in Bell Labs. The first toy interface I did was to implement John Chamber's early concept of "Data Management in S" (1991). The implementation followed that interface pretty closely and immediately showed some of the limitations when dealing with very large databases; if my memory serves me, the issue was the instance-based of the language back then, e.g., if you attached an RDBMS to the `search()` path and then needed to resolve a symbol "foo", you effectively had to bring all the objects in the database to check their mode/class, i.e., the instance object had the metadata in itself as attributes. The experiment showed that the S3 implementation of "data management" was not really suitable to large external RDBMS (probably it was never intended to do that anyway). (Note however, that since then, John and Duncan Temple Lang generalized the data management in S4 a lot, including Duncan's implementation in his RObjectTables package where he considered a lot of synchronization/caching issues relevant to DBI and, more generally, to most external interfaces). Back then we were working very closely with Lucent's microelectronics manufacturing --- our colleagues there had huge Oracle (mostly) databases that we needed to constantly query via [SQL*Plus](http://en.wikipedia.org/wiki/SQL*Plus). My colleague Jake Luciani was developing advanced applications in C and SQL, and the two of us came up with the first implementation of S3 directly connecting with Oracle. What I remember is that the Linux [PRO*C](http://en.wikipedia.org/wiki/Pro*C) pre-compiler (that embedded SQL in C code) was very buggy --- we spent a lot of time looking for workarounds and tricks until we got the C interface running. At the time, other projects within Bell Labs began using MySQL, and we moved to MySQL (with the help of Doug Bates' student Saikat DebRoy, then a summer intern) with no intentions of looking back at the very difficult Oracle interface. It was at this time that I moved all the code from S3 methods to S4 classes and methods and begun reaching out to the S/R community for suggestions, ideas, etc. All (most) of this work was on Bell Labs versions of S3 and S4, but I made sure it worked with S-Plus. At some point around 2000 (I don't remember exactly when), I ported all the code to R regressing to S3 methods, and later on (once S4 classes and methods were available in R) I re-implemented everything back to S4 classes and methods in R (a painful back-and-forth). It was at this point that I decided to drop S-Plus altogether. Around that time, I came across a very early implementation of SQLite and I was quite interested and thought it was a very nice RDBMS that could be used for all kinds of experimentation, etc., so it was pretty easy to implement on top of the DBI. Within the R community, there were quite a number of people that showed interest on defining a common interface to databases, but only a few folks actually provided code/suggestions/etc. (Tim Keitt was most active with the dbi/PostgreSQL packages --- he also was considering what he called "proxy" objects, which was reminiscent of what Duncan had been doing). Kurt Hornick, Vincent Carey, Robert Gentleman, and others provided suggestions/comments/support for the DBI definition. By around 2003, the DBI was more or less implemented as it is today. I'm sure I'll forget some (most should be in the THANKS sections of the various packages), but the names that come to my mind at this moment are Jake Luciani (ROracle), Don MacQueen and other early ROracle users (super helpful), Doug Bates and his student Saikat DebRoy for RMySQL, Fei Chen (at the time a student of Prof. Ripley) also contributed to RMySQL, Tim Keitt (working on an early S3 interface to PostgrSQL), Torsten Hothorn (worked with mSQL and also MySQL), Prof. Ripley working/extending the RODBC package, in addition to John Chambers and Duncan Temple-Lang who provided very important comments and suggestions. Actually, the real impetus behind the DBI was always to do distributed statistical computing --- *not* to provide a yet-another import/export mechanism --- and this perspective was driven by John and Duncan's vision and work on inter-system computing, COM, CORBA, etc. I'm not sure many of us really appreciated (even now) the full extent of those ideas and concepts. Just like in other languages (C's ODBC, Java's JDBC, Perl's DBI/DBD, Python dbapi), R/S DBI was meant to unify the interfacing to RDBMS so that R/S applications could be developed on top of the DBI and not be hard coded to any one relation database. The interface I tried to follow the closest was the Python's DBAPI --- I haven't worked on this topic for a while, but I still feel Python's DBAPI is the cleanest and most relevant for the S language. DBI/inst/doc/DBI.Rmd0000644000176200001440000001005113575266047013450 0ustar liggesusers--- title: "Introduction to DBI" author: "Katharina Brunner" date: "14 October 2019" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{"Introduction to DBI"} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` The {DBI} package defines a common interface between the R and database management systems (DBMS). Hence the name: DBI stands for **d**ata**b**ase **i**nterface. Using DBI, developers can focus on the functionalities of their code, instead of setting up the infrastructure depending on the underlying database. This DBMS-agnostic approach is possible, because DBI works best with several other packages that act as drivers to absorb the peculiarities of the specific DBMSs. These packages import {DBI} and implement its methods depending on the specific database management system. Currently, DBI works with the [many different database management systems](https://github.com/r-dbi/DBI/issues/274), e.g.: * MySQL, using the R-package [RMySQL](https://github.com/r-dbi/RMySQL) * MariaDB, using the R-package [RMariaDB](https://github.com/r-dbi/RMariaDB) * Postgres, using and the R-package [RPostgres](https://github.com/r-dbi/RPostgres) * SQLite, using and the R-package [RSQLite](https://github.com/r-dbi/RSQLite) DBI offers a set of classes and methods that define what operations are possible and how they are performed: * connect/disconnect to the DBMS * create and execute statements in the DBMS * extract results/output from statements * error/exception handling * information (meta-data) from database objects * transaction management (optional) ## Examples To showcase DBI capabilities, we create a in-memory RSQLite database ```{r} library(DBI) con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:") con ``` The function `dbListTables()` displays the names tables in the remote database. Since we haven't pushed any data to the database, there are no tables to show. ```{r} dbListTables(con) ``` We can write the famous data `mtcars` dataset to the remote database by using `dbWriteTable()`. Calling `dbListTables()` displays the table name: ```{r} dbWriteTable(con, "mtcars", mtcars) dbListTables(con) ``` To get all columns names of a remote table, use `dbListFields()`. It returns a character vector with all column names in the same order as in the database: ```{r} dbListFields(con, "mtcars") ``` If you want to import database table from the DBMS as a data frame, `dbReadTable()` helps to do that. Basically, it is the result of the most generic SQL call `SELECT * FROM `. ```{r} dbReadTable(con, "mtcars") ``` Of course, you can run more specific SQL queries, too. `dbGetQuery()` is the function to send a query to a database and retrieve the result as a data frame. Especially when working with large datasets, it is important to free the resources associated with retrieving the result. `dbGetQuery()` cares about this, too. ```{r} df <- dbGetQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df ``` Behind the scences, `dbGetQuery()` is a combination of `dbSendQuery()`, `dbFetch()` and `dbClearResult()`. The following snippet leads to the same result as `dbGetQuery()` above: ```{r} res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") df <- dbFetch(res) dbClearResult(res) df ``` When working with large datasets it might be smart to fetch the result step by step, not in one big chunk. This can be implemented with a `while` loop and a `dbFetch()` call that defines a maximum number of records to retrieve per fetch, here `n = 5`. There are eleven cars with four cylinders, so we expect two chunks of five rows and one chuck of one row: ```{r} res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") while(!dbHasCompleted(res)){ chunk <- dbFetch(res, n = 5) print(nrow(chunk)) } ``` Again, call `dbClearResult()` and disconnect from the connection with `dbDisconnect()`, when you are done: ```{r} dbClearResult(res) dbDisconnect(con) ``` ## Further Reading * An overview on [working with databases in R on Rstudio.com](https://db.rstudio.com/) DBI/inst/doc/DBI-history.html0000644000176200001440000002165413575372773015410 0ustar liggesusers History of DBI

History of DBI

David James

The following history of DBI was contributed by David James, the driving force behind the development of DBI, and many of the packages that implement it.

The idea/work of interfacing S (originally S3 and S4) to RDBMS goes back to the mid- and late 1990’s in Bell Labs. The first toy interface I did was to implement John Chamber’s early concept of “Data Management in S” (1991). The implementation followed that interface pretty closely and immediately showed some of the limitations when dealing with very large databases; if my memory serves me, the issue was the instance-based of the language back then, e.g., if you attached an RDBMS to the search() path and then needed to resolve a symbol “foo”, you effectively had to bring all the objects in the database to check their mode/class, i.e., the instance object had the metadata in itself as attributes. The experiment showed that the S3 implementation of “data management” was not really suitable to large external RDBMS (probably it was never intended to do that anyway). (Note however, that since then, John and Duncan Temple Lang generalized the data management in S4 a lot, including Duncan’s implementation in his RObjectTables package where he considered a lot of synchronization/caching issues relevant to DBI and, more generally, to most external interfaces).

Back then we were working very closely with Lucent’s microelectronics manufacturing — our colleagues there had huge Oracle (mostly) databases that we needed to constantly query via SQL*Plus. My colleague Jake Luciani was developing advanced applications in C and SQL, and the two of us came up with the first implementation of S3 directly connecting with Oracle. What I remember is that the Linux PRO*C pre-compiler (that embedded SQL in C code) was very buggy — we spent a lot of time looking for workarounds and tricks until we got the C interface running. At the time, other projects within Bell Labs began using MySQL, and we moved to MySQL (with the help of Doug Bates’ student Saikat DebRoy, then a summer intern) with no intentions of looking back at the very difficult Oracle interface. It was at this time that I moved all the code from S3 methods to S4 classes and methods and begun reaching out to the S/R community for suggestions, ideas, etc. All (most) of this work was on Bell Labs versions of S3 and S4, but I made sure it worked with S-Plus. At some point around 2000 (I don’t remember exactly when), I ported all the code to R regressing to S3 methods, and later on (once S4 classes and methods were available in R) I re-implemented everything back to S4 classes and methods in R (a painful back-and-forth). It was at this point that I decided to drop S-Plus altogether. Around that time, I came across a very early implementation of SQLite and I was quite interested and thought it was a very nice RDBMS that could be used for all kinds of experimentation, etc., so it was pretty easy to implement on top of the DBI.

Within the R community, there were quite a number of people that showed interest on defining a common interface to databases, but only a few folks actually provided code/suggestions/etc. (Tim Keitt was most active with the dbi/PostgreSQL packages — he also was considering what he called “proxy” objects, which was reminiscent of what Duncan had been doing). Kurt Hornick, Vincent Carey, Robert Gentleman, and others provided suggestions/comments/support for the DBI definition. By around 2003, the DBI was more or less implemented as it is today.

I’m sure I’ll forget some (most should be in the THANKS sections of the various packages), but the names that come to my mind at this moment are Jake Luciani (ROracle), Don MacQueen and other early ROracle users (super helpful), Doug Bates and his student Saikat DebRoy for RMySQL, Fei Chen (at the time a student of Prof. Ripley) also contributed to RMySQL, Tim Keitt (working on an early S3 interface to PostgrSQL), Torsten Hothorn (worked with mSQL and also MySQL), Prof. Ripley working/extending the RODBC package, in addition to John Chambers and Duncan Temple-Lang who provided very important comments and suggestions.

Actually, the real impetus behind the DBI was always to do distributed statistical computing — not to provide a yet-another import/export mechanism — and this perspective was driven by John and Duncan’s vision and work on inter-system computing, COM, CORBA, etc. I’m not sure many of us really appreciated (even now) the full extent of those ideas and concepts. Just like in other languages (C’s ODBC, Java’s JDBC, Perl’s DBI/DBD, Python dbapi), R/S DBI was meant to unify the interfacing to RDBMS so that R/S applications could be developed on top of the DBI and not be hard coded to any one relation database. The interface I tried to follow the closest was the Python’s DBAPI — I haven’t worked on this topic for a while, but I still feel Python’s DBAPI is the cleanest and most relevant for the S language.