RMySQL/0000755000175100001440000000000011705334641011363 5ustar hornikusersRMySQL/MD50000644000175100001440000000660411705334641011701 0ustar hornikusersc72363dd2c259cb03f3c84b7d67452ab *DESCRIPTION 8524589942ddd1223155da5f1f0b2fb6 *NAMESPACE 0ee18ec90b33c7f05db788f8e95c580a *R/MySQL.R b3134bfb5d92164d899131872dbb7b46 *R/MySQLSupport.R 048320acc0a04b16697dbf768422d9cd *R/S4R.R 66183fa2289e68135b335137ef922f56 *R/dbObjectId.R 5b151f734933cffa81cc749638d33bfd *R/zzz.R a7d5f50372f47d76ef94c2b82c02a80e *configure 72c6a759f166d493bd5a4bca79dfc217 *configure.in 6d42d4b30c8893ea8755823f65513275 *configure.win ef4fdd92dab8525330cd819c31c993cd *inst/FindMySQLhome.R 94d55d512a9ba36caa9b7df079bae19f *inst/GPL 7f96654033adf77d3afdce453e705e6c *inst/INSTALL 275548e83481040511e5e0ae748f53ed *inst/NEWS 0461db331194d75f15a1a77a179e761d *inst/README 2b8b06b164ec5d453b6872e51cec8905 *inst/README.windows 9dc93e1d5232c85fb49f5ca6d41c47e7 *inst/THANKS a48411df15dd1c02cbf1c7a7788ef8bf *inst/TODO 6d2a3c270c1a669f48c40f4456ff92c4 *inst/WindowsPath.txt e7843268f470a14492e4b13a8e80ddac *inst/doc/DBI.pdf 601d5fbeba706c6f03b51d20bec2c86f *inst/newFunctionNames.txt c49574e6e5966577398ba92efa9f19f0 *man/MySQL.Rd b284df8cf83aee06d748903155e4cf22 *man/MySQLConnection-class.Rd e5f5304362c367dd9edd87354379fa28 *man/MySQLDriver-class.Rd f3f8abebe2f52478b06fc275765a2084 *man/MySQLObject-class.Rd d7284f97c21df32b7ee4e59c7b6c4c6f *man/MySQLResult-class.Rd ab9c7e328ccca724365d003160ed96f8 *man/RMySQL-package.Rd c17850b19291ba18053c8b95ecaebcb0 *man/S4R.Rd acf49a664d28b530b0b62c5320872601 *man/dbApply-methods.Rd 094685d0196b672a7b6ebd424928bce3 *man/dbApply.Rd 0d9c1e1deb8a6f12ce119fa4a82305d5 *man/dbBuildTableDefinition.Rd 83c74f94fcb961ec99250b424e5684c4 *man/dbCallProc-methods.Rd cad8a0ccb26d7da71bb1a8f229415042 *man/dbCommit-methods.Rd 439b7bfd7ca0317c470ebce7d85e2c6b *man/dbConnect-methods.Rd 15cb1a03e3c588227fa5bf1314989d77 *man/dbDataType-methods.Rd 608e05ec9cd9f27b3f9a9504dc4775d3 *man/dbDriver-methods.Rd 60b74de937c4648a22398c88ec7a8c83 *man/dbEscapeStrings-methods.Rd 91093c7d250459575e87c31ece9ce1d9 *man/dbEscapeStrings.Rd d9d88703fba48ec6aad193b1c0ca82d6 *man/dbGetInfo-methods.Rd 6fcc0b97e07fe8314873e3b9fc6d6e53 *man/dbListTables-methods.Rd 8435c12642f32639cbd81b475233bb6b *man/dbNextResult-methods.Rd 1d136037b0a365b2189a35d5fc88a282 *man/dbNextResult.Rd a7e435833c102b86e410b7c505c5137f *man/dbObjectId-class.Rd 4724877eb40269e97bb0f6df206a20ad *man/dbReadTable-methods.Rd 7b13086e43499b6bc0dc09b969c4a377 *man/dbSendQuery-methods.Rd 7276af60ffdef298bca5775be5093b84 *man/dbSetDataMappings-methods.Rd d49374082cc3dc6a1fb9064ea104752b *man/fetch-methods.Rd cbf24d3b5b6ab2e8ce98d7df53aa42b7 *man/isIdCurrent.Rd 45c417b70f6157f20ec429c8dc8976c6 *man/make.db.names-methods.Rd 28400faeb31f67d63037146b6ac8d3f1 *man/mysqlClientLibraryVersions.Rd 36fe09fdbeb0a4cc6a693a5b7ad73890 *man/mysqlDBApply.Rd 04af37c9163ab5c2025cca66f368cdfb *man/mysqlSupport.Rd 31a34de30ed95141cf4201ac43dda487 *man/safe.write.Rd 650d8854df8d7169c0f06cd697fe76ba *man/summary-methods.Rd b363d2c1b9627aa0cbe89b04998ca6ec *src/Makevars.in 2c11cc6f639ee3aed3182984cc1047e4 *src/Makevars.win32 7e4d4e9b19fc2025f4de2beb8d779e14 *src/Makevars.win64 b529cd222b3015696bf992ff163b203c *src/RS-DBI.c bff2ee466b782ac8850126c42188c007 *src/RS-DBI.h 6a097eac2f3c1537d64220ffd396fa34 *src/RS-MySQL.c 95424df5256dfd3550e086a6b405606e *src/RS-MySQL.h 57c889afe8188b6dbaa63586f6cd0d29 *src/S4R.h 04e5914a4a36d4ef4821c227dba50ee7 *src/getopt.h b1d7080f5fb1f0ccffcc1e51c32e94d8 *tests/tests.R 669931b682cd23a193d768ae52aeacdd *tests/tests.Rout.save RMySQL/NAMESPACE0000644000175100001440000000352611703617102012602 0ustar hornikusersimport(methods) import(DBI) #useDynLib(RMySQL) ## Classes exportClasses( dbObjectId, MySQLObject, MySQLDriver, MySQLConnection, MySQLResult ) ## Methods/Generics exportMethods( coerce, dbApply, dbCallProc, dbClearResult, dbColumnInfo, dbCommit, dbConnect, dbDataType, dbDisconnect, dbEscapeStrings, dbExistsTable, dbGetException, dbGetInfo, dbGetQuery, dbGetRowCount, dbGetRowsAffected, dbGetStatement, dbHasCompleted, dbListConnections, dbListFields, dbListResults, dbListTables, dbMoreResults, dbNextResult, dbReadTable, dbRemoveTable, dbRollback, dbSendQuery, dbUnloadDriver, dbWriteTable, fetch, format, initialize, isSQLKeyword, make.db.names, show, SQLKeywords, summary ) ## regular functions (most of these will be made private) export( MySQL, dbBuildTableDefinition, isIdCurrent, .MySQLKeywords, mysqlInitDriver, mysqlCloseDriver, mysqlDescribeDriver, mysqlDriverInfo, mysqlNewConnection, mysqlCloneConnection, mysqlDescribeConnection, mysqlConnectionInfo, mysqlCloseConnection, mysqlExecStatement, mysqlQuickSQL, mysqlDBApply, mysqlFetch, mysqlResultInfo, mysqlDescribeResult, mysqlDescribeFields, mysqlCloseResult, mysqlImportFile, mysqlReadTable, mysqlWriteTable, mysqlEscapeStrings, mysqlDataType, mysqlClientLibraryVersions, safe.write ) ## constants export( CLIENT_LONG_PASSWORD, CLIENT_FOUND_ROWS, CLIENT_LONG_FLAG, CLIENT_CONNECT_WITH_DB, CLIENT_NO_SCHEMA, CLIENT_COMPRESS, CLIENT_ODBC, CLIENT_LOCAL_FILES, CLIENT_IGNORE_SPACE, CLIENT_PROTOCOL_41, CLIENT_INTERACTIVE, CLIENT_SSL, CLIENT_IGNORE_SIGPIPE, CLIENT_TRANSACTIONS, CLIENT_RESERVED, CLIENT_SECURE_CONNECTION, CLIENT_MULTI_STATEMENTS, CLIENT_MULTI_RESULTS ) RMySQL/DESCRIPTION0000644000175100001440000000126411705334641013074 0ustar hornikusersPackage: RMySQL Version: 0.9-3 Date: 2012-01-17 Title: R interface to the MySQL database Author: David A. James and Saikat DebRoy Maintainer: Jeffrey Horner Description: Database interface and MySQL driver for R. This version complies with the database interface definition as implemented in the package DBI 0.2-2. LazyLoad: true Depends: R (>= 2.8.0), methods, DBI (>= 0.2-2), utils License: GPL-2 URL: http://biostat.mc.vanderbilt.edu/RMySQL, https://github.com/jeffreyhorner/RMySQL Collate: S4R.R zzz.R MySQLSupport.R dbObjectId.R MySQL.R Packaged: 2012-01-17 16:38:02 UTC; hornerj Repository: CRAN Date/Publication: 2012-01-17 18:10:41 RMySQL/configure.in0000644000175100001440000002004411703617102013666 0ustar hornikusersdnl dnl RMySQL dnl dnl $Id$ dnl dnl Generate a "configure" script that will install the RMySQL package. dnl dnl NOTE: The resulting configure script implements the following logic: dnl dnl 1. If PKG_CPPFLAGS and PKG_LIBS are defined, use them (as suggested in dnl Section 1.2.1 in the "Writing R Extensions, 1.3.0). Ditto for dnl MYSQL_DIR, MYSQL_INC, MYSQL_LIB. dnl dnl 2. We check for mysql.h and -lmysqlclient in system directories, and if dnl found, we use these (provide the user does not explicitly request dnl another version, see below). Notice that the MySQL source distribution dnl installs by default to /usr/local/lib/mysql and /usr/local/include/mysql dnl dnl 3. Alternatively, if the user specifies explicitly a particular MySQL dnl installation we use that version. This can be requested through dnl --with-mysql-dir=DIR dnl --with-mysql-inc= dnl or --with-mysql-lib= dnl dnl (these are equivent to setting and exporting MYSQL_{DIR,INC,LIB}) dnl In the first case, DIR is assumed to include the lib and include dnl subdirectories; individual locations of these two may be dnl specified independently through and , dnl respectively. If we found these, we exit. dnl dnl 4. We check for the GNU implementation of getopt_long and set the dnl C preprocessor macro HAVE_GETOPT_LONG accordingly. On windows dnl (including MinGW) should be false. dnl dnl Global variables: The following variables may be set and exported dnl prior to running configure: dnl PKG_CPPFLAGS, PKG_LIBS, MYSQL_DIR, MYSQL_INC, MYSQL_LIB dnl AC_INIT(src/RS-MySQL.c) AC_PROG_CPP # Some people have reported not having libz (which we clearly is needed # in the INSTALL file). Oh well. # AC_CHECK_LIB(z, compress, HAVE_COMPRESS="yes", HAVE_COMPRESS="no") # Do we have access to GNU's getopt_long (problem on some systems, e.g., # FreeBDS, Mac OS/X, Windows/MinGW) # AC_CHECK_LIB(c, getopt_long, HAVE_GETOPT_LONG="yes", HAVE_GETOPT_LONG="no") # can we find MySQL in the system directories? (users may still want/need # to use another version/installation) # AC_CHECK_LIB(mysqlclient, mysql_init, HAVE_MYSQL_LIB="yes", HAVE_MYSQL_LIB="") AC_CHECK_HEADERS(mysql.h, HAVE_MYSQL_INC="yes", HAVE_MYSQL_INC="") # # the user may still want a particular MySQL installation/version (possibly # overriding system directories). Note that we don't clobber the shell # variables MYSQL_DIR, MSYQL_INC, MYSQL_LIB, that may be inherited from the # global shell environement. # AC_ARG_WITH(mysql-dir, [--with-mysql-dir=MYSQL_DIR specifies an existing MySQL base dir], MYSQL_DIR="${with_mysql_dir}") AC_ARG_WITH(mysql-inc, [--with-mysql-inc=MYSQL_INC specifies an existing MySQL include dir], MYSQL_INC="${with_mysql_inc}") AC_ARG_WITH(mysql-lib, [--with-mysql-lib=MYSQL_LIB specifies an existing MySQL lib dir], MYSQL_LIB="${with_mysql_lib}") # handle the uniformative cases of --with-mysql w.o. argument # and the case of -with-no-mysql test "${MYSQL_DIR}" = "yes" -o "${MYSQL_DIR}" = "no" && MYSQL_DIR="" test "${MYSQL_LIB}" = "yes" -o "${MYSQL_LIB}" = "no" && MYSQL_LIB="" test "${MYSQL_INC}" = "yes" -o "${MYSQL_INC}" = "no" && MYSQL_INC="" if test -n "${MYSQL_DIR}" ; then test ! -d "${MYSQL_DIR}" && AC_MSG_ERROR([dir ${MYSQL_DIR} does not exist]) test -z "${MYSQL_INC}" -a -d "${MYSQL_DIR}/include/mysql" && \ MYSQL_INC="${MYSQL_DIR}/include/mysql" test -z "${MYSQL_LIB}" -a -d "${MYSQL_DIR}/lib/mysql" && \ MYSQL_LIB="${MYSQL_DIR}/lib/mysql" fi # # We now determine whether we found the lib and header files (we still # need to check PKG_*, in case the user only defined one them) # if test -z "${PKG_LIBS}" ; then if test -n "${MYSQL_LIB}" ; then # use the one specified in --with-mysql-* PKG_LIBS="-L${MYSQL_LIB} -lmysqlclient" else # use the one in the system dirs (if there's one) test -n "${HAVE_MYSQL_LIB}" && PKG_LIBS="-lmysqlclient" fi fi if test -z "${PKG_CPPFLAGS}" ; then if test -n "${MYSQL_INC}" ; then # use the one specified in --with-mysql-inc=DIR PKG_CPPFLAGS="-I${MYSQL_INC}" FOUND_INC="yes" else if test -n "${HAVE_MYSQL_INC}" ; then # use the one in the system dirs PKG_CPPFLAGS="" FOUND_INC="yes" else PKG_CPPFLAGS="" FOUND_INC="no" fi fi fi if test "${HAVE_GETOPT_LONG}" = "no" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DHAVE_GETOPT_LONG=0 " fi # if above fails, do a more exhaustive search into potential mysql # subdirectories of the system directories. if test -z "${HAVE_MYSQL_LIB}" -a -z "${PKG_LIBS}" ; then for dir in /usr/local/lib64 /usr/lib64 \ /usr/local/lib /usr/lib /usr/local/mysql/lib /opt/lib /lib do # need to release mysqlcient from cache unset ac_cv_lib_mysqlclient_mysql_init candidate="${dir}/mysql" AC_CHECK_LIB(mysqlclient, mysql_init, HAVE_MYSQL_LIB="${candidate}", HAVE_MYSQL_LIB="", [-L${candidate}]) if test -n "${HAVE_MYSQL_LIB}" ; then echo " mysqlclient found in -L${HAVE_MYSQL_LIB}" PKG_LIBS="-L${HAVE_MYSQL_LIB} -lmysqlclient" break fi done fi # ditto for the header files if test -z "${HAVE_MYSQL_INC}" -a -z "${PKG_CPPFLAGS}" ; then for dir in /usr/local/include /usr/include /usr/local/mysql/include \ /opt/include /include do candidate="${dir}/mysql" AC_CHECK_HEADER(${candidate}/mysql.h, HAVE_MYSQL_INC="${candidate}", HAVE_MYSQL_INC="") if test -n "${HAVE_MYSQL_INC}" ; then PKG_CPPFLAGS="-I${HAVE_MYSQL_INC}" FOUND_INC="yes" break fi done fi # don't go any further if don't have libz if test "${HAVE_COMPRESS}" = "no" ; then echo "" echo "Configuration error:" echo ' Could not locate the library "libz" required by MySQL.' echo "" echo "INSTRUCTIONS:" echo "" echo ' The "libz" library is required by the MySQL client library' echo " in order to compress/uncompress connections between clients" echo " and the MySQL engine." echo "" echo ' Make sure you have "libz" installed properly and/or included' echo ' in your $LD_LIBRARY_PATH. Perhaps it is not in any of the' echo " standard directories (e.g., /usr/lib/, /usr/local/lib)?" echo "" echo "Aborting the installation of RMySQL." echo "" exit 1 fi # If we stil haven't set PKG_*, error if test "${FOUND_INC}" = "no" -o -z "${PKG_LIBS}" ; then echo "" echo "Configuration error:" echo " could not find the MySQL installation include and/or library" echo " directories. Manually specify the location of the MySQL" echo " libraries and the header files and re-run R CMD INSTALL." echo "" echo "INSTRUCTIONS:" echo "" echo "1. Define and export the 2 shell variables PKG_CPPFLAGS and" echo " PKG_LIBS to include the directory for header files (*.h)" echo " and libraries, for example (using Bourne shell syntax):" echo "" echo ' export PKG_CPPFLAGS="-I"' echo ' export PKG_LIBS="-L -lmysqlclient"' echo "" echo " Re-run the R INSTALL command:" echo "" echo " R CMD INSTALL RMySQL_.tar.gz" echo "" echo "2. Alternatively, you may pass the configure arguments" echo " --with-mysql-dir= (distribution directory)" echo " or" echo " --with-mysql-inc= (where MySQL header files reside)" echo " --with-mysql-lib= (where MySQL libraries reside)" echo " in the call to R INSTALL --configure-args='...' " echo "" echo " R CMD INSTALL --configure-args='--with-mysql-dir=DIR' RMySQL_.tar.gz" echo "" exit 1 fi AC_SUBST(PKG_CPPFLAGS) AC_SUBST(PKG_LIBS) AC_OUTPUT(src/Makevars) RMySQL/man/0000755000175100001440000000000011703617102012130 5ustar hornikusersRMySQL/man/mysqlDBApply.Rd0000644000175100001440000000771511703617102015012 0ustar hornikusers% $Id$ \name{mysqlDBApply} \alias{mysqlDBApply} \title{Apply R/S-Plus functions to remote groups of DBMS rows (experimental)} \description{ Applies R/S-Plus functions to groups of remote DBMS rows without bringing an entire result set all at once. The result set is expected to be sorted by the grouping field. } \usage{ mysqlDBApply(res, INDEX, FUN = stop("must specify FUN"), begin = NULL, group.begin = NULL, new.record = NULL, end = NULL, batchSize = 100, maxBatch = 1e6, ..., simplify = TRUE) } \arguments{ \item{res}{a result set (see \code{\link[DBI]{dbSendQuery}}).} \item{INDEX}{a character or integer specifying the field name or field number that defines the various groups.} \item{FUN}{a function to be invoked upon identifying the last row from every group. This function will be passed a data frame holding the records of the current group, a character string with the group label, plus any other arguments passed to \code{dbApply} as \code{"..."}.} \item{begin}{a function of no arguments to be invoked just prior to retrieve the first row from the result set.} \item{end}{a function of no arguments to be invoked just after retrieving the last row from the result set.} \item{group.begin}{a function of one argument (the group label) to be invoked upon identifying a row from a new group}. \item{new.record}{a function to be invoked as each individual record is fetched. The first argument to this function is a one-row data.frame holding the new record.} \item{batchSize}{the default number of rows to bring from the remote result set. If needed, this is automatically extended to hold groups bigger than \code{batchSize}.} \item{maxBatch}{the absolute maximum of rows per group that may be extracted from the result set.} \item{...}{any additional arguments to be passed to \code{FUN}.} \item{simplify}{Not yet implemented} } \details{ \code{dbApply} This function is meant to handle somewhat gracefully(?) large amounts of data from the DBMS by bringing into R manageable chunks (about \code{batchSize} records at a time, but not more than \code{maxBatch}); the idea is that the data from individual groups can be handled by R, but not all the groups at the same time. The MySQL implementation \code{mysqlDBApply} allows us to register R functions that get invoked when certain fetching events occur. These include the ``begin'' event (no records have been yet fetched), ``begin.group'' (the record just fetched belongs to a new group), ``new record'' (every fetched record generates this event), ``group.end'' (the record just fetched was the last row of the current group), ``end'' (the very last record from the result set). Awk and perl programmers will find this paradigm very familiar (although SAP's ABAP language is closer to what we're doing). } \value{ A list with as many elements as there were groups in the result set. } \note{This is an experimental version implemented only in R (there are plans, time permitting, to implement it in S-Plus). The terminology that we're using is closer to SQL than R. In R what we're referring to ``groups'' are the individual levels of a factor (grouping field in our terminology). } \seealso{\code{\link{MySQL}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{fetch}}.} \examples{\dontrun{ ## compute quanitiles for each network agent con <- dbConnect(MySQL(), group="vitalAnalysis") res <- dbSendQuery(con, "select Agent, ip_addr, DATA from pseudo_data order by Agent") out <- dbApply(res, INDEX = "Agent", FUN = function(x, grp) quantile(x$DATA, names=FALSE)) } } \keyword{programming}% at least one, from doc/KEYWORDS \keyword{interface}% __ONLY ONE__ keyword per line \keyword{database} % vim: syntax=tex RMySQL/man/dbObjectId-class.Rd0000644000175100001440000000272311703617102015517 0ustar hornikusers% $Id$ \name{dbObjectId-class} \docType{class} \alias{dbObjectId-class} \title{Class dbObjectId} \description{ A helper (mixin) class to provide external references in an R/S-Plus portable way. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Slots}{ \describe{ \item{\code{Id}:}{Object of class \code{"integer"} this is an integer vector holding an opaque reference into a C struct (may or may not be a C pointer, may or may not have length one). } } } \section{Methods}{ \describe{ \item{\link{coerce}}{\code{signature(from = "dbObjectId", to = "integer")}: ... } \item{\link{coerce}}{\code{signature(from = "dbObjectId", to = "numeric")}: ... } \item{\link{coerce}}{\code{signature(from = "dbObjectId", to = "character")}: ... } \item{\link{format}}{\code{signature(x = "dbObjectId")}: ... } \item{\link{print}}{\code{signature(x = "dbObjectId")}: ... } \item{\link{show}}{\code{signature(object = "dbObjectId")}: ... } } } \note{A cleaner mechanism would use external references, but historically this class has existed mainly for R/S-Plus portability.} \examples{\dontrun{ pg <- dbDriver("PostgreSQL") con <- dbConnect(pg, "user", "password") is(pg, "dbObjectId") ## True is(con, "dbObjectId") ## True isIdCurrent(con) ## True q("yes") \$ R isIdCurrent(con) ## False } } \keyword{classes} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/MySQLConnection-class.Rd0000644000175100001440000000544111703617102016513 0ustar hornikusers% $Id$ \name{MySQLConnection-class} \docType{class} \alias{MySQLConnection-class} \title{Class MySQLConnection} \description{MySQLConnection class.} \section{Generators}{ The method \code{\link[DBI]{dbConnect}} is the main generator. } \section{Extends}{ Class \code{"DBIConnection"}, directly. Class \code{"MySQLObject"}, directly. Class \code{"DBIObject"}, by class "DBIConnection". Class \code{"dbObjectId"}, by class "MySQLObject". } \section{Methods}{ \describe{ \item{\link{coerce}}{\code{signature(from = "MySQLConnection", to = "MySQLResult")}: ... } \item{\link[DBI]{dbCallProc}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbCommit}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbConnect}}{\code{signature(drv = "MySQLConnection")}: ... } \item{\link[DBI]{dbDisconnect}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbExistsTable}}{\code{signature(conn = "MySQLConnection", name = "character")}: ... } \item{\link[DBI]{dbGetException}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbGetInfo}}{\code{signature(dbObj = "MySQLConnection")}: ... } \item{\link[DBI]{dbGetQuery}}{\code{signature(conn = "MySQLConnection", statement = "character")}: ... } \item{\link[DBI]{dbListFields}}{\code{signature(conn = "MySQLConnection", name = "character")}: ... } \item{\link[DBI]{dbListResults}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbListTables}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbReadTable}}{\code{signature(conn = "MySQLConnection", name = "character")}: ... } \item{\link[DBI]{dbRemoveTable}}{\code{signature(conn = "MySQLConnection", name = "character")}: ... } \item{\link[DBI]{dbRollback}}{\code{signature(conn = "MySQLConnection")}: ... } \item{\link[DBI]{dbSendQuery}}{\code{signature(conn = "MySQLConnection", statement = "character")}: ... } \item{\link[DBI]{dbWriteTable}}{\code{signature(conn = "MySQLConnection", name = "character", value = "data.frame")}: ... } \item{summary}{\code{signature(object = "MySQLConnection")}: ... } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://developer.r-project.org/db}. } \seealso{ DBI base classes: \code{\link[DBI]{DBIObject-class}} \code{\link[DBI]{DBIDriver-class}} \code{\link[DBI]{DBIConnection-class}} \code{\link[DBI]{DBIResult-class}} MySQL classes: \code{\link{MySQLObject-class}} \code{\link{MySQLDriver-class}} \code{\link{MySQLConnection-class}} \code{\link{MySQLResult-class}} } \examples{\dontrun{ drv <- dbDriver("MySQL) con <- dbConnect(drv, dbname = "rsdbi.db") } } \keyword{database} \keyword{interface} \keyword{classes} % vim: syntax=tex RMySQL/man/dbSendQuery-methods.Rd0000644000175100001440000000265511703617102016315 0ustar hornikusers% $Id$ \name{dbSendQuery-methods} \docType{methods} \alias{dbSendQuery-methods} \alias{dbGetQuery-methods} \alias{dbClearResult-methods} \alias{dbGetException-methods} \alias{dbSendQuery,MySQLConnection,character-method} \alias{dbGetQuery,MySQLConnection,character-method} \alias{dbClearResult,MySQLResult-method} \alias{dbGetException,MySQLConnection-method} \alias{dbGetException,MySQLResult-method} \title{ Execute a statement on a given database connection } \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{conn}{ an \code{MySQLConnection} object. } \item{statement}{a character vector of length 1 with the SQL statement.} \item{res}{an \code{MySQLResult} object.} \item{\dots }{additional parameters.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbDriver}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, "usr", "password", "dbname") res <- dbSendQuery(con, "SELECT * from liv25") data <- fetch(res, n = -1) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbNextResult-methods.Rd0000644000175100001440000000525411703617102016511 0ustar hornikusers\name{dbNextResult-methods} \docType{methods} \alias{dbNextResult-methods} \alias{dbNextResult,MySQLConnection-method} \alias{dbMoreResults-methods} \alias{dbMoreResults,MySQLConnection-method} \title{Fetch Next Result Set from Multiple Statements or Stored Procedures} \description{ \code{dbMoreResults} checks whether there are additional result sets for processing. \code{dbNextResult} fetches the next result set. } \section{Methods}{ \describe{ These MySQL methods provide functionality to sequentially extract multiple results produced by SQL scripts or stored procedures. In the case of stored procedures invoked with \code{CALL}, the first result set indicates the call status, and output data (if any) are return as additional result sets. \item{con = "MySQLConnection"}{a MySQL connection object.} } } \section{Note}{ MySQL supports SQL scripts (a single string with multiple statements terminated by ';') from version 4.1.1 onwards and stored procedures from version 5.0. To process SQL scripts on a MySQL connection, the connection must be created using the \code{CLIENT\_MULTI\_STATEMENTS}. In addition, to process stored procedures that return one or more result sets, the connection must be created using the \code{CLIENT\_MULTI\_RESULTS} client flag. For simplicity, use \code{CLIENT\_MULTI\_STATEMENTS} for working with either SQL scripts or stored procedures. For more details, read on. More precisely, to execute multiple statements the connection needs \code{CLIENT\_MULTI\_STATEMENTS}; this in turn automatically enables \code{CLIENT\_MULTI\_RESULTS} for \emph{fetching} of multiple output results. On the other hand, the client flag \code{CLIENT\_MULTI\_RESULTS} by itself enables stored procedures to return one or more results. See the MySQL documentation in \url{www.mysql.com} for full details. } \keyword{methods} \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbHasCompleted}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ con <- dbConnect(MySQL(), dbname = "rs-dbi", client.flag=CLIENT\_MULTI\_STATEMENTS) sql.script <- paste( "select * from abc", "select * def", collapse = ";") rs1 <- dbSendQuery(con, sql.script) data1 <- fetch(rs1, n = -1) if(dbMoreResults(con)){ rs2 <- dbNextResult(con) ## you could use dbHasCompleted(rs2) to determine whether ## rs2 is a select-like that generates output or not. data2 <- fetch(rs2, n = -1) } } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/MySQLResult-class.Rd0000644000175100001440000000443211703617102015671 0ustar hornikusers% $Id$ \name{MySQLResult-class} \docType{class} \alias{MySQLResult-class} \title{Class MySQLResult} \description{ MySQL's query results class. This classes encapsulates the result of an SQL statement (either \code{select} or not). } \section{Generators}{ The main generator is \code{\link[DBI]{dbSendQuery}}. } \section{Extends}{ Class \code{"DBIResult"}, directly. Class \code{"MySQLObject"}, directly. Class \code{"DBIObject"}, by class "DBIResult". Class \code{"dbObjectId"}, by class "MySQLObject". } \section{Methods}{ \describe{ \item{\link{coerce}}{\code{signature(from = "MySQLConnection", to = "MySQLResult")}: ... } \item{\link[DBI]{dbClearResult}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbColumnInfo}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbGetException}}{\code{signature(conn = "MySQLResult")}: ... } \item{\link[DBI]{dbGetInfo}}{\code{signature(dbObj = "MySQLResult")}: ... } \item{\link[DBI]{dbGetRowCount}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbGetRowsAffected}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbGetStatement}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbHasCompleted}}{\code{signature(res = "MySQLResult")}: ... } \item{\link[DBI]{dbListFields}}{\code{signature(conn = "MySQLResult", name = "missing")}: ... } \item{\link[DBI]{fetch}}{\code{signature(res = "MySQLResult", n = "numeric")}: ... } \item{\link[DBI]{fetch}}{\code{signature(res = "MySQLResult", n = "missing")}: ... } \item{\link{summary}}{\code{signature(object = "MySQLResult")}: ... } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://developer.r-project.org/db}. } \seealso{ DBI base classes: \code{\link[DBI]{DBIObject-class}} \code{\link[DBI]{DBIDriver-class}} \code{\link[DBI]{DBIConnection-class}} \code{\link[DBI]{DBIResult-class}} MySQL classes: \code{\link{MySQLObject-class}} \code{\link{MySQLDriver-class}} \code{\link{MySQLConnection-class}} \code{\link{MySQLResult-class}} } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, dbname = "rsdbi.db") } } \keyword{database} \keyword{interface} \keyword{classes} % vim: syntax=tex RMySQL/man/dbApply-methods.Rd0000644000175100001440000000233011703617102015451 0ustar hornikusers% $Id$ \name{dbApply-methods} \docType{methods} \alias{dbApply-methods} \alias{dbApply,MySQLResult-method} \title{Apply R/S-Plus functions to remote groups of DBMS rows (experimental)} \description{ Applies R/S-Plus functions to groups of remote DBMS rows without bringing an entire result set all at once. The result set is expected to be sorted by the grouping field. } \section{Methods}{\describe{ \item{res}{a MySQL result set (see \code{\link[DBI]{dbSendQuery}}).} \item{...}{any additional arguments to be passed to \code{FUN}.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}} \code{\link{mysqlDBApply}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{fetch}} } \examples{\dontrun{ ## compute quanitiles for each network agent con <- dbConnect(MySQL(), group="vitalAnalysis") rs <- dbSendQuery(con, "select Agent, ip_addr, DATA from pseudo_data order by Agent") out <- dbApply(rs, INDEX = "Agent", FUN = function(x, grp) quantile(x$DATA, names=FALSE)) } } \keyword{programming} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbGetInfo-methods.Rd0000644000175100001440000000400211703617102015715 0ustar hornikusers% $Id$ \name{dbGetInfo-methods} \docType{methods} \alias{dbGetInfo} \alias{dbGetDBIVersion-methods} \alias{dbGetStatement-methods} \alias{dbGetRowCount-methods} \alias{dbGetRowsAffected-methods} \alias{dbColumnInfo-methods} \alias{dbHasCompleted-methods} \alias{dbGetInfo,MySQLObject-method} \alias{dbGetInfo,MySQLDriver-method} % BUG: this is not needed \alias{dbGetInfo,MySQLConnection-method} % BUG: this is not needed \alias{dbGetInfo,MySQLResult-method} % BUG: this is not needed \alias{dbGetStatement,MySQLResult-method} \alias{dbGetRowCount,MySQLResult-method} \alias{dbGetRowsAffected,MySQLResult-method} \alias{dbColumnInfo,MySQLResult-method} \alias{dbColumnInfo,MySQLConnection-method} \alias{dbHasCompleted,MySQLResult-method} \title{ Database interface meta-data } \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{dbObj}{ any object that implements some functionality in the R/S-Plus interface to databases (a driver, a connection or a result set). } \item{res}{ an \code{MySQLResult}.} \item{\dots}{currently not being used.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbDriver}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbListTables}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, group = "wireless") dbListTables(con) rs <- dbSendQuery(con, query.sql) dbGetStatement(rs) dbHasCompleted(rs) info <- dbGetInfo(rs) names(dbGetInfo(drv)) # DBIConnection info names(dbGetInfo(con)) # DBIResult info names(dbGetInfo(rs)) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbEscapeStrings.Rd0000644000175100001440000000173411703617102015504 0ustar hornikusers% $Id$ \name{dbEscapeStrings} \alias{dbEscapeStrings} \title{Escape SQL-special characters in strings} \description{ is expected to be sorted by the grouping field. } \usage{ dbEscapeStrings(con, strings, ...) } \arguments{ \item{con}{a connection object (see \code{\link[DBI]{dbConnect}}).} \item{strings}{a character vector.} \item{...}{any additional arguments to be passed to the dispatched method.} } \details{ \code{dbEscapeStrings} Currently, only the \code{\link{MySQL}} driver implements this method. } \value{ A character vector with SQL special characters properly escaped. } \seealso{ \code{\link{MySQL}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{fetch}} } \examples{\dontrun{ tmp <- sprintf("select * from emp where lname = \%s", "O'Reilly") sql <- dbEscapeString(con, tmp) dbGetQuery(con, sql) } } \keyword{programming}% at least one, from doc/KEYWORDS \keyword{interface}% __ONLY ONE__ keyword per line \keyword{database} % vim: syntax=tex RMySQL/man/mysqlSupport.Rd0000644000175100001440000002463111703617102015167 0ustar hornikusers% $Id$ \name{mysqlSupport} \alias{mysqlInitDriver} % driver-related function \alias{mysqlDriverInfo} \alias{mysqlDescribeDriver} \alias{mysqlCloseDriver} % connection-related \alias{mysqlNewConnection} \alias{mysqlCloneConnection} \alias{mysqlConnectionInfo} \alias{mysqlDescribeConnection} \alias{mysqlCloseConnection} \alias{mysqlExecStatement} % result-related \alias{mysqlFetch} \alias{mysqlQuickSQL} \alias{mysqlResultInfo} \alias{mysqlDescribeResult} \alias{mysqlCloseResult} \alias{mysqlDescribeFields} \alias{mysqlReadTable} \alias{mysqlWriteTable} % convenience functions \alias{mysqlImportFile} \alias{mysqlDataType} \alias{mysqlEscapeStrings} \alias{.MySQLPkgName} % constants \alias{.MySQLPkgVersion} \alias{.MySQLPkgRCS} \alias{.MySQL.NA.string} \alias{.MySQLSQLKeywords} \alias{.conflicts.OK} \alias{CLIENT_LONG_PASSWORD} % new more secure passwords \alias{CLIENT_FOUND_ROWS} % Found instead of affected rows \alias{CLIENT_LONG_FLAG} % Get all column flags \alias{CLIENT_CONNECT_WITH_DB} % One can specify db on connect \alias{CLIENT_NO_SCHEMA} % Don't allow database.table.column \alias{CLIENT_COMPRESS} % Can use compression protocol \alias{CLIENT_ODBC} % Odbc client \alias{CLIENT_LOCAL_FILES} % Can use LOAD DATA LOCAL \alias{CLIENT_IGNORE_SPACE} % Ignore spaces before '(' \alias{CLIENT_PROTOCOL_41} % New 4.1 protocol \alias{CLIENT_INTERACTIVE} % This is an interactive client \alias{CLIENT_SSL} % Switch to SSL after handshake \alias{CLIENT_IGNORE_SIGPIPE} % IGNORE sigpipes \alias{CLIENT_TRANSACTIONS} % Client knows about transactions \alias{CLIENT_RESERVED} % Old flag for 4.1 protocol \alias{CLIENT_SECURE_CONNECTION} % New 4.1 authentication \alias{CLIENT_MULTI_STATEMENTS} % Enable/disable multi-stmt support \alias{CLIENT_MULTI_RESULTS} % Enable/disable multi-results %\non_function{} \title{Support Functions} \description{ These functions are the workhorse behind the RMySQL package, but users need not invoke these directly. For details see \code{\link{MySQL}}. } \usage{ ## MySQLDriver-related mysqlInitDriver(max.con=16, fetch.default.rec = 500, force.reload=FALSE) mysqlDriverInfo(obj, what, ...) mysqlDescribeDriver(obj, verbose = FALSE, ...) mysqlCloseDriver(drv, ...) ## MySQLConnection-related mysqlNewConnection(drv, dbname, username, password, host, unix.socket, port, client.flag, groups, default.file) mysqlCloneConnection(con, ...) mysqlConnectionInfo(obj, what, ...) mysqlDescribeConnection(obj, verbose = FALSE, ...) mysqlCloseConnection(con, ...) ## MySQLResult-related mysqlExecStatement(con, statement) mysqlFetch(res, n=0, ...) mysqlQuickSQL(con, statement) mysqlResultInfo(obj, what, ...) mysqlDescribeResult(obj, verbose = FALSE, ...) mysqlCloseResult(res, ...) mysqlDescribeFields(res, ...) ## data mappings, convenience functions, and extensions mysqlDataType(obj, ...) mysqlReadTable(con, name, row.names = "row_names", check.names = TRUE, ...) mysqlWriteTable(con, name, value, field.types, row.names = TRUE, overwrite=FALSE, append=FALSE, ..., allow.keywords = FALSE) mysqlImportFile(con, name, value, field.types, overwrite=FALSE, append=FALSE, header, row.names, nrows=50, sep=",", eol="\n", skip = 0, quote='"', ...) mysqlEscapeStrings(con, strings) } \arguments{ \item{max.con}{ positive integer specifying maximum number of open connections. The current default of 10 is hardcoded in the C code. } \item{fetch.default.rec}{ default number of rows to fetch (move to R/S-Plus). This default is used in \code{mysqlFetch}. The default is 500. } \item{force.reload}{ logical indicating whether to re-initialize the driver. This may be useful if you want to change the defaults (e.g., \code{fetch.default.rec}). Note that the driver is a singleton (subsequent inits just returned the previously initialized driver, thus this argument). } \item{obj}{ any of the MySQL DBI objects (e.g., \code{MySQLConnection}, \code{MySQLResult}). } \item{what}{ character vector of metadata to extract, e.g., "version", "statement", "isSelect". } \item{verbose}{ logical controlling how much information to display. Defaults to \code{FALSE}. } \item{drv}{ an \code{MySQLDriver} object as produced by \code{mysqlInitDriver}. } \item{con}{ an \code{MySQLConnection} object as produced by \code{mysqlNewConnection} and \code{mysqlCloneConnection}. } \item{res}{ an \code{MySQLResult} object as produced by by \code{mysqlExecStatement}. } \item{username}{ a character string with the MySQL's user name. } \item{password}{ character string with the MySQL's password. } \item{groups}{ character vector with one or more MySQL group names. For details see \code{\link{MySQL}}. } \item{default.file}{filename of an alternate MySQL options file.} \item{dbname}{ character string with the MySQL database name.} \item{host}{ character string with the name (or IP address) of the machine hosting the database. Default is \code{""}, which is interpreted as \code{localhost} by the MySQL's API. } \item{unix.socket}{ (optional) character string with a filename for the socket file name. Consult the MySQL documentation for details. } \item{port}{ (optional) positive integer specifying the TCP port number that the MySQL server is listening to. Consult the MySQL documentation for details. } \item{client.flag}{ (optional) integer setting flags for the client. Consult the MySQL documentation for details. } \item{force}{ logical indicating whether to close a connection that has open result sets. The default is \code{FALSE}. } \item{statement}{ character string holding one (and only one) SQL statement. } \item{n}{ number of rows to fetch from the given result set. A value of -1 indicates to retrieve all the rows. The default of 0 specifies to extract whatever the \code{fetch.default.rec} was specified during driver initialization \code{mysqlInit}. } \item{name}{ character vector of names (table names, fields, keywords). } \item{value}{ a data.frame. } \item{field.types}{ a list specifying the mapping from R/S-Plus fields in the data.frame \code{value} to SQL data types. The default is \code{sapply(value,SQLDataType)}, see \code{MySQLSQLType}. } \item{header}{ logical, does the input file have a header line? Default is the same heuristic used by \code{read.table}, i.e., TRUE if the first line has one fewer column that the second line. } \item{row.names}{ a logical specifying whether to prepend the \code{value} data.frame row names or not. The default is \code{TRUE}. } \item{check.names}{ a logical specifying whether to convert DBMS field names into legal S names. Default is \code{TRUE}. } \item{overwrite}{ logical indicating whether to replace the table \code{name} with the contents of the data.frame \code{value}. The defauls is \code{FALSE}. } \item{append}{ logical indicating whether to append \code{value} to the existing table \code{name}. } \item{nrows}{ number of lines to rows to import using \code{read.table} from the input file to create the proper table definition. Default is 50. } \item{sep}{field separator character.} \item{eol}{end-of-line separator.} \item{skip}{number of lines to skip before reading data in the input file.} \item{quote}{the quote character used in the input file (defaults to \".} \item{allow.keywords}{ logical indicating whether column names that happen to be MySQL keywords be used as column names in the resulting relation (table) being written. Defaults to \code{FALSE}, forcing \code{mysqlWriteTable} to modify column names to make them legal MySQL identifiers. } \item{strings}{a character vector of strings to be escaped} \item{\dots}{ placeholder for future use. } } \value{ \code{mysqlInitDriver} returns an \code{MySQLDriver} object. \code{mysqlDriverInfo} returns a list of name-value metadata pairs. \code{mysqlDescribeDriver} returns \code{NULL} (displays the object's metadata). \code{mysqlCloseDriver} returns a logical indicating whether the operation succeeded or not. \code{mysqlNewConnection} returns an \code{MySQLConnection} object. \code{mysqlCloneConnection} returns an \code{MySQLConnection} object. \code{mysqlConnectionInfo}returns a list of name-value metadata pairs. \code{mysqlDescribeConnection} returns \code{NULL} (displays the object's metadata). \code{mysqlCloseConnection} returns a logical indicating whether the operation succeeded or not. \code{mysqlExecStatement} returns an \code{MySQLResult} object. \code{mysqlFetch} returns a data.frame. \code{mysqlQuickSQL} returns either a data.frame if the \code{statement} is a \code{select}-like or NULL otherwise. \code{mysqlDescribeResult} returns \code{NULL} (displays the object's metadata). \code{mysqlCloseResult} returns a logical indicating whether the operation succeeded or not. \code{mysqlDescribeFields} returns a data.frame with one row per field with columns \code{name}, \code{Sclass}, \code{type}, \code{len}, \code{precision}, \code{scale}, and \code{nullOK} which fully describe each field in a result set. Except for \code{Sclass} (which shows the mapping of the field type into an R/S-Plus class) all the information pertains to MySQL's data storage attributes. \code{mysqlReadTable} returns a data.frame with the contents of the DBMS table. \code{mysqlWriteTable} returns a logical indicating whether the operation succeeded or not. \code{mysqlDataType} retuns a character string with the closest \code{mysqlResultInfo} returns a list of name-value metadata pairs. \code{mysqlEscapeStrings} returns a character vector with each string escaped for MySQL special characters (such as single and double quotes). This is done using the character set used by the connection \code{con}. } \section{Constants}{ \code{.MySQLPkgName} (currently \code{"RMySQL"}), \code{.MySQLPkgVersion} (the R package version), \code{.MySQLPkgRCS} (the RCS revision), \code{.MySQL.NA.string} (character that MySQL uses to denote \code{NULL} on input), \code{.MySQLSQLKeywords} (a lot!) \code{.conflicts.OK}. %\non_function{} } \keyword{datasets} \keyword{interface} \keyword{database} %\keyword{internal} % vim:syntax=tex RMySQL/man/isIdCurrent.Rd0000644000175100001440000000202311703617102014647 0ustar hornikusers% $Id$ \name{isIdCurrent} \alias{isIdCurrent} \title{ Check whether a database handle object is valid or not } \description{ Support function that verifies that an object holding a reference to a foreign object is still valid for communicating with the RDBMS } \usage{ isIdCurrent(obj) } \arguments{ \item{obj}{ any \code{dbObject} (e.g., \code{dbDriver}, \code{dbConnection}, \code{dbResult}). } } \value{ a logical scalar. } \details{ \code{dbObjects} are R/S-Plus remote references to foreign objects. This introduces differences to the object's semantics such as persistence (e.g., connections may be closed unexpectedly), thus this function provides a minimal verification to ensure that the foreign object being referenced can be contacted. } \seealso{ \code{\link[DBI]{dbDriver}} \code{\link[DBI]{dbConnect}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{fetch}} } \examples{\dontrun{ cursor <- dbSendQuery(con, sql.statement) isIdCurrent(cursor) } } \keyword{interface} \keyword{database} % docclass is function % vim: syntax=tex RMySQL/man/dbNextResult.Rd0000644000175100001440000000354411703617102015050 0ustar hornikusers% $Id$ \name{dbNextResult} \alias{dbNextResult} \alias{dbMoreResults} \title{Fetch next result set from an SQL script or stored procedure (experimental)} \description{ Fetches the next result set from the output of a multi-statement SQL script or stored procedure; checkes whether there are additonal result sets to process. } \usage{ dbNextResult(con, ...) dbMoreResults(con, ...) } \arguments{ \item{con}{a connection object (see \code{\link[DBI]{dbConnect}}).} \item{...}{any additional arguments to be passed to the dispatched method} } \details{ SQL scripts (i.e., multiple SQL statements separated by ';') and stored procedures oftentimes generate multiple result sets. These DBI generic functions provide a means to process them sequentially. \code{dbNextResult} fetches the next result from the sequence of pending results sets; \code{dbMoreResults} returns a logical to indicate whether there are additional results to process. } \value{ \code{dbNextResult} returns a result set or \code{NULL}. \code{dbMoreResults} returns a logical specifying whether or not there are additional result sets to process in the connection. } \section{Note}{ Currently only the \code{\link{MySQL}} driver implements these methods. See 'methods?dbNextMethod'. } \seealso{ \code{\link{MySQL}} \code{\link[DBI]{dbConnect}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{fetch}} } \examples{\dontrun{ rs1 <- dbSendQuery(con, paste( "select Agent, ip\_addr, DATA from pseudo\_data order by Agent", "select * from Agent\_name", sep = ";") ) x1 <- fetch(rs1, n = -1) if(dbMoreResults(con)){ rs2 <- dbNextResult(con) x2 <- fetch(rs2, n = -1) } } } \keyword{programming}% at least one, from doc/KEYWORDS \keyword{interface}% __ONLY ONE__ keyword per line \keyword{database} % vim: syntax=tex RMySQL/man/MySQL.Rd0000644000175100001440000001225011703617102013364 0ustar hornikusers% $Id$ \name{MySQL} \alias{MySQL} \title{ Instantiate a MySQL client from the current R session } \description{ This function creates and initializes a MySQL client. It returns an driver object that allows you to connect to one or several MySQL servers. } \usage{ MySQL(max.con = 16, fetch.default.rec = 500, force.reload = FALSE) } \arguments{ \item{max.con }{ maximum number of connections that are intended to have open at one time. There's no intrinic limit, since strictly speaking this limit applies to MySQL \emph{servers}, but clients can have (at least in theory) more than this. Typically there are at most a handful of open connections, thus the internal \code{RMySQL} code uses a very simple linear search algorithm to manage its connection table. } \item{fetch.default.rec}{ number of records to fetch at one time from the database. (The \code{\link[DBI]{fetch}} method uses this number as a default.) } \item{force.reload}{ should the client code be reloaded (reinitialize)? Setting this to \code{TRUE} allows you to change default settings. Notice that all connections should be closed before re-loading. } } \value{ An object \code{MySQLDriver} that extends \code{dbDriver} and \code{dbObjectId}. This object is required to create connections to one or several MySQL database engines. } \section{Side Effects}{ The R client part of the database communication is initialized, but note that connecting to the database engine needs to be done through calls to \code{\link[DBI]{dbConnect}}. } \details{ This object is a singleton, that is, on subsequent invocations it returns the same initialized object. This implementation allows you to connect to multiple host servers and run multiple connections on each server simultaneously. } \section{User authentication}{ The preferred method to pass authentication parameters to the server (e.g., user, password, host) is through the MySQL personal configuration file \file{\$HOME/.my.cnf} (or \file{c:/my.cnf} under Windows). Since specifying passwords on calls to \code{dbConnect} is a very bad idea (and so is specifying passwords through shell variables), the client code parses the configuration file \file{\$HOME/.my.cnf}; this file consists of zero or more sections, each starting with a line of the form \code{[section-name]}, for instance \$ cat \$HOME/.my.cnf\cr \# this is a comment\cr [client]\cr user = dj\cr host = localhost\cr \cr [rs-dbi]\cr database = s-data\cr \cr [lasers]\cr user = opto\cr database = opto\cr password = pure-light\cr host = merced\cr ...\cr [iptraffic]\cr host = data\cr database = iptraffic\cr \cr This file should be readeable only by you. Inside each section, MySQL parameters may be specified one per line (e.g., \code{user = opto}). MySQL always considers default options from the \code{[client]} group for connecting to a server. To override or add additional options, R MySQL combines default options from the \code{[rs-dbi]} group, but you may specifiy you own group in the \code{dbConnect} call to tailor your environment. Note that to override options, you must place your group after the \code{[client]} group in configuration file. For instance, if you define a group, say, \code{[iptraffic]}, then instead of including all these parameters in the call to \code{dbConnect}, you simply supply the name of the \code{group}, e.g., \code{dbConnect(mgr, group = "iptraffic")}. The most important parameters are \code{user}, \code{password}, \code{host}, and \code{dbname}. } \note{ Use the option \code{database} in place of\code{dbname} in configuration files. } \author{David A. James} \section{References}{ See \url{stat.bell-labs.com/RS-DBI} for more details on the R/S-Plus database interface. See the documentation at the MySQL Web site \url{http://www.mysql.com} for details. } \seealso{ On database managers: \code{\link[DBI]{dbDriver}} \code{\link[DBI]{dbUnloadDriver}} On connections, SQL statements and resultSets: \code{\link[DBI]{dbConnect}} \code{\link[DBI]{dbDisconnect}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{dbGetQuery}} \code{\link[DBI]{fetch}} \code{\link[DBI]{dbClearResult}} On transaction management: \code{\link[DBI]{dbCommit}} \code{\link[DBI]{dbRollback}} On meta-data: \code{\link{summary}} \code{\link[DBI]{dbGetInfo}} \code{\link[DBI]{dbGetDBIVersion}} \code{\link[DBI]{dbListTables}} \code{\link[DBI]{dbListConnections}} \code{\link[DBI]{dbListResults}} \code{\link[DBI]{dbColumnInfo}} \code{\link[DBI]{dbGetException}} \code{\link[DBI]{dbGetStatement}} \code{\link[DBI]{dbHasCompleted}} \code{\link[DBI]{dbGetRowCount}} } \examples{\dontrun{ # create a MySQL instance and create one connection. > m <- dbDriver("MySQL") # open the connection using user, passsword, etc., as # specified in the "[iptraffic]" section of the # configuration file \file{\$HOME/.my.cnf} > con <- dbConnect(m, group = "iptraffic") > rs <- dbSendQuery(con, "select * from HTTP_ACCESS where IP_ADDRESS = '127.0.0.1'") > df <- fetch(rs, n = 50) > dbHasCompleted(rs) [1] FALSE > df2 <- fetch(rs, n = -1) > dbHasCompleted(rs) [1] TRUE > dbClearResult(rs) > dim(dbGetQuery(con, "show tables")) [1] 74 1 > dbListTables(con) } } \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbConnect-methods.Rd0000644000175100001440000000602511703617102015762 0ustar hornikusers% $Id$ \name{dbConnect-methods} \docType{methods} \alias{dbDisconnect-methods} \alias{dbConnect-methods} \alias{dbDisconnect,MySQLConnection-method} \alias{dbConnect,MySQLDriver-method} \alias{dbConnect,MySQLConnection-method} \alias{dbConnect,character-method} \title{ Create a connection object to an MySQL DBMS } \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{drv}{ an object of class \code{MySQLDriver}, or the character string "MySQL" or an \code{MySQLConnection}. } \item{conn}{ an \code{MySQLConnection} object as produced by \code{dbConnect}. } \item{username}{string of the MySQL login name or NULL. If NULL or the empty string \code{""}, the current user is assumed.} \item{password}{string with the MySQL password or NULL. If NULL, only entries in the user table for the users that have a blank (empty) password field are checked for a match.} \item{dbname}{string with the database name or NULL. If NOT NULL, the connection sets the default database to this value.} \item{host}{string identifying the host machine running the MySQL server or NULL. If NULL or the string \code{"localhost"}, a connection to the local host is assumed.} \item{unix.socket}{(optional) string of the unix socket or named pipe.} \item{port}{(optional) integer of the TCP/IP default port.} \item{client.flag}{(optional) integer setting various MySQL client flags. See the MySQL manual for details.} \item{group}{string identifying a section in the \code{default.file} to use for setting authentication parameters (see \code{\link{MySQL}}.)} \item{default.file}{string of the filename with MySQL client options. Defaults to \code{\$HOME/.my.cnf}} \item{\dots }{Currently unused.} } } \section{Side Effects}{ A connection between R/S-Plus and an MySQL server is established. The current implementation supports up to 100 simultaneous connections. } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ # create an MySQL instance and create one connection. drv <- dbDriver("MySQL") # open the connection using user, passsword, etc., as con <- dbConnect(drv, group = "rs-dbi") # Run an SQL statement by creating first a resultSet object rs <- dbSendQuery(con, statement = paste( "SELECT w.laser_id, w.wavelength, p.cut_off", "FROM WL w, PURGE P", "WHERE w.laser_id = p.laser_id", "SORT BY w.laser_id") # we now fetch records from the resultSet into a data.frame data <- fetch(rs, n = -1) # extract all rows dim(data) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/MySQLObject-class.Rd0000644000175100001440000000275711703617102015631 0ustar hornikusers% $Id$ \name{MySQLObject-class} \docType{class} \alias{MySQLObject-class} \title{Class MySQLObject} \description{ Base class for all MySQL-specific DBI classes } \section{Objects from the Class}{ A virtual Class: No objects may be created from it. } \section{Extends}{ Class \code{"DBIObject"}, directly. Class \code{"dbObjectId"}, directly. } \section{Methods}{ \describe{ \item{\link{coerce}}{\code{signature(from = "MySQLObject", to = "MySQLriver")}: ... } \item{\link[DBI]{dbDataType}}{\code{signature(dbObj = "MySQLObject")}: ... } \item{\link[DBI]{isSQLKeyword}}{\code{signature(dbObj = "MySQLObject", name = "character")}: ... } \item{\link[DBI]{make.db.names}}{\code{signature(dbObj = "MySQLObject", snames = "character")}: ... } \item{\link[DBI]{SQLKeywords}}{\code{signature(dbObj = "MySQLObject")}: ... } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://developer.r-project.org/db}. } \seealso{ DBI base classes: \code{\link[DBI]{DBIObject-class}} \code{\link[DBI]{DBIDriver-class}} \code{\link[DBI]{DBIConnection-class}} \code{\link[DBI]{DBIResult-class}} MySQL classes: \code{\link{MySQLObject-class}} \code{\link{MySQLDriver-class}} \code{\link{MySQLConnection-class}} \code{\link{MySQLResult-class}} } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, dbname = "rsdbi.db") } } \keyword{database} \keyword{interface} \keyword{classes} % vim: syntax=tex RMySQL/man/safe.write.Rd0000644000175100001440000000205511703617102014470 0ustar hornikusers% $Id$ \name{safe.write} \alias{safe.write} \title{Write a data.frame avoiding exceeding memory limits} \description{ This function batches calls to \code{write.table} to avoid exceeding memory limits for very large data.frames. } \usage{ safe.write(value, file, batch, ...) } \arguments{ \item{value}{a data.frame;} \item{file}{a file object (connection, file name, etc).} \item{batch}{maximum number of rows to write at a time.} \item{\dots}{any other arguments are passed to \code{write.table}.} } \details{ The function has a while loop invoking \code{\link{write.table}} for subsets of \code{batch} rows of \code{value}. Since this is a helper function for \code{\link[RMySQL]{mysqlWriteTable}}, it has hardcoded other arguments to \code{write.table}. } \value{ \code{NULL}, invisibly. } \note{No error checking whatsoever is done.} \seealso{\code{\link{write.table}}} \examples{\dontrun{ ctr.file <- file("dump.sqloader", "w") safe.write(big.data, file = ctr.file, batch = 25000) } } \keyword{internal} %% vim: syntax=tex RMySQL/man/fetch-methods.Rd0000644000175100001440000000407011703617102015152 0ustar hornikusers% $Id$ \name{fetch-methods} \docType{methods} \alias{fetch-methods} \alias{fetch,MySQLResult,numeric-method} \alias{fetch,MySQLResult,missing-method} %\alias{fetch,MySQLResult-method} \title{ Fetch records from a previously executed query } \description{ This method is a straight-forward implementation of the corresponding generic function. } \section{Methods}{\describe{ \item{res}{ an \code{MySQLResult} object. } \item{n}{ maximum number of records to retrieve per fetch. Use \code{n = -1} to retrieve all pending records; use a value of \code{n = 0} for fetching the default number of rows \code{fetch.default.rec} defined in the \code{\link{MySQL}} initialization invocation. } \item{\dots }{currently not used.} } } \details{ The \code{RMySQL} implementations retrieves only \code{n} records, and if \code{n} is missing it only returns up to \code{fetch.default.rec} as specified in the call to \code{\link{MySQL}} (500 by default). } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{dbClearResult}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, user = "opto", password="pure-light", host = "localhost", dbname="lasers") res <- dbSendQuery(con, statement = paste( "SELECT w.laser_id, w.wavelength, p.cut_off", "FROM WL w, PURGE P", "WHERE w.laser_id = p.laser_id", "ORDER BY w.laser_id")) # we now fetch the first 100 records from the resultSet into a data.frame data1 <- fetch(res, n = 100) dim(data1) dbHasCompleted(res) # let's get all remaining records data2 <- fetch(res, n = -1) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/make.db.names-methods.Rd0000644000175100001440000000530011703617102016461 0ustar hornikusers% $Id$ \name{make.db.names-methods} \docType{methods} \alias{SQLKeywords-methods} \alias{isSQLKeyword-methods} \alias{make.db.names,MySQLObject,character-method} \alias{SQLKeywords,MySQLObject-method} \alias{SQLKeywords,missing-method} \alias{isSQLKeyword,MySQLObject,character-method} \title{ Make R/S-Plus identifiers into legal SQL identifiers } \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{dbObj}{ any MySQL object (e.g., \code{MySQLDriver}). } \item{snames}{ a character vector of R/S-Plus identifiers (symbols) from which we need to make SQL identifiers. } \item{name}{ a character vector of SQL identifiers we want to check against keywords from the DBMS. } \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{keywords}{ a character vector with SQL keywords, by default it is \code{.MySQLKeywords} define in \code{RMySQL}. This may be overriden by users. } \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}. } \item{\dots}{currently not used.} } } \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. MySQL does add some keywords to the SQL 92 standard, they are listed in the \code{.MySQLKeywords} object. See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbReadTable}}, \code{\link[DBI]{dbWriteTable}}, \code{\link[DBI]{dbExistsTable}}, \code{\link[DBI]{dbRemoveTable}}, \code{\link[DBI]{dbListTables}}. } \examples{\dontrun{ # This example shows how we could export a bunch of data.frames # into tables on a remote database. con <- dbConnect("MySQL", "user", "password") export <- c("trantime.email", "trantime.print", "round.trip.time.email") tabs <- make.db.names(export, unique = T, allow.keywords = T) for(i in seq(along = export) ) dbWriteTable(con, name = tabs[i], get(export[i])) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbDataType-methods.Rd0000644000175100001440000000202511703617102016100 0ustar hornikusers% $Id$ \name{dbDataType-methods} \docType{methods} \alias{dbDataType-methods} \alias{dbDataType,MySQLObject-method} \title{ Determine the SQL Data Type of an S object } \description{ This method is a straight-forward implementation of the corresponding generic function. } \arguments{ \item{dbObj}{ any \code{MySQLObject} object, e.g., \code{MySQLDriver}, \code{MySQLConnection}, \code{MySQLResult}. } \item{obj}{ R/S-Plus object whose SQL type we want to determine. } \item{\dots }{ any other parameters that individual methods may need. } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link[DBI]{isSQLKeyword}} \code{\link[DBI]{make.db.names}} } \examples{\dontrun{ data(quakes) drv <- dbDriver("MySQL") sql.type <- dbDataType(drv, quakes) } } \keyword{methods} \keyword{interface} \keyword{database} % docclass is function % Converted by Sd2Rd version 1.15.2.1. % vim: syntax=tex RMySQL/man/dbEscapeStrings-methods.Rd0000644000175100001440000000302211703617102017135 0ustar hornikusers\name{dbEscapeStrings-methods} \docType{methods} \alias{dbEscapeStrings-methods} \alias{dbEscapeStrings,MySQLConnection,character-method} \alias{dbEscapeStrings,MySQLResult,character-method} \title{Escape a Character Vector According to SQL rules} \description{ Escape SQL-special characters in a character vector according to MySQL rules. } \section{Methods}{ \describe{ \item{con = "MySQLConnection", strings = "character"}{ This method encodes the \code{strings} character vector according to the MySQL escape rules and taking into consideration the character set used by the connection (each MySQL connection may be set to use different character sets). Note that the \code{RMySQL} package currently does not deal with character set conversions -- it uses whatever character encoding the R session is using, but the MySQL runtime library handles this transparently. } \item{...}{currently unused.} }} \keyword{methods} \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link{dbNextResult}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ con <- dbConnect(MySQL(), dbname = "rs-dbi", client.flag=CLIENT\_MULTI\_STATEMENTS) tmp <- sprintf("select * from emp where lname = %s", "O'Reilly") sql <- dbEscapeString(con, tmp) dbGetQuery(con, sql) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbReadTable-methods.Rd0000644000175100001440000001342311703617102016214 0ustar hornikusers% $Id$ \name{dbReadTable-methods} \docType{methods} \alias{dbReadTable-methods} \alias{dbWriteTable-methods} \alias{dbExistsTable-methods} \alias{dbRemoveTable-methods} \alias{dbReadTable,MySQLConnection,character-method} \alias{dbWriteTable,MySQLConnection,character,character-method} \alias{dbWriteTable,MySQLConnection,character,data.frame-method} \alias{dbExistsTable,MySQLConnection,character-method} \alias{dbRemoveTable,MySQLConnection,character-method} \title{ Convenience functions for Importing/Exporting DBMS tables } \description{ These functions mimic their R/S-Plus counterpart \code{get}, \code{assign}, \code{exists}, \code{remove}, and \code{objects}, except that they generate code that gets remotely executed in a database engine. } \section{Methods}{\describe{ \item{conn}{ an \code{MySQLConnection} database connection object. } \item{name}{ a character string specifying a table name. } \item{value}{ a data.frame (or coercible to data.frame). } \item{row.names}{ in the case of \code{dbReadTable}, this argument can be a string or an index specifying the column in the DBMS table to be used as \code{row.names} in the output data.frame (a \code{NULL}, \code{""}, or 0 specifies that no column should be used as \code{row.names} in the output). In the case of \code{dbWriteTable}, this argument should be a logical specifying whether the \code{row.names} should be output to the output DBMS table; if \code{TRUE}, an extra field whose name will be whatever the R/S-Plus identifier \code{"row.names"} maps to the DBMS (see \code{\link[DBI]{make.db.names}}). } \item{overwrite}{ a logical specifying whether to overwrite an existing table or not. Its default is \code{FALSE}. } \item{append}{ a logical specifying whether to append to an existing table in the DBMS. Its default is \code{FALSE}. } \item{allow.keywords}{ \code{dbWriteTable} accepts a logical \code{allow.keywords} to allow or prevent MySQL reserved identifiers to be used as column names. By default it is \code{FALSE}. } \item{dots}{ optional arguments. When \code{dbWriteTable} is used to import data from a file, you may optionally specify \code{header=}, \code{row.names=}, \code{col.names=}, \code{sep=}, \code{eol=}, \code{field.types=}, \code{skip=}, and \code{quote=}. \code{header} is a logical indicating whether the first data line (but see \code{skip}) has a header or not. If missing, it value is determined following \code{\link{read.table}} convention, namely, it is set to TRUE if and only if the first row has one fewer field that the number of columns. \code{row.names} is a logical to specify whether the first column is a set of row names. If missing its default follows the \code{\link{read.table}} convention. \code{col.names} a character vector with column names (these names will be filtered with \code{\link[DBI]{make.db.names}} to ensure valid SQL identifiers. (See also \code{field.types} below.) \code{sep=} specifies the field separator, and its default is \code{','}. \code{eol=} specifies the end-of-line delimiter, and its default is \code{'\n'}. \code{skip} specifies number of lines to skip before reading the data, and it defaults to 0. \code{field.types} is a list of named field SQL types where \code{names(field.types)} provide the new table's column names (if missing, field types are inferred using \code{\link[DBI]{dbDataType}}). } } } \value{ A \code{data.frame} in the case of \code{dbReadTable}; otherwise a logical indicating whether the operation was successful. } \note{ Note that data.frames are only approximately analogous to tables (relations) in relational DBMS, and thus you should not expect complete agreement in their semantics. Tables in RDBMS are best thought of as \emph{relations} with a number of constraints imposed by the relational database model, and data.frames, with their roots in statistical modeling, as self-contained "sequence of observations on some chosen variables" (Chambers and Hastie (1992), p.46). In particular the \code{data.frame} returned by \code{dbReadTable} only has primitive data, e.g., it does not coerce character data to factors. Also, column names in a data.frame are \emph{not} guaranteed to be equal to the column names in a MySQL exported/imported table (e.g., by default MySQL reserved identifiers may not be used as column names --- and with 218 keywords like \code{"BEFORE"}, \code{"DESC"}, and \code{"FROM"} the likelihood of name conflicts is not small.) Use \code{isSQLKeyword(con, names(value))} to check whether the data.frame names in \code{value} coincide with MySQL reserver words. MySQL table names are \emph{not} case sensitive, e.g., table names \code{ABC} and \code{abc} are considered equal. } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link{mysqlImportFile}}, \code{\link[DBI]{isSQLKeyword}}, \code{\link[DBI]{dbDriver}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbListTables}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ conn <- dbConnect("MySQL", group = "wireless") if(dbExistsTable(con, "fuel_frame")){ dbRemoveTable(conn, "fuel_frame") dbWriteTable(conn, "fuel_frame", fuel.frame) } if(dbExistsTable(conn, "RESULTS")){ dbWriteTable(conn, "RESULTS", results2000, append = T) else dbWriteTable(conn, "RESULTS", results2000) } } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbCallProc-methods.Rd0000644000175100001440000000155011703617102016066 0ustar hornikusers% $Id$ \name{dbCallProc-methods} \docType{methods} \alias{dbCallProc-methods} \alias{dbCallProc,MySQLConnection-method} \title{ Call an SQL stored procedure } \description{ Not yet implemented. } \section{Methods}{\describe{ \item{conn}{ a \code{MySQLConnection} object. } \item{\dots }{ additional arguments are passed to the implementing method. } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/RMySQL-package.Rd0000644000175100001440000001561411703617102015106 0ustar hornikusers\name{RMySQL-package} \alias{RMySQL-package} \alias{RMySQL} \docType{package} \title{ R interface to the MySQL database } \description{ The functions in this package allow you interact with one or more MySQL databases from R. } \section{Overview}{ A typical usage of the R-MySQL interface is: \enumerate{ \item Connect and authenticate to one or more MySQL databases: \preformatted{ con <- dbConnect(MySQL(), group = "lasers") con2 <- dbConnect(MySQL(), user="opto", password="pure-light", dbname="lasers", host="merced") } \item List tables and fields in a table: \preformatted{ dbListTables(con) dbListFields(con, "table\_name") } \item Import and export data.frames: \preformatted{ d <- dbReadTable(con, "WL") dbWriteTable(con, "WL2", a.data.frame) ## table from a data.frame dbWriteTable(con, "test2", "~/data/test2.csv") ## table from a file } \item Run an arbitrary SQL statement and extract all its output (returns a data.frame): \preformatted{ dbGetQuery(con, "select count(*) from a\_table") dbGetQuery(con, "select * from a\_table") } \item Run an SQL statement and extract its output in pieces (returns a result set): \preformatted{ rs <- dbSendQuery(con, "select * from WL where width\_nm between 0.5 and 1") d1 <- fetch(rs, n = 10000) d2 <- fetch(rs, n = -1 } \item Run multiple SQL statements and process the various result sets (note the \code{client.flag} value in the \code{dbConnect} call): \preformatted{ con <- dbConnection(MySQL(), dbname = "rs-dbi", client.flag = CLIENT\_MULTI\_STATEMENTS) script <- paste("select * from WL where width\_nm between 0.5 and 1" "select * from lasers\_id where id LIKE 'AL100%' sep = ";") rs1 <- dbSendQuery(con, script) d1 <- fetch(rs1, n = -1) if(dbMoreResults(con)){ rs2 <- dbNextResult(con) d2 <- fetch(rs2, n=-1) } } \item Get meta-information on a connection (thread-id, etc.): \preformatted{ summary(MySQL(), verbose = TRUE) summary(con, verbose = TRUE) summary(rs, verbose = TRUE) dbListConnections(MySQL()) dbListResultSets(con) dbHasCompleted(rs) } \item Close connections: \preformatted{ dbDisconnect(con) dbDisconnect(con2) } } } \section{Data mappings between MySQL and R}{ MySQL tables are read into R as data.frames, but without coercing character or logical data into factors. Similarly while exporting data.frames, factors are exported as character vectors. Integer columns are usually imported as R integer vectors, except for cases such as \code{BIGINT} or \code{UNSIGNED INTEGER} which are coerced to R's \code{double} precision vectors to avoid truncation (currently R's integers are signed 32-bit quantities). Time variables are imported/exported as character data, so you need to convert these to your favorite date/time representation. Currently there are no facilities to import/export \code{BLOBs}. } \section{RDBMS tables, data.frames, and data types}{ Tables in a relational database are only superficially similar to R's data.frames (e.g., tables as unordered sets of rows compared to data.frames as ordered sets, tables having referential constraints, indexes, and so on.) } \section{User authentication}{ Although you can specify user authentication parameters (user, password, database, and host) in the call to \code{dbConnect}, the preferred method to pass these parameters to the server is through a MySQL \code{default.file}, e.g., \file{\$HOME/.my.cnf} (or \file{c:/my.cnf} under Windows). The MySQL \code{dbConnect} method parses the \code{default.file=\$HOME/.my.cnf} to initialize connections to MySQL databases. This file consists of zero or more named sections each starting with a line of the form \code{[section-name]}; each section includes zero or more MySQL variable declaration per line, such as, \code{user=}, \code{password=}, \code{host=}, etc. For instance, \preformatted{ $ cat $HOME/.my.cnf # this is a comment ; this is also a comment [client] user = dj host = localhost [rs-dbi] database = s-data [lasers] user = opto database = opto password = pure-light host = merced ... [iptraffic] host = data database = iptraffic } This file should be readable only by you. \code{RMySQL} always initializes connection values from the \code{[client]} and \code{[rs-dbi]} sections, but you may define you own project-specific sections (as in the example above) to tailor its environment; if the same parameter appears in multiple sections (e.g., in \code{client} and \code{rs-dbi}), the last (closer to the bottom) occurrence is used. If you define a section, for instance, \code{[iptraffic]}, then instead of including all these parameters in the call to \code{dbConnect}, you simply supply the name of the \code{group}, e.g., \code{dbConnect(MySQL(), group = "iptraffic")}. In addition to \code{user}, \code{password}, \code{host}, and \code{dbname}, you may specify any other connection parameters, e.g., \code{port}, \code{socket}. See the MySQL documentation for details. Lastly, you may specify an alternate \code{default.file}, e.g., \code{dbConnect(MySQL(), group="iptraffic", default.file="router\_shield")}. } \author{ David A. James Saikat DebRoy } \section{References}{ See \url{stat.bell-labs.com/RS-DBI} for more details on the R/S-Plus database interface. See the documentation at the MySQL Web site \url{http://www.mysql.com} for details. } \seealso{ On database managers: \code{\link[DBI]{dbDriver}} \code{\link[DBI]{dbUnloadDriver}} On connections, SQL statements and resultSets: \code{\link[DBI]{dbConnect}} \code{\link[DBI]{dbDisconnect}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{dbGetQuery}} \code{\link[DBI]{fetch}} \code{\link[DBI]{dbClearResult}} On transaction management: \code{\link[DBI]{dbCommit}} \code{\link[DBI]{dbRollback}} On meta-data: \code{\link{summary}} \code{\link[DBI]{dbGetInfo}} \code{\link[DBI]{dbGetDBIVersion}} \code{\link[DBI]{dbListTables}} \code{\link[DBI]{dbListConnections}} \code{\link[DBI]{dbListResults}} \code{\link[DBI]{dbColumnInfo}} \code{\link[DBI]{dbGetException}} \code{\link[DBI]{dbGetStatement}} \code{\link[DBI]{dbHasCompleted}} \code{\link[DBI]{dbGetRowCount}} } \examples{\dontrun{ # create a MySQL instance and create one connection. > m <- dbDriver("MySQL") ## or MySQL() # open the connection using user, passsword, etc., as # specified in the "[iptraffic]" section of the # configuration file \file{\$HOME/.my.cnf} > con <- dbConnect(m, group = "iptraffic") > rs <- dbSendQuery(con, "select * from HTTP_ACCESS where IP_ADDRESS = '127.0.0.1'") > df <- fetch(rs, n = 50) > dbHasCompleted(rs) [1] FALSE > df2 <- fetch(rs, n = -1) > dbHasCompleted(rs) [1] TRUE > dbClearResult(rs) > dim(dbGetQuery(con, "show tables")) [1] 74 1 > dbListTables(con) } } \keyword{package} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbDriver-methods.Rd0000644000175100001440000000365511703617102015632 0ustar hornikusers% $Id$ \name{dbDriver-methods} \docType{methods} \alias{dbDriver-methods} \alias{dbUnloadDriver-methods} \alias{dbDriver,character-method} \alias{dbUnloadDriver,MySQLDriver-method} \title{ MySQL implementation of the Database Interface (DBI) classes and drivers } \description{ MySQL driver initialization and closing } \section{Methods}{\describe{ \item{drvName}{ character name of the driver to instantiate. } \item{drv}{ an object that inherits from \code{MySQLDriver} as created by \code{dbDriver}. } \item{max.con}{optional integer requesting the maximum number of simultanous connections (may be up to 100)}. \item{fetch.default.rec}{default number of records to retrieve per fetch. Default is 500. This may be overridden in calls to \code{\link[DBI]{fetch}} with the \code{n=} argument.} \item{force.reload}{optional logical used to force re-loading or recomputing the size of the connection table. Default is \code{FALSE}.} \item{...}{currently unused.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbListTables}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ # create an MySQL instance and set 10000 of rows per fetch. m <- dbDriver("MySQL", fetch.default.records=10000) con <- dbConnect(m, username="usr", password = "pwd", dbname = "iptraffic") rs <- dbSubmitQuery(con, "select * from HTTP_ACCESS where IP_ADDRESS = '127.0.0.1'") df <- fetch(rs, n = 50) df2 <- fetch(rs, n = -1) dbClearResult(rs) pcon <- dbConnect(p, group = "wireless") dbListTables(pcon) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/summary-methods.Rd0000644000175100001440000000245011703617102015556 0ustar hornikusers% $Id$ \name{summary-methods} \docType{methods} \alias{coerce-methods} \alias{summary-methods} \alias{format-methods} \alias{show-methods} \alias{coerce,dbObjectId,integer-method} \alias{coerce,dbObjectId,numeric-method} \alias{coerce,dbObjectId,character-method} \alias{coerce,MySQLObject,MySQLDriver-method} \alias{coerce,MySQLConnection,MySQLResult-method} \alias{coerce,MySQLConnection,MySQLDriver-method} \alias{coerce,MySQLResult,MySQLConnection-method} \alias{coerce,MySQLResult,MySQLDriver-method} \alias{format,dbObjectId-method} \alias{print,dbObjectId-method} \alias{show,dbObjectId-method} \alias{summary,MySQLObject-method} \alias{summary,MySQLDriver-method} \alias{summary,MySQLConnection-method} \alias{summary,MySQLResult-method} \title{Summarize an MySQL object} \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{object = "DBIObject"}{ Provides relevant metadata information on \code{object}, for instance, the MySQL server file, the SQL statement associated with a result set, etc. } \item{from}{object to be coerced} \item{to}{coercion class} \item{x}{object to \code{format} or \code{print} or \code{show}} } } \keyword{methods} \keyword{database} \keyword{interface} % vim: syntax=tex RMySQL/man/dbListTables-methods.Rd0000644000175100001440000000254211703617102016437 0ustar hornikusers% $Id$ \name{dbListTables-methods} \docType{methods} \alias{dbListTables-methods} \alias{dbListFields-methods} \alias{dbListConnections-methods} \alias{dbListResults-methods} \alias{dbListTables,MySQLConnection-method} \alias{dbListFields,MySQLConnection,character-method} \alias{dbListFields,MySQLResult,missing-method} \alias{dbListConnections,MySQLDriver-method} \alias{dbListResults,MySQLConnection-method} \title{ List items from an MySQL DBMS and from objects } \description{ These methods are straight-forward implementations of the corresponding generic functions. } \section{Methods}{\describe{ \item{drv}{an \code{MySQLDriver}.} \item{conn}{an \code{MySQLConnection}.} \item{name}{a character string with the table name.} \item{\dots}{currently not used.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbColumnInfo}}, \code{\link[DBI]{dbDriver}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}} } \examples{\dontrun{ drv <- dbDriver("MySQL") # after working awhile... for(con in dbListConnections(drv)){ dbGetStatement(dbListResults(con)) } } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/mysqlClientLibraryVersions.Rd0000644000175100001440000000076411703617102020010 0ustar hornikusers% $Id$ \name{mysqlClientLibraryVersions} \alias{mysqlClientLibraryVersions} \title{MySQL Check for Compiled Versus Loaded Client Library Versions} \description{ This function prints out the compiled and loaded client library versions. } \usage{ mysqlClientLibraryVersions() } \value{ A named integer vector of length two, the first element representing the compiled library version and the second element representint the loaded client library version. } \keyword{database} % vim: syntax=tex RMySQL/man/dbBuildTableDefinition.Rd0000644000175100001440000000275511703617102016756 0ustar hornikusers%% TODO: Should we move this to the DBI package? \name{dbBuildTableDefinition} \alias{dbBuildTableDefinition} \title{Build the SQL CREATE TABLE definition as a string} \description{ Build the SQL CREATE TABLE definition as a string for the input data.frame } \usage{ dbBuildTableDefinition(dbObj, name, obj, field.types = NULL, row.names = TRUE, ...) } \arguments{ \item{dbObj}{any DBI object (used only to dispatch according to the engine (e.g., MySQL, Oracle, PostgreSQL, SQLite) } \item{name}{name of the new SQL table} \item{obj}{an R object coerceable to data.frame for which we want to create a table} \item{field.types}{optional named list of the types for each field in \code{obj}} \item{row.names}{logical, should row.name of \code{value} be exported as a \code{row\_names} field? Default is TRUE} \item{\dots}{reserved for future use} } \details{ The output SQL statement is a simple \code{CREATE TABLE} with suitable for \code{dbGetQuery} } \value{ An SQL string } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \keyword{methods} \keyword{interface} \keyword{database} %% vim: syntax=tex RMySQL/man/MySQLDriver-class.Rd0000644000175100001440000000322411703617102015644 0ustar hornikusers% $Id$ \name{MySQLDriver-class} \docType{class} \alias{MySQLDriver-class} \title{Class MySQLDriver} \description{ An MySQL driver implementing the R/S-Plus database (DBI) API. } \section{Generators}{ The main generators are \code{\link[DBI]{dbDriver}} and \code{\link{MySQL}}. } \section{Extends}{ Class \code{"DBIDriver"}, directly. Class \code{"MySQLObject"}, directly. Class \code{"DBIObject"}, by class "DBIDriver". Class \code{"dbObjectId"}, by class "MySQLObject". } \section{Methods}{ \describe{ \item{\link{coerce}}{\code{signature(from = "MySQLObject", to = "MySQLDriver")}: ... } \item{\link[DBI]{dbConnect}}{\code{signature(drv = "MySQLDriver")}: ... } \item{\link[DBI]{dbGetInfo}}{\code{signature(dbObj = "MySQLDriver")}: ... } \item{\link[DBI]{dbListConnections}}{\code{signature(drv = "MySQLDriver")}: ... } \item{\link[DBI]{dbUnloadDriver}}{\code{signature(drv = "MySQLDriver")}: ... } \item{\link{summary}}{\code{signature(object = "MySQLDriver")}: ... } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://developer.r-project.org/db}. } \seealso{ DBI base classes: \code{\link[DBI]{DBIObject-class}} \code{\link[DBI]{DBIDriver-class}} \code{\link[DBI]{DBIConnection-class}} \code{\link[DBI]{DBIResult-class}} MySQL classes: \code{\link{MySQLObject-class}} \code{\link{MySQLDriver-class}} \code{\link{MySQLConnection-class}} \code{\link{MySQLResult-class}} } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, "user/password@dbname") } } \keyword{database} \keyword{interface} \keyword{classes} % vim: syntax=tex RMySQL/man/dbSetDataMappings-methods.Rd0000644000175100001440000000221511703617102017412 0ustar hornikusers% $Id$ \name{dbSetDataMappings-methods} \docType{methods} \alias{dbSetDataMappings-methods} \alias{dbSetDataMappings,MySQLResult,data.frame-method} \title{ Set data mappings between MySQL and R/S-Plus } \description{ Not yet implemented } \section{Methods}{\describe{ \item{res}{ a \code{MySQLResult} object as returned by \code{dbSendQuery}. } \item{flds}{ a data.frame with field descriptions as returned by \code{\link[DBI]{dbColumnInfo}}. } \item{\dots }{ any additional arguments are passed to the implementing method. } } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbColumnInfo}}. } \examples{\dontrun{ makeImage <- function(x) { .C("make_Image", as.integer(x), length(x)) } res <- dbSendQuery(con, statement) flds <- dbColumnInfo(res) flds[3, "Sclass"] <- makeImage dbSetDataMappings(rs, flds) im <- fetch(rs, n = -1) } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbCommit-methods.Rd0000644000175100001440000000237711703617102015627 0ustar hornikusers% $Id$ \name{dbCommit-methods} \docType{methods} \alias{dbCommit-methods} \alias{dbRollback-methods} \alias{dbCommit,MySQLConnection-method} \alias{dbRollback,MySQLConnection-method} \title{ DBMS Transaction Management } \description{ Commits or roll backs the current transaction in an MySQL connection } \section{Methods}{\describe{ \item{conn}{a \code{MySQLConnection} object, as produced by the function \code{dbConnect}.} \item{\dots }{currently unused.} } } \references{ See the Database Interface definition document \code{DBI.pdf} in the base directory of this package or \url{http://stat.bell-labs.com/RS-DBI}. } \seealso{ \code{\link{MySQL}}, \code{\link[DBI]{dbConnect}}, \code{\link[DBI]{dbSendQuery}}, \code{\link[DBI]{dbGetQuery}}, \code{\link[DBI]{fetch}}, \code{\link[DBI]{dbCommit}}, \code{\link[DBI]{dbGetInfo}}, \code{\link[DBI]{dbReadTable}}. } \examples{\dontrun{ drv <- dbDriver("MySQL") con <- dbConnect(drv, group = "group") rs <- dbSendQuery(con, "delete * from PURGE as p where p.wavelength<0.03") if(dbGetInfo(rs, what = "rowsAffected") > 250){ warning("dubious deletion -- rolling back transaction") dbRollback(con) } } } \keyword{methods} \keyword{interface} \keyword{database} % vim: syntax=tex RMySQL/man/dbApply.Rd0000644000175100001440000000305311703617102014013 0ustar hornikusers% $Id$ \name{dbApply} \alias{dbApply} \title{Apply R functions to remote groups of DBMS rows (experimental)} \description{ Applies R functions to groups of remote DBMS rows without bringing an entire result set all at once. The result set is expected to be sorted by the grouping field. } \usage{ dbApply(res, ...) } \arguments{ \item{res}{a result set (see \code{\link[DBI]{dbSendQuery}}).} \item{...}{any additional arguments to be passed to \code{FUN}.} } \details{ \code{dbApply} This generic is meant to handle somewhat gracefully(?) large amounts of data from the DBMS by bringing into R manageable chunks; the idea is that the data from individual groups can be handled by R, but not all the groups at the same time. Currently, only the \code{\link{MySQL}} driver implements a method (see the helper function \code{\link{mysqlDBApply}}) for this generic function. } \value{ A list with as many elements as there were groups in the result set. } \seealso{ \code{\link{MySQL}} \code{\link{mysqlDBApply}} \code{\link[DBI]{dbSendQuery}} \code{\link[DBI]{fetch}} } \examples{\dontrun{ ## compute quanitiles for each network agent con <- dbConnect(MySQL(), group="vitalAnalysis") rs <- dbSendQuery(con, "select Agent, ip_addr, DATA from pseudo_data order by Agent") out <- dbApply(rs, INDEX = "Agent", FUN = function(x, grp) quantile(x$DATA, names=FALSE)) } } \keyword{programming}% at least one, from doc/KEYWORDS \keyword{interface}% __ONLY ONE__ keyword per line \keyword{database} % vim: syntax=tex RMySQL/man/S4R.Rd0000644000175100001440000000074711703617102013037 0ustar hornikusers% $Id$ \name{S4R} \alias{ErrorClass} \alias{usingR} \title{R compatibility with S version 4/Splus5+ support functions} \description{ These objects ease the task of porting functions into R from S Version 4 and S-Plus 5.0 and later. See the documentation there. May be obsolete in the future. } \usage{ usingR(major, minor) } \examples{\dontrun{ rc <- try(fetch(res, n = -1)) if(inherit(rc, ErrorClass)) stop("could not fetch the data") } } \keyword{internal} % vim:syntax=tex RMySQL/configure.win0000644000175100001440000000102611703617102014054 0ustar hornikusersecho -n "checking for \$MYSQL_HOME... " if test -z "$MYSQL_HOME" ; then echo "not found... searching registry..." echo "" "${R_HOME}/bin${R_ARCH_BIN}/Rscript" inst/FindMySQLhome.R echo "" exit 1 else echo ${MYSQL_HOME} if test ! -d ${MYSQL_HOME}; then echo "MYSQL_HOME is set but does not point to a directory" exit 2 fi fi x86=`"${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e 'cat(.Machine$sizeof.pointer==4)'` if test $x86 = "TRUE"; then cp src/Makevars.win32 src/Makevars.win else cp src/Makevars.win64 src/Makevars.win fi RMySQL/src/0000755000175100001440000000000011705321752012151 5ustar hornikusersRMySQL/src/RS-MySQL.c0000644000175100001440000016136211705321752013615 0ustar hornikusers/* * $Id: RS-MySQL.c 360 2009-04-07 16:41:24Z j.horner $ * * * Copyright (C) 1999-2002 The Omega Project for Statistical Computing. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RS-MySQL.h" #include "R_ext/Rdynload.h" #ifndef USING_R # error("the function RS_DBI_invokeBeginGroup() has not been implemented in S") # error("the function RS_DBI_invokeEndGroup() has not been implemented in S") # error("the function RS_DBI_invokeNewRecord() has not been implemented in S") #endif /* R and S DataBase Interface to MySQL * * * C Function library which can be used to run SQL queries from * inside of S4, Splus5.x, or R. * This driver hooks R/S and MySQL and implements the proposed S-DBI * generic R/S-database interface 0.2. * * For details see * On S, Appendix A in "Programming with Data" by John M. Chambers. * On R, "The .Call and .External Interfaces" in the "Writing R Extensions" * manual. * On MySQL, The "MySQL Reference Manual" available at http://www.mysql.com * Also, "MySQL" Third Ed. by Paul Dubois (2005) New Riders Publishing. * * TODO: * 1. Make sure the code is thread-safe, in particular, * we need to remove the PROBLEM ... ERROR macros * in RS_DBI_errorMessage() because it's definetely not * thread-safe. But see RS_DBI_setException(). * 2. Apparently, MySQL treats TEXT as BLOB's (actually, it seems * that MySQL makes no clear distinction between BLOB's and * CLOB's). Need to resolve this once and for all. */ Mgr_Handle * RS_MySQL_init(s_object *config_params, s_object *reload) { S_EVALUATOR /* Currently we can specify the defaults for 2 parameters, max num of * connections, and max of records per fetch (this can be over-ridden * explicitly in the S call to fetch). */ Mgr_Handle *mgrHandle; Sint fetch_default_rec, force_reload, max_con; const char *drvName = "MySQL"; max_con = INT_EL(config_params,0); fetch_default_rec = INT_EL(config_params,1); force_reload = LGL_EL(reload,0); mgrHandle = RS_DBI_allocManager(drvName, max_con, fetch_default_rec, force_reload); return mgrHandle; } s_object * RS_MySQL_closeManager(Mgr_Handle *mgrHandle) { S_EVALUATOR RS_DBI_manager *mgr; s_object *status; mgr = RS_DBI_getManager(mgrHandle); if(mgr->num_con) RS_DBI_errorMessage( "there are opened connections -- close them first", RS_DBI_ERROR); RS_DBI_freeManager(mgrHandle); MEM_PROTECT(status = NEW_LOGICAL((Sint) 1)); LGL_EL(status,0) = TRUE; MEM_UNPROTECT(1); return status; } /* Are there more results on this connection (as in multi results or * SQL scripts */ s_object * /* boolean */ RS_MySQL_moreResultSets(Con_Handle *conHandle) { S_EVALUATOR RS_DBI_connection *con; MYSQL *my_connection; my_bool tmp; s_object *status; /* boolean */ con = RS_DBI_getConnection(conHandle); my_connection = (MYSQL *) con->drvConnection; tmp = mysql_more_results(my_connection); MEM_PROTECT(status = NEW_LOGICAL((Sint) 1)); if(tmp) LGL_EL(status, 0) = TRUE; else LGL_EL(status, 0) = FALSE; MEM_UNPROTECT(1); return status; } Res_Handle * RS_MySQL_nextResultSet(Con_Handle *conHandle) { S_EVALUATOR RS_DBI_connection *con; RS_DBI_resultSet *result; Res_Handle *rsHandle; MYSQL_RES *my_result; MYSQL *my_connection; Sint rc, num_fields, is_select; con = RS_DBI_getConnection(conHandle); my_connection = (MYSQL *) con->drvConnection; rc = (Sint) mysql_next_result(my_connection); if(rc<0){ RS_DBI_errorMessage("no more result sets", RS_DBI_ERROR); } else if(rc>0){ RS_DBI_errorMessage("error in getting next result set", RS_DBI_ERROR); } /* the following comes verbatim from RS_MySQL_exec() */ my_result = mysql_use_result(my_connection); if(!my_result) my_result = (MYSQL_RES *) NULL; num_fields = (Sint) mysql_field_count(my_connection); is_select = (Sint) TRUE; if(!my_result){ if(num_fields>0){ RS_DBI_errorMessage("error in getting next result set", RS_DBI_ERROR); } else is_select = FALSE; } /* we now create the wrapper and copy values */ rsHandle = RS_DBI_allocResultSet(conHandle); result = RS_DBI_getResultSet(rsHandle); result->statement = RS_DBI_copyString(""); result->drvResultSet = (void *) my_result; result->rowCount = (Sint) 0; result->isSelect = is_select; if(!is_select){ result->rowsAffected = (Sint) mysql_affected_rows(my_connection); result->completed = 1; } else { result->rowsAffected = (Sint) -1; result->completed = 0; } if(is_select) result->fields = RS_MySQL_createDataMappings(rsHandle); return rsHandle; } /* open a connection with the same parameters used for in conHandle */ Con_Handle * RS_MySQL_cloneConnection(Con_Handle *conHandle) { S_EVALUATOR return RS_MySQL_createConnection( RS_DBI_asMgrHandle(MGR_ID(conHandle)), RS_MySQL_cloneConParams(RS_DBI_getConnection(conHandle)->conParams)); } RS_MySQL_conParams * RS_MySQL_allocConParams(void) { RS_MySQL_conParams *conParams; conParams = (RS_MySQL_conParams *) malloc(sizeof(RS_MySQL_conParams)); if(!conParams){ RS_DBI_errorMessage("could not malloc space for connection params", RS_DBI_ERROR); } conParams->dbname = NULL; conParams->username = NULL; conParams->password = NULL; conParams->host = NULL; conParams->unix_socket = NULL; conParams->port = 0; conParams->client_flag = 0; conParams->groups = NULL; conParams->default_file = NULL; return conParams; } RS_MySQL_conParams * RS_MySQL_cloneConParams(RS_MySQL_conParams *cp) { RS_MySQL_conParams *new = RS_MySQL_allocConParams(); if (cp->dbname) new->dbname = RS_DBI_copyString(cp->dbname); if (cp->username) new->username = RS_DBI_copyString(cp->username); if (cp->password) new->password = RS_DBI_copyString(cp->password); if (cp->host) new->host = RS_DBI_copyString(cp->host); if (cp->unix_socket) new->unix_socket = RS_DBI_copyString(cp->unix_socket); new->port = cp->port; new->client_flag = cp->client_flag; if (cp->groups) new->groups = RS_DBI_copyString(cp->groups); if (cp->default_file) new->default_file = RS_DBI_copyString(cp->default_file); return new; } void RS_MySQL_freeConParams(RS_MySQL_conParams *conParams) { if(conParams->dbname) free(conParams->dbname); if(conParams->username) free(conParams->username); if(conParams->password) free(conParams->password); if(conParams->host) free(conParams->host); if(conParams->unix_socket) free(conParams->unix_socket); /* port and client_flag are unsigned ints */ if(conParams->groups) free(conParams->groups); if(conParams->default_file) free(conParams->default_file); free(conParams); return; } Con_Handle * RS_MySQL_newConnection(Mgr_Handle *mgrHandle, s_object *s_dbname, s_object *s_username, s_object *s_password, s_object *s_myhost, s_object *s_unix_socket, s_object *s_port, s_object *s_client_flag, s_object *s_groups, s_object *s_default_file) { S_EVALUATOR RS_MySQL_conParams *conParams; if(!is_validHandle(mgrHandle, MGR_HANDLE_TYPE)) RS_DBI_errorMessage("invalid MySQLManager", RS_DBI_ERROR); /* Create connection parameters structure and initialize */ conParams = RS_MySQL_allocConParams(); /* Arguments override defaults in config file */ if(s_dbname != R_NilValue && IS_CHARACTER(s_dbname)) conParams->dbname = RS_DBI_copyString((char *) CHR_EL(s_dbname,0)); if(s_username != R_NilValue && IS_CHARACTER(s_username)) conParams->username = RS_DBI_copyString((char *) CHR_EL(s_username,0)); if(s_password != R_NilValue && IS_CHARACTER(s_password)) conParams->password = RS_DBI_copyString((char *) CHR_EL(s_password,0)); if(s_myhost != R_NilValue && IS_CHARACTER(s_myhost)) conParams->host = RS_DBI_copyString((char *) CHR_EL(s_myhost,0)); if(s_unix_socket != R_NilValue && IS_CHARACTER(s_unix_socket)) conParams->unix_socket = RS_DBI_copyString((char *) CHR_EL(s_unix_socket,0)); if (s_port != R_NilValue && IS_INTEGER(s_port) && INT_EL(s_port,0) > 0) conParams->port = (unsigned int) INT_EL(s_port,0); if (s_client_flag != R_NilValue && IS_INTEGER(s_client_flag)) conParams->client_flag = (unsigned int) INT_EL(s_client_flag,0); if(s_groups != R_NilValue && IS_CHARACTER(s_groups)) conParams->groups = RS_DBI_copyString((char *) CHR_EL(s_groups,0)); if(s_default_file != R_NilValue && IS_CHARACTER(s_default_file)) conParams->default_file = RS_DBI_copyString((char *) CHR_EL(s_default_file,0)); return RS_MySQL_createConnection(mgrHandle,conParams); } /* RS_MySQL_createConnection - internal function * * Used by both RS_MySQL_newConnection and RS_MySQL_cloneConnection. * It is responsible for the memory associated with conParams. */ Con_Handle * RS_MySQL_createConnection(Mgr_Handle *mgrHandle, RS_MySQL_conParams *conParams) { S_EVALUATOR RS_DBI_connection *con; Con_Handle *conHandle; MYSQL *my_connection; if(!is_validHandle(mgrHandle, MGR_HANDLE_TYPE)) RS_DBI_errorMessage("invalid MySQLManager", RS_DBI_ERROR); /* Initialize MySQL connection */ my_connection = mysql_init(NULL); #if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID > 32348 /* (BDR's fix) * Starting w. MySQL 3.23.39, LOAD DATA INFILE may be disabled (although * the default is enabled); since assignTable() depends on it, * we unconditionally enable it. */ mysql_options(my_connection, MYSQL_OPT_LOCAL_INFILE, 0); #endif /* Load MySQL default connection values from a group. * * MySQL will combine the options found in the '[client]' group and one more group * specified by MYSQL_READ_DEFAULT_GROUP. Typically, this will * be '[rs-dbi]' but the user can override with another group. Note that * while our interface will allow a user to pass in a vector of groups, * only the first group in the vector will be combined with '[client]'. * * Should we make this an error in a later release?) */ if (conParams->groups) mysql_options(my_connection, MYSQL_READ_DEFAULT_GROUP, conParams->groups); /* MySQL reads defaults from my.cnf or equivalent, but the user can supply * an alternative. */ if(conParams->default_file) mysql_options(my_connection, MYSQL_READ_DEFAULT_FILE, conParams->default_file); if(!mysql_real_connect(my_connection, conParams->host, conParams->username, conParams->password, conParams->dbname, conParams->port, conParams->unix_socket, conParams->client_flag)){ RS_MySQL_freeConParams(conParams); char buf[2048]; sprintf(buf, "Failed to connect to database: Error: %s\n", mysql_error(my_connection)); RS_DBI_errorMessage(buf, RS_DBI_ERROR); } /* MySQL connections can only have 1 result set open at a time */ conHandle = RS_DBI_allocConnection(mgrHandle, (Sint) 1); con = RS_DBI_getConnection(conHandle); if(!con){ mysql_close(my_connection); RS_MySQL_freeConParams(conParams); RS_DBI_errorMessage("could not alloc space for connection object", RS_DBI_ERROR); } con->conParams = (void *) conParams; con->drvConnection = (void *) my_connection; return conHandle; } s_object * RS_MySQL_closeConnection(Con_Handle *conHandle) { S_EVALUATOR RS_DBI_connection *con; MYSQL *my_connection; s_object *status; con = RS_DBI_getConnection(conHandle); if(con->num_res>0){ RS_DBI_errorMessage( "close the pending result sets before closing this connection", RS_DBI_ERROR); } /* make sure we first free the conParams and mysql connection from * the RS-RBI connection object. */ if(con->conParams){ RS_MySQL_freeConParams(con->conParams); con->conParams = (RS_MySQL_conParams *) NULL; } my_connection = (MYSQL *) con->drvConnection; mysql_close(my_connection); con->drvConnection = (void *) NULL; RS_DBI_freeConnection(conHandle); MEM_PROTECT(status = NEW_LOGICAL((Sint) 1)); LGL_EL(status, 0) = TRUE; MEM_UNPROTECT(1); return status; } /* Execute (currently) one sql statement (INSERT, DELETE, SELECT, etc.), * set coercion type mappings between the server internal data types and * S classes. Returns an S handle to a resultSet object. */ Res_Handle * RS_MySQL_exec(Con_Handle *conHandle, s_object *statement) { S_EVALUATOR RS_DBI_connection *con; Res_Handle *rsHandle; RS_DBI_resultSet *result; MYSQL *my_connection; MYSQL_RES *my_result; int num_fields, state; Sint res_id, is_select; char *dyn_statement; con = RS_DBI_getConnection(conHandle); my_connection = (MYSQL *) con->drvConnection; dyn_statement = RS_DBI_copyString(CHR_EL(statement,0)); /* Do we have a pending resultSet in the current connection? * MySQL only allows one resultSet per connection. */ if(con->num_res>0){ res_id = (Sint) con->resultSetIds[0]; /* recall, MySQL has only 1 res */ rsHandle = RS_DBI_asResHandle(MGR_ID(conHandle), CON_ID(conHandle), res_id); result = RS_DBI_getResultSet(rsHandle); if(result->completed == 0){ free(dyn_statement); RS_DBI_errorMessage( "connection with pending rows, close resultSet before continuing", RS_DBI_ERROR); } else RS_MySQL_closeResultSet(rsHandle); } /* Here is where we actually run the query */ state = mysql_query(my_connection, dyn_statement); if(state) { char errMsg[256]; free(dyn_statement); (void) sprintf(errMsg, "could not run statement: %s", mysql_error(my_connection)); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } /* Do we need output column/field descriptors? Only for SELECT-like * statements. The MySQL reference manual suggests invoking * mysql_use_result() and if it succeed the statement is SELECT-like * that can use a resultSet. Otherwise call mysql_field_count() * and if it returns zero, the sql was not a SELECT-like statement. * Finally a non-zero means a failed SELECT-like statement. */ my_result = mysql_use_result(my_connection); if(!my_result) my_result = (MYSQL_RES *) NULL; num_fields = (int) mysql_field_count(my_connection); is_select = (Sint) TRUE; if(!my_result){ if(num_fields>0){ free(dyn_statement); RS_DBI_errorMessage("error in select/select-like", RS_DBI_ERROR); } else is_select = FALSE; } /* we now create the wrapper and copy values */ rsHandle = RS_DBI_allocResultSet(conHandle); result = RS_DBI_getResultSet(rsHandle); result->statement = RS_DBI_copyString(dyn_statement); result->drvResultSet = (void *) my_result; result->rowCount = (Sint) 0; result->isSelect = is_select; if(!is_select){ result->rowsAffected = (Sint) mysql_affected_rows(my_connection); result->completed = 1; } else { result->rowsAffected = (Sint) -1; result->completed = 0; } if(is_select) result->fields = RS_MySQL_createDataMappings(rsHandle); free(dyn_statement); return rsHandle; } RS_DBI_fields * RS_MySQL_createDataMappings(Res_Handle *rsHandle) { MYSQL_RES *my_result; MYSQL_FIELD *select_dp; RS_DBI_connection *con; RS_DBI_resultSet *result; RS_DBI_fields *flds; int j, num_fields, internal_type; char errMsg[2048]; result = RS_DBI_getResultSet(rsHandle); my_result = (MYSQL_RES *) result->drvResultSet; /* here we fetch from the MySQL server the field descriptions */ select_dp = mysql_fetch_fields(my_result); con = RS_DBI_getConnection(rsHandle); num_fields = (int) mysql_field_count((MYSQL *) con->drvConnection); flds = RS_DBI_allocFields(num_fields); /* WARNING: TEXT fields are represented as BLOBS (sic), * not VARCHAR or some kind of string type. More troublesome is the * fact that a TEXT fields can be BINARY to indicate case-sensitivity. * The bottom line is that MySQL has a serious deficiency re: text * types (IMHO). A binary object (in SQL92, X/SQL at least) can * store all kinds of non-ASCII, non-printable stuff that can * potentially screw up S and R CHARACTER_TYPE. We are on thin ice. * * I'm aware that I'm introducing a potential bug here by following * the MySQL convention of treating BLOB's as TEXT (I'm symplifying * in order to properly handle commonly-found TEXT fields, at the * risk of core dumping when bona fide Binary objects are being * retrieved. * * Possible workaround: if strlen() of the field equals the * MYSQL_FIELD->length for all rows, then we are probably(?) safe * in considering TEXT a character type (non-binary). */ for (j = 0; j < num_fields; j++){ /* First, save the name, MySQL internal field name, type, length, etc. */ flds->name[j] = RS_DBI_copyString(select_dp[j].name); flds->type[j] = select_dp[j].type; /* recall that these are enum*/ flds->length[j] = select_dp[j].length; flds->precision[j] = select_dp[j].length; flds->scale[j] = select_dp[j].decimals; flds->nullOk[j] = (!IS_NOT_NULL(select_dp[j].flags)); internal_type = select_dp[j].type; switch(internal_type) { case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 1; break; case FIELD_TYPE_TINY: /* 1-byte TINYINT */ case FIELD_TYPE_SHORT: /* 2-byte SMALLINT */ case FIELD_TYPE_INT24: /* 3-byte MEDIUMINT */ case FIELD_TYPE_LONG: /* 4-byte INTEGER */ /* if unsigned, turn into numeric (may be too large for ints/long)*/ if(select_dp[j].flags & UNSIGNED_FLAG) flds->Sclass[j] = NUMERIC_TYPE; else flds->Sclass[j] = INTEGER_TYPE; break; #if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 50003 /* 5.0.3 */ case FIELD_TYPE_BIT: if(flds->precision[j] <= sizeof(Sint)) /* can R int hold the bytes? */ flds->Sclass[j] = INTEGER_TYPE; else { flds->Sclass[j] = CHARACTER_TYPE; (void) sprintf(errMsg, "BIT field in column %d too long (%d bits) for an R integer (imported as character)", j+1, flds->precision[j]); } #endif case FIELD_TYPE_LONGLONG: /* TODO: can we fit these in R/S ints? */ if(sizeof(Sint)>=8) /* Arg! this ain't pretty:-( */ flds->Sclass[j] = INTEGER_TYPE; else flds->Sclass[j] = NUMERIC_TYPE; case FIELD_TYPE_DECIMAL: #if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 50003 /* 5.0.3 */ case FIELD_TYPE_NEWDECIMAL: #endif if(flds->scale[j] > 0 || flds->precision[j] > 10) flds->Sclass[j] = NUMERIC_TYPE; else flds->Sclass[j] = INTEGER_TYPE; break; case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: flds->Sclass[j] = NUMERIC_TYPE; break; case FIELD_TYPE_BLOB: /* TODO: how should we bring large ones*/ case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_LONG_BLOB: flds->Sclass[j] = CHARACTER_TYPE; /* Grr! Hate this! */ flds->isVarLength[j] = (Sint) 1; break; case FIELD_TYPE_DATE: case FIELD_TYPE_TIME: case FIELD_TYPE_DATETIME: case FIELD_TYPE_YEAR: case FIELD_TYPE_NEWDATE: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 1; break; case FIELD_TYPE_ENUM: flds->Sclass[j] = CHARACTER_TYPE; /* see the MySQL ref. manual */ flds->isVarLength[j] = (Sint) 1; break; case FIELD_TYPE_SET: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 0; break; default: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 1; (void) sprintf(errMsg, "unrecognized MySQL field type %d in column %d imported as character", internal_type, j); RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); break; } } return flds; } s_object * /* output is a named list */ RS_MySQL_fetch(s_object *rsHandle, s_object *max_rec) { S_EVALUATOR RS_DBI_manager *mgr; RS_DBI_resultSet *result; RS_DBI_fields *flds; MYSQL_RES *my_result; MYSQL_ROW row; s_object *output, *s_tmp; #ifndef USING_R s_object *raw_obj, *raw_container; #endif unsigned long *lens; int i, j, null_item, expand; Sint *fld_nullOk, completed; Stype *fld_Sclass; Sint num_rec; int num_fields; result = RS_DBI_getResultSet(rsHandle); flds = result->fields; if(!flds) RS_DBI_errorMessage("corrupt resultSet, missing fieldDescription", RS_DBI_ERROR); num_rec = INT_EL(max_rec,0); expand = (num_rec < 0); /* dyn expand output to accommodate all rows*/ if(expand || num_rec == 0){ mgr = RS_DBI_getManager(rsHandle); num_rec = mgr->fetch_default_rec; } num_fields = flds->num_fields; MEM_PROTECT(output = NEW_LIST((Sint) num_fields)); RS_DBI_allocOutput(output, flds, num_rec, 0); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc output list", RS_DBI_ERROR); #endif fld_Sclass = flds->Sclass; fld_nullOk = flds->nullOk; /* actual fetching....*/ my_result = (MYSQL_RES *) result->drvResultSet; completed = (Sint) 0; for(i = 0; ; i++){ if(i==num_rec){ /* exhausted the allocated space */ if(expand){ /* do we extend or return the records fetched so far*/ num_rec = 2 * num_rec; RS_DBI_allocOutput(output, flds, num_rec, expand); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc output list", RS_DBI_ERROR); #endif } else break; /* okay, no more fetching for now */ } row = mysql_fetch_row(my_result); if(row==NULL){ /* either we finish or we encounter an error */ unsigned int err_no; RS_DBI_connection *con; con = RS_DBI_getConnection(rsHandle); err_no = mysql_errno((MYSQL *) con->drvConnection); completed = (Sint) (err_no ? -1 : 1); break; } lens = mysql_fetch_lengths(my_result); for(j = 0; j < num_fields; j++){ null_item = (row[j] == NULL); switch((int)fld_Sclass[j]){ case INTEGER_TYPE: if(null_item) NA_SET(&(LST_INT_EL(output,j,i)), INTEGER_TYPE); else LST_INT_EL(output,j,i) = (Sint) atol(row[j]); break; case CHARACTER_TYPE: /* BUG: I need to verify that a TEXT field (which is stored as * a BLOB by MySQL!) is indeed char and not a true * Binary obj (MySQL does not truly distinguish them). This * test is very gross. */ if(null_item) #ifdef USING_R SET_LST_CHR_EL(output,j,i,NA_STRING); #else NA_CHR_SET(LST_CHR_EL(output,j,i)); #endif else { if((size_t) lens[j] != strlen(row[j])){ char warn[128]; (void) sprintf(warn, "internal error: row %ld field %ld truncated", (long) i, (long) j); RS_DBI_errorMessage(warn, RS_DBI_WARNING); } SET_LST_CHR_EL(output,j,i,C_S_CPY(row[j])); } break; case NUMERIC_TYPE: if(null_item) NA_SET(&(LST_NUM_EL(output,j,i)), NUMERIC_TYPE); else LST_NUM_EL(output,j,i) = (double) atof(row[j]); break; #ifndef USING_R case SINGLE_TYPE: if(null_item) NA_SET(&(LST_FLT_EL(output,j,i)), SINGLE_TYPE); else LST_FLT_EL(output,j,i) = (float) atof(row[j]); break; case RAW_TYPE: /* these are blob's */ raw_obj = NEW_RAW((Sint) lens[j]); memcpy(RAW_DATA(raw_obj), row[j], lens[j]); raw_container = LST_EL(output,j); /* get list of raw objects*/ SET_ELEMENT(raw_container, (Sint) i, raw_obj); SET_ELEMENT(output, (Sint) j, raw_container); break; #endif default: /* error, but we'll try the field as character (!)*/ if(null_item) #ifdef USING_R SET_LST_CHR_EL(output,j,i, NA_STRING); #else NA_CHR_SET(LST_CHR_EL(output,j,i)); #endif else { char warn[64]; (void) sprintf(warn, "unrecognized field type %d in column %d", (int) fld_Sclass[j], (int) j); RS_DBI_errorMessage(warn, RS_DBI_WARNING); SET_LST_CHR_EL(output,j,i,C_S_CPY(row[j])); } break; } } } /* actual number of records fetched */ if(i < num_rec){ num_rec = i; /* adjust the length of each of the members in the output_list */ for(j = 0; jrowCount += num_rec; result->completed = (int) completed; MEM_UNPROTECT(1); return output; } /* return a 2-elem list with the last exception number and * exception message on a given connection. */ s_object * RS_MySQL_getException(s_object *conHandle) { S_EVALUATOR MYSQL *my_connection; s_object *output; RS_DBI_connection *con; Sint n = 2; char *exDesc[] = {"errorNum", "errorMsg"}; Stype exType[] = {INTEGER_TYPE, CHARACTER_TYPE}; Sint exLen[] = {1, 1}; con = RS_DBI_getConnection(conHandle); if(!con->drvConnection) RS_DBI_errorMessage("internal error: corrupt connection handle", RS_DBI_ERROR); output = RS_DBI_createNamedList(exDesc, exType, exLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not allocate named list", RS_DBI_ERROR); #endif my_connection = (MYSQL *) con->drvConnection; LST_INT_EL(output,0,0) = (Sint) mysql_errno(my_connection); SET_LST_CHR_EL(output,1,0,C_S_CPY(mysql_error(my_connection))); return output; } s_object * RS_MySQL_closeResultSet(s_object *resHandle) { S_EVALUATOR RS_DBI_resultSet *result; MYSQL_RES *my_result; s_object *status; result = RS_DBI_getResultSet(resHandle); my_result = (MYSQL_RES *) result->drvResultSet; if(my_result){ /* we need to flush any possibly remaining rows (see Manual Ch 20 p358) */ MYSQL_ROW row; while((row = mysql_fetch_row(result->drvResultSet))) ; } mysql_free_result(my_result); /* need to NULL drvResultSet, otherwise can't free the rsHandle */ result->drvResultSet = (void *) NULL; RS_DBI_freeResultSet(resHandle); MEM_PROTECT(status = NEW_LOGICAL((Sint) 1)); LGL_EL(status, 0) = TRUE; MEM_UNPROTECT(1); return status; } s_object * RS_MySQL_managerInfo(Mgr_Handle *mgrHandle) { S_EVALUATOR RS_DBI_manager *mgr; s_object *output; Sint i, num_con, max_con, *cons, ncon; Sint j, n = 8; char *mgrDesc[] = {"drvName", "connectionIds", "fetch_default_rec", "managerId", "length", "num_con", "counter", "clientVersion"}; Stype mgrType[] = {CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, CHARACTER_TYPE}; Sint mgrLen[] = {1, 1, 1, 1, 1, 1, 1, 1}; mgr = RS_DBI_getManager(mgrHandle); if(!mgr) RS_DBI_errorMessage("driver not loaded yet", RS_DBI_ERROR); num_con = (Sint) mgr->num_con; max_con = (Sint) mgr->length; mgrLen[1] = num_con; output = RS_DBI_createNamedList(mgrDesc, mgrType, mgrLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc named list", RS_DBI_ERROR); #endif j = (Sint) 0; if(mgr->drvName) SET_LST_CHR_EL(output,j++,0,C_S_CPY(mgr->drvName)); else SET_LST_CHR_EL(output,j++,0,C_S_CPY("")); cons = (Sint *) S_alloc((long)max_con, (int)sizeof(Sint)); ncon = RS_DBI_listEntries(mgr->connectionIds, mgr->length, cons); if(ncon != num_con){ RS_DBI_errorMessage( "internal error: corrupt RS_DBI connection table", RS_DBI_ERROR); } for(i = 0; i < num_con; i++) LST_INT_EL(output, j, i) = cons[i]; j++; LST_INT_EL(output,j++,0) = mgr->fetch_default_rec; LST_INT_EL(output,j++,0) = mgr->managerId; LST_INT_EL(output,j++,0) = mgr->length; LST_INT_EL(output,j++,0) = mgr->num_con; LST_INT_EL(output,j++,0) = mgr->counter; SET_LST_CHR_EL(output,j++,0,C_S_CPY(mysql_get_client_info())); return output; } s_object * RS_MySQL_connectionInfo(Con_Handle *conHandle) { S_EVALUATOR MYSQL *my_con; RS_MySQL_conParams *conParams; RS_DBI_connection *con; s_object *output; Sint i, n = 8, *res, nres; char *conDesc[] = {"host", "user", "dbname", "conType", "serverVersion", "protocolVersion", "threadId", "rsId"}; Stype conType[] = {CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE}; Sint conLen[] = {1, 1, 1, 1, 1, 1, 1, 1}; char *tmp; con = RS_DBI_getConnection(conHandle); conLen[7] = con->num_res; /* num of open resultSets */ my_con = (MYSQL *) con->drvConnection; output = RS_DBI_createNamedList(conDesc, conType, conLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc named list", RS_DBI_ERROR); #endif conParams = (RS_MySQL_conParams *) con->conParams; PROTECT(output); tmp = conParams->host? conParams->host : (my_con->host?my_con->host:""); SET_LST_CHR_EL(output,0,0,C_S_CPY(tmp)); tmp = conParams->username? conParams->username : (my_con->user?my_con->user:""); SET_LST_CHR_EL(output,1,0,C_S_CPY(tmp)); tmp = conParams->dbname? conParams->dbname : (my_con->db?my_con->db:""); SET_LST_CHR_EL(output,2,0,C_S_CPY(tmp)); SET_LST_CHR_EL(output,3,0,C_S_CPY(mysql_get_host_info(my_con))); SET_LST_CHR_EL(output,4,0,C_S_CPY(mysql_get_server_info(my_con))); LST_INT_EL(output,5,0) = (Sint) mysql_get_proto_info(my_con); LST_INT_EL(output,6,0) = (Sint) mysql_thread_id(my_con); res = (Sint *) S_alloc( (long) con->length, (int) sizeof(Sint)); nres = RS_DBI_listEntries(con->resultSetIds, con->length, res); if(nres != con->num_res){ UNPROTECT(1); RS_DBI_errorMessage( "internal error: corrupt RS_DBI resultSet table", RS_DBI_ERROR); } for( i = 0; i < con->num_res; i++){ LST_INT_EL(output,7,i) = (Sint) res[i]; } UNPROTECT(1); return output; } s_object * RS_MySQL_resultSetInfo(Res_Handle *rsHandle) { S_EVALUATOR RS_DBI_resultSet *result; s_object *output, *flds; Sint n = 6; char *rsDesc[] = {"statement", "isSelect", "rowsAffected", "rowCount", "completed", "fieldDescription"}; Stype rsType[] = {CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, LIST_TYPE}; Sint rsLen[] = {1, 1, 1, 1, 1, 1}; result = RS_DBI_getResultSet(rsHandle); if(result->fields) flds = RS_DBI_getFieldDescriptions(result->fields); else flds = S_NULL_ENTRY; output = RS_DBI_createNamedList(rsDesc, rsType, rsLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc named list", RS_DBI_ERROR); #endif SET_LST_CHR_EL(output,0,0,C_S_CPY(result->statement)); LST_INT_EL(output,1,0) = result->isSelect; LST_INT_EL(output,2,0) = result->rowsAffected; LST_INT_EL(output,3,0) = result->rowCount; LST_INT_EL(output,4,0) = result->completed; if(flds != S_NULL_ENTRY) SET_ELEMENT(LST_EL(output, 5), (Sint) 0, flds); return output; } s_object * RS_MySQL_typeNames(s_object *type) { s_object *typeNames; Sint n, *typeCodes; int i; char *tname; n = LENGTH(type); typeCodes = INTEGER_DATA(type); MEM_PROTECT(typeNames = NEW_CHARACTER(n)); for(i = 0; i < n; i++) { tname = RS_DBI_getTypeName(typeCodes[i], RS_MySQL_dataTypes); if (!tname) tname = ""; SET_CHR_EL(typeNames, i, C_S_CPY(tname)); } MEM_UNPROTECT(1); return typeNames; } /* * RS_MySQL_dbApply. * * R/S: dbApply(rs, INDEX, FUN, group.begin, group.end, end, ...) * * This first implementation of R's dbApply() * extracts rows from an open result set rs and applies functions * to those rows of each group. This is how it works: it keeps tracks of * the values of the field pointed by "group" and it identifies events: * BEGIN_GROUP (just read the first row of a different group), * NEW_RECORD (every record fetched generates this event), * and END_GROUP (just finished with the current group). At these points * we invoke the R functions group.end() and group.begin() in the * environment() of dbApply * [should it be the environment where dbApply was called from (i.e., * dbApply's parent's * frame)?] * Except for the very first group, the order of invocation is * end.group() followed by begin.group() * * NOTE: We're thinking of groups as commonly defined in awk scripts * (but also in SAP's ABAP/4) were rows are assumed to be sorted by * the "group" fields and we detect a different (new) group when any of * the "group" fields changes. Our implementation does not require * the result set to be sorted by group, but for performance-sake, * it better be. * * TODO: 1. Notify the reason for exiting (normal, exhausted maxBatches, etc.) * 2. Allow INDEX to be a list, as in tapply(). * 3. Handle NA's (SQL NULL's) in the INDEX and/or data fields. * Currently they are ignored, thus effectively causing a * new BEGIN_GROUP event. * 4. Re-write fetch() in terms of events (END_OF_DATA, * EXHAUST_DATAFRAME, DB_ERROR, etc.) * 5. Create a table of R callback functions indexed by events, * then a handle_event() could conveniently handle all the events. */ s_object *expand_list(s_object *old, Sint new_len); void add_group(s_object *group_names, s_object *data, Stype *fld_Sclass, Sint group, Sint ngroup, Sint i); unsigned int check_groupEvents(s_object *data, Stype fld_Sclass[], Sint row, Sint col); /* The following are the masks for the events/states we recognize as we * bring rows from the result set/cursor */ #define NEVER 0 #define BEGIN 1 /* prior to reading 1st row from the resultset */ #define END 2 /* after reading last row from the result set */ #define BEGIN_GROUP 4 /* just read in 1'st row for a different group */ #define END_GROUP 8 /* just read the last row of the current group */ #define NEW_RECORD 16 /* uninteresting ... */ #define PARTIAL_GROUP 32 /* too much data (>max_rex) partial buffer */ /* the following are non-grouping events (e.g., db errors, memory) */ #define EXHAUSTED_DF 64 /* exhausted the allocated data.frame */ #define EXHAUSTED_OUT 128 /* exhausted the allocated output list */ #define END_OF_DATA 256 /* end of data from the result set */ #define DBMS_ERROR 512 /* error in remote dbms */ /* beginGroupFun takes only one arg: the name of the current group */ s_object * RS_DBI_invokeBeginGroup(s_object *callObj, /* should be initialized */ const char *group_name, /* one string */ s_object *rho) { S_EVALUATOR s_object *s_group_name, *val; /* make a copy of the argument */ MEM_PROTECT(s_group_name = NEW_CHARACTER((Sint) 1)); SET_CHR_EL(s_group_name, 0, C_S_CPY(group_name)); /* and stick into call object */ SETCADR(callObj, s_group_name); val = EVAL_IN_FRAME(callObj, rho); MEM_UNPROTECT(1); return S_NULL_ENTRY; } s_object * RS_DBI_invokeNewRecord(s_object *callObj, /* should be initialized already */ s_object *new_record,/* a 1-row data.frame */ s_object *rho) { S_EVALUATOR s_object *df, *val; /* make a copy of the argument */ MEM_PROTECT(df = COPY_ALL(new_record)); /* and stick it into the call object */ SETCADR(callObj, df); val = EVAL_IN_FRAME(callObj, rho); MEM_UNPROTECT(1); return S_NULL_ENTRY; } /* endGroupFun takes two args: a data.frame and the group name */ s_object * RS_DBI_invokeEndGroup(s_object *callObj, s_object *data, const char *group_name, s_object *rho) { S_EVALUATOR s_object *s_x, *s_group_name, *val; /* make copies of the arguments */ MEM_PROTECT(callObj = duplicate(callObj)); MEM_PROTECT(s_x = COPY_ALL(data)); MEM_PROTECT(s_group_name = NEW_CHARACTER((Sint) 1)); SET_CHR_EL(s_group_name, 0, C_S_CPY(group_name)); /* stick copies of args into the call object */ SETCADR(callObj, s_x); SETCADDR(callObj, s_group_name); SETCADDDR(callObj, R_DotsSymbol); val = EVAL_IN_FRAME(callObj, rho); MEM_UNPROTECT(3); return val; } s_object * /* output is a named list */ RS_MySQL_dbApply(s_object *rsHandle, /* resultset handle */ s_object *s_group_field,/* this is a 0-based field number */ s_object *s_funs, /* a 5-elem list with handler funs */ s_object *rho, /* the env where to run funs */ s_object *s_batch_size, /* alloc these many rows */ s_object *s_max_rec) /* max rows per group */ { S_EVALUATOR RS_DBI_resultSet *result; RS_DBI_fields *flds; MYSQL_RES *my_result; MYSQL_ROW row; s_object *data, *cur_rec, *out_list, *group_names, *val; #ifndef USING_R s_object *raw_obj, *raw_container; #endif unsigned long *lens = (unsigned long *)0; Stype *fld_Sclass; Sint i, j, null_item, expand, *fld_nullOk, completed; Sint num_rec, num_groups; int num_fields; Sint max_rec = INT_EL(s_max_rec,0); /* max rec per group */ Sint ngroup = 0, group_field = INT_EL(s_group_field,0); long total_records; Sint pushed_back = FALSE; unsigned int event = NEVER; int np = 0; /* keeps track of MEM_PROTECT()'s */ s_object *beginGroupCall, *beginGroupFun = LST_EL(s_funs, 2); s_object *endGroupCall, *endGroupFun = LST_EL(s_funs, 3); s_object *newRecordCall, *newRecordFun = LST_EL(s_funs, 4); int invoke_beginGroup = (GET_LENGTH(beginGroupFun)>0); int invoke_endGroup = (GET_LENGTH(endGroupFun)>0); int invoke_newRecord = (GET_LENGTH(newRecordFun)>0); row = NULL; beginGroupCall = R_NilValue; /* -Wall */ if(invoke_beginGroup){ MEM_PROTECT(beginGroupCall=lang2(beginGroupFun, R_NilValue)); ++np; } endGroupCall = R_NilValue; /* -Wall */ if(invoke_endGroup){ /* TODO: append list(...) to the call object */ MEM_PROTECT(endGroupCall = lang4(endGroupFun, R_NilValue, R_NilValue, R_NilValue)); ++np; } newRecordCall = R_NilValue; /* -Wall */ if(invoke_newRecord){ MEM_PROTECT(newRecordCall = lang2(newRecordFun, R_NilValue)); ++np; } result = RS_DBI_getResultSet(rsHandle); flds = result->fields; if(!flds) RS_DBI_errorMessage("corrupt resultSet, missing fieldDescription", RS_DBI_ERROR); num_fields = flds->num_fields; fld_Sclass = flds->Sclass; fld_nullOk = flds->nullOk; MEM_PROTECT(data = NEW_LIST((Sint) num_fields)); /* buffer records */ MEM_PROTECT(cur_rec = NEW_LIST((Sint) num_fields)); /* current record */ np += 2; RS_DBI_allocOutput(cur_rec, flds, (Sint) 1, 0); RS_DBI_makeDataFrame(cur_rec); num_rec = INT_EL(s_batch_size, 0); /* this is num of rec per group! */ max_rec = INT_EL(s_max_rec,0); /* max rec **per group** */ num_groups = num_rec; MEM_PROTECT(out_list = NEW_LIST(num_groups)); MEM_PROTECT(group_names = NEW_CHARACTER(num_groups)); np += 2; /* set conversion for group names */ if(result->rowCount==0){ event = BEGIN; /* here we could invoke the begin function*/ } /* actual fetching.... */ my_result = (MYSQL_RES *) result->drvResultSet; completed = (Sint) 0; total_records = 0; expand = 0; /* expand or init each data vector? */ i = 0; /* index into row number **within** groups */ while(1){ if(i==0 || i==num_rec){ /* BEGIN, EXTEND_DATA, BEGIN_GROUP */ /* reset num_rec upon a new group, double it if needs to expand */ num_rec = (i==0) ? INT_EL(s_batch_size, 0) : 2*num_rec; if(idrvConnection); completed = (Sint) (err_no ? -1 : 1); break; } if(!pushed_back){ /* recompute fields lengths? */ lens = mysql_fetch_lengths(my_result); /* lengths for each field */ ++total_records; } /* coerce each entry row[j] to an R/S type according to its Sclass. * TODO: converter functions are badly needed. */ for(j = 0; j < num_fields; j++){ null_item = (row[j] == NULL); switch((int)fld_Sclass[j]){ case INTEGER_TYPE: if(null_item) NA_SET(&(LST_INT_EL(data,j,i)), INTEGER_TYPE); else LST_INT_EL(data,j,i) = atol(row[j]); LST_INT_EL(cur_rec,j,0) = LST_INT_EL(data,j,i); break; case CHARACTER_TYPE: /* BUG: I need to verify that a TEXT field (which is stored as * a BLOB by MySQL!) is indeed char and not a true * Binary obj (MySQL does not truly distinguish them). This * test is very gross. */ if(null_item) #ifdef USING_R SET_LST_CHR_EL(data,j,i,NA_STRING); #else NA_CHR_SET(LST_CHR_EL(data,j,i)); #endif else { if((size_t) lens[j] != strlen(row[j])){ char warn[128]; (void) sprintf(warn, "internal error: row %ld field %ld truncated", (long) i, (long) j); RS_DBI_errorMessage(warn, RS_DBI_WARNING); } SET_LST_CHR_EL(data,j,i,C_S_CPY(row[j])); } SET_LST_CHR_EL(cur_rec, j, 0, C_S_CPY(LST_CHR_EL(data,j,i))); break; case NUMERIC_TYPE: if(null_item) NA_SET(&(LST_NUM_EL(data,j,i)), NUMERIC_TYPE); else LST_NUM_EL(data,j,i) = (double) atof(row[j]); LST_NUM_EL(cur_rec,j,0) = LST_NUM_EL(data,j,i); break; #ifndef USING_R case SINGLE_TYPE: if(null_item) NA_SET(&(LST_FLT_EL(data,j,i)), SINGLE_TYPE); else LST_FLT_EL(data,j,i) = (float) atof(row[j]); LST_FLT_EL(cur_rec,j,0) = LST_FLT_EL(data,j,i); break; case RAW_TYPE: /* these are blob's */ raw_obj = NEW_RAW((Sint) lens[j]); memcpy(RAW_DATA(raw_obj), row[j], lens[j]); raw_container = LST_EL(data,j); /* get list of raw objects*/ SET_ELEMENT(raw_container, (Sint) i, raw_obj); SET_ELEMENT(data, (Sint) j, raw_container); break; #endif default: /* error, but we'll try the field as character (!)*/ if(null_item) #ifdef USING_R SET_LST_CHR_EL(data,j,i, NA_STRING); #else NA_CHR_SET(LST_CHR_EL(data,j,i)); #endif else { char warn[64]; (void) sprintf(warn, "unrecognized field type %d in column %d", (int) fld_Sclass[j], (int) j); RS_DBI_errorMessage(warn, RS_DBI_WARNING); SET_LST_CHR_EL(data,j,i,C_S_CPY(row[j])); } SET_LST_CHR_EL(cur_rec,j,0, C_S_CPY(LST_CHR_EL(data,j,i))); break; } } if(!pushed_back){ if(invoke_newRecord) RS_DBI_invokeNewRecord(newRecordCall, cur_rec, rho); } else { pushed_back = FALSE; } /* We just finished processing the new record, now we check * for some events (in addition to NEW_RECORD, of course). */ event = check_groupEvents(data, fld_Sclass, i, group_field); if(BEGIN_GROUP & event){ if(ngroup==num_groups){ /* exhausted output list? */ num_groups = 2 * num_groups; MEM_PROTECT(SET_LENGTH(out_list, num_groups)); MEM_PROTECT(SET_LENGTH(group_names, num_groups)); np += 2; } if(invoke_beginGroup) RS_DBI_invokeBeginGroup( beginGroupCall, CHR_EL(group_names, ngroup), rho); } if(END_GROUP & event){ add_group(group_names, data, fld_Sclass, group_field, ngroup, i-1); RS_DBI_allocOutput(data, flds, i, expand++); RS_DBI_makeDataFrame(data); val = RS_DBI_invokeEndGroup(endGroupCall, data, CHR_EL(group_names, ngroup), rho); SET_ELEMENT(out_list, ngroup, val); /* set length of data to zero to force initialization * for next group */ RS_DBI_allocOutput(data, flds, (Sint) 0, (Sint) 1); i = 0; /* flush */ ++ngroup; pushed_back = TRUE; continue; } i++; } /* we fetched all the rows we needed/could; compute actual number of * records fetched. * TODO: What should we return in the case of partial groups??? */ if(completed < 0) RS_DBI_errorMessage("error while fetching rows", RS_DBI_WARNING); else if(completed) event = (END_GROUP|END); else event = PARTIAL_GROUP; /* wrap up last group */ if((END_GROUP & event) || (PARTIAL_GROUP & event)){ add_group(group_names, data, fld_Sclass, group_field, ngroup, i-i); if(irowCount += total_records; result->completed = (int) completed; SET_NAMES(out_list, group_names); /* do I need to PROTECT? */ #ifndef USING_R out_list = AS_LIST(out_list); /* for S4/Splus[56]'s sake */ #endif MEM_UNPROTECT(np); return out_list; } unsigned int check_groupEvents(s_object *data, Stype fld_Sclass[], Sint irow, Sint jcol) { if(irow==0) /* Begin */ return (BEGIN|BEGIN_GROUP); switch(fld_Sclass[jcol]){ case LOGICAL_TYPE: if(LST_LGL_EL(data,jcol,irow)!=LST_LGL_EL(data,jcol,irow-1)) return (END_GROUP|BEGIN_GROUP); break; case INTEGER_TYPE: if(LST_INT_EL(data,jcol,irow)!=LST_INT_EL(data,jcol,irow-1)) return (END_GROUP|BEGIN_GROUP); break; case NUMERIC_TYPE: if(LST_NUM_EL(data,jcol,irow)!=LST_NUM_EL(data,jcol,irow-1)) return (END_GROUP|BEGIN_GROUP); break; #ifndef USING_R case SINGLE_TYPE: if(LST_FLT_EL(data,jcol,irow)!=LST_FLT_EL(data,jcol,irow-1)) return (END_GROUP|BEGIN_GROUP); break; #endif case CHARACTER_TYPE: if(strcmp(LST_CHR_EL(data,jcol,irow), LST_CHR_EL(data,jcol,irow-1))) return (END_GROUP|BEGIN_GROUP); break; default: PROBLEM "un-regongnized R/S data type %d", fld_Sclass[jcol] ERROR; break; } return NEW_RECORD; } /* append current group (as character) to the vector of group names */ void add_group(s_object *group_names, s_object *data, Stype *fld_Sclass, Sint group_field, Sint ngroup, Sint i) { char buff[1024]; switch((int) fld_Sclass[group_field]){ case LOGICAL_TYPE: (void) sprintf(buff, "%ld", (long) LST_LGL_EL(data,group_field,i)); break; case INTEGER_TYPE: (void) sprintf(buff, "%ld", (long) LST_INT_EL(data,group_field,i)); break; #ifndef USING_R case SINGLE_TYPE: (void) sprintf(buff, "%f", (double) LST_FLT_EL(data,group_field,i)); break; #endif case NUMERIC_TYPE: (void) sprintf(buff, "%f", (double) LST_NUM_EL(data,group_field,i)); break; case CHARACTER_TYPE: strcpy(buff, LST_CHR_EL(data,group_field,i)); break; default: RS_DBI_errorMessage("unrecognized R/S type for group", RS_DBI_ERROR); break; } SET_CHR_EL(group_names, ngroup, C_S_CPY(buff)); return; } /* the following function was kindly provided by Mikhail Kondrin * it returns the last inserted index. * TODO: It returns an int, but it can potentially be inadequate * if the index is anîunsigned integer. Should we return * a numeric instead? */ s_object * RS_MySQL_insertid(Con_Handle *conHandle) { S_EVALUATOR MYSQL *my_con; RS_DBI_connection *con; s_object *output; char *conDesc[] = {"iid"}; Stype conType[] = {INTEGER_TYPE}; /* dj: are we sure an int will do? */ Sint conLen[] = {1}; con = RS_DBI_getConnection(conHandle); my_con = (MYSQL *) con->drvConnection; output = RS_DBI_createNamedList(conDesc, conType, conLen, 1); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage("internal error: could not alloc named list", RS_DBI_ERROR); #endif LST_INT_EL(output,0,0) = (Sint) mysql_insert_id(my_con); return output; } /* The single string version of this function was kindly provided by * J. T. Lindgren (any bugs are probably dj's) * * NOTE/BUG?: This function could potentially grab a huge amount of memory * if given (not inappropriately) very large binary objects. How should * we protect against potentially deadly requests? */ s_object * RS_MySQL_escapeStrings(Con_Handle *conHandle, s_object *strings) { RS_DBI_connection *con; MYSQL *my_connection; long len, old_len; Sint i, nStrings; char *str; char *escapedString; s_object *output; con = RS_DBI_getConnection(conHandle); my_connection = (MYSQL *) con->drvConnection; nStrings = GET_LENGTH(strings); MEM_PROTECT(output = NEW_CHARACTER(nStrings)); old_len = (long) 1; escapedString = (char *) S_alloc(old_len, (int) sizeof(char)); if(!escapedString){ RS_DBI_errorMessage( "(RS_MySQL_escapeStrings) could not allocate memory", RS_DBI_ERROR); } for(i=0; i # undef ERROR #endif #include #include #include #include #include "RS-DBI.h" /* Note that MySQL client/server buffers are limited to 16MB and 1MB, * respectively (MySQL 4.1.1-alpha manual). So plan accordingly! */ /* MySQL connection parameters struct, allocating and freeing * methods. See mysql_real_connect() for details on the params * themselves. */ typedef struct st_sdbi_conParams { char *dbname; char *username; char *password; char *host; char *unix_socket; unsigned int port; unsigned int client_flag; char *groups; char *default_file; } RS_MySQL_conParams; RS_MySQL_conParams *RS_MySQL_allocConParams(void); RS_MySQL_conParams *RS_MySQL_cloneConParams(RS_MySQL_conParams *conParams); void RS_MySQL_freeConParams(RS_MySQL_conParams *conParams); /* The following functions are the S/R entry points into the C implementation * (i.e., these are the only ones visible from R/S) we use the prefix * "RS_MySQL" in function names to denote this. * These functions are built on top of the underlying RS_DBI manager, * connection, and resultsets structures and functions (see RS-DBI.h). * * Note: A handle is just an R/S object (see RS-DBI.h for details), i.e., * Mgr_Handle, Con_Handle, Res_Handle, Db_Handle are s_object * (integer vectors, to be precise). */ /* dbManager */ Mgr_Handle *RS_MySQL_init(s_object *config_params, s_object *reload); s_object *RS_MySQL_close(Mgr_Handle *mgrHandle); /* dbConnection */ Con_Handle *RS_MySQL_newConnection(Mgr_Handle *mgrHandle, s_object *s_dbname, s_object *s_username, s_object *s_password, s_object *s_myhost, s_object *s_unix_socket, s_object *s_port, s_object *s_client_flag, s_object *s_groups, s_object *s_default_file); Con_Handle *RS_MySQL_createConnection(Mgr_Handle *mgrHandle, RS_MySQL_conParams *conParams); Con_Handle *RS_MySQL_cloneConnection(Con_Handle *conHandle); s_object *RS_MySQL_closeConnection(Con_Handle *conHandle); s_object *RS_MySQL_getException(Con_Handle *conHandle); /* err No, Msg */ /* dbResultSet */ Res_Handle *RS_MySQL_exec(Con_Handle *conHandle, s_object *statement); s_object *RS_MySQL_fetch(Res_Handle *rsHandle, s_object *max_rec); s_object *RS_MySQL_closeResultSet(Res_Handle *rsHandle); /* Multiple result set function (as of MySQL Version 4.1) */ Res_Handle *RS_MySQL_nextResultSet(Con_Handle *conHandle); s_object *RS_MySQL_moreResultSets(Con_Handle *conHandle); /* boolean */ s_object *RS_MySQL_validHandle(Db_Handle *handle); /* boolean */ RS_DBI_fields *RS_MySQL_createDataMappings(Res_Handle *resHandle); /* the following funs return named lists with meta-data for * the manager, connections, and result sets, respectively. */ s_object *RS_MySQL_managerInfo(Mgr_Handle *mgrHandle); s_object *RS_MySQL_connectionInfo(Con_Handle *conHandle); s_object *RS_MySQL_resultSetInfo(Res_Handle *rsHandle); s_object *RS_MySQL_escapeStrings(Con_Handle *conHandle, s_object *statement); s_object *RS_MySQL_versionId(void); /* the following type names are from "mysql_com.h" */ static struct data_types RS_MySQL_dataTypes[] = { { "FIELD_TYPE_DECIMAL", FIELD_TYPE_DECIMAL}, { "FIELD_TYPE_TINY", FIELD_TYPE_TINY}, { "FIELD_TYPE_SHORT", FIELD_TYPE_SHORT}, { "FIELD_TYPE_LONG", FIELD_TYPE_LONG}, { "FIELD_TYPE_FLOAT", FIELD_TYPE_FLOAT}, { "FIELD_TYPE_DOUBLE", FIELD_TYPE_DOUBLE}, { "FIELD_TYPE_NULL", FIELD_TYPE_NULL}, { "FIELD_TYPE_TIMESTAMP", FIELD_TYPE_TIMESTAMP}, { "FIELD_TYPE_LONGLONG", FIELD_TYPE_LONGLONG}, { "FIELD_TYPE_INT24", FIELD_TYPE_INT24}, { "FIELD_TYPE_DATE", FIELD_TYPE_DATE}, { "FIELD_TYPE_TIME", FIELD_TYPE_TIME}, { "FIELD_TYPE_DATETIME", FIELD_TYPE_DATETIME}, { "FIELD_TYPE_YEAR", FIELD_TYPE_YEAR}, { "FIELD_TYPE_NEWDATE", FIELD_TYPE_NEWDATE}, { "FIELD_TYPE_ENUM", FIELD_TYPE_ENUM}, { "FIELD_TYPE_SET", FIELD_TYPE_SET}, { "FIELD_TYPE_TINY_BLOB", FIELD_TYPE_TINY_BLOB}, { "FIELD_TYPE_MEDIUM_BLOB",FIELD_TYPE_MEDIUM_BLOB}, { "FIELD_TYPE_LONG_BLOB", FIELD_TYPE_LONG_BLOB}, { "FIELD_TYPE_BLOB", FIELD_TYPE_BLOB}, { "FIELD_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING}, { "FIELD_TYPE_STRING", FIELD_TYPE_STRING}, { (char *) 0, -1 } }; s_object *RS_MySQL_typeNames(s_object *typeIds); extern const struct data_types RS_dataTypeTable[]; #ifdef _cplusplus } #endif #endif /* _RS_MYSQL_H */ RMySQL/src/Makevars.win320000755000175100001440000000013111703617102014577 0ustar hornikusersPKG_CPPFLAGS = -I"${MYSQL_HOME}"/include PKG_LIBS = "${MYSQL_HOME}"/lib/opt/libmysql.lib RMySQL/src/Makevars.in0000644000175100001440000000007011705321752014247 0ustar hornikusersPKG_CPPFLAGS = @PKG_CPPFLAGS@ PKG_LIBS = @PKG_LIBS@ -lz RMySQL/src/RS-DBI.h0000644000175100001440000002506011705321752013245 0ustar hornikusers#ifndef _RS_DBI_H #define _RS_DBI_H 1 /* * $Id$ * * Copyright (C) 1999-2002 The Omega Project for Statistical Computing. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* The following include file defines a number of C macros that hide * differences between R and S (e.g., the macro for type "Sint" expand * to "long" in the case of S and to int in the case of R, etc.) */ #ifdef __cplusplus extern "C" { #endif #include "S4R.h" /* WIN32 uses int _getpid() */ #if defined WIN32 #include /* #define getpid _getpid */ #include /* #define pid_t int */ #else #include #endif #include /* for isalpha */ /* We now define 4 important data structures: * RS_DBI_manager, RS_DBI_connection, RS_DBI_resultSet, and * RS_DBI_fields, corresponding to dbManager, dbConnection, * dbResultSet, and list of field descriptions. */ /* In R/S a dbObject is a foreign reference consisting of a vector * of 1, 2 or 3 integers. In the C implementation we use these * R/S vectors as handles (we could have used pointers). */ typedef enum enum_dbi_exception { RS_DBI_MESSAGE, RS_DBI_WARNING, RS_DBI_ERROR, RS_DBI_TERMINATE } DBI_EXCEPTION; /* dbObject handles are simple S/R integer vectors of 1, 2, or 3 integers * the *_ID macros extract the appropriate scalar. */ #define Mgr_Handle s_object #define Con_Handle s_object #define Res_Handle s_object #define Db_Handle s_object /* refers to any one of the above */ /* The integer value for the following enum's needs to equal * GET_LENGTH(handle) for the various handles. */ typedef enum enum_handle_type { MGR_HANDLE_TYPE = 1, /* dbManager handle */ CON_HANDLE_TYPE = 2, /* dbConnection handle */ RES_HANDLE_TYPE = 3 /* dbResult handle */ } HANDLE_TYPE; #define MGR_ID(handle) INT_EL((handle),0) /* the actual scalar mgr id */ #define CON_ID(handle) INT_EL((handle),1) #define RES_ID(handle) INT_EL((handle),2) /* First, the following fully describes the field output by a select * (or select-like) statement, and the mappings from the internal * database types to S classes. This structure contains the info we need * to build the R/S list (or data.frame) that will receive the SQL * output. It still needs some work to handle arbitrty BLOB's (namely * methods to map BLOBs into user-defined S objects). * Each element is an array of num_fields, this flds->Sclass[3] stores * the S class for the 4th output fields. */ typedef struct st_sdbi_fields { int num_fields; char **name; /* DBMS field names */ Sint *type; /* DBMS internal types */ Sint *length; /* DBMS lengths in bytes */ Sint *precision; /* DBMS num of digits for numeric types */ Sint *scale; /* DBMS num of decimals for numeric types */ Sint *nullOk; /* DBMS indicator for DBMS' NULL type */ Sint *isVarLength; /* DBMS variable-length char type */ Stype *Sclass; /* R/S class (type) -- may be overriden */ /* TODO: Need a table of fun pointers to converters */ } RS_DBI_fields; typedef struct st_sdbi_exception { DBI_EXCEPTION exceptionType; /* one of RS_DBI_WARN, RS_RBI_ERROR, etc */ int errorNum; /* SQL error number (possibly driver-dependent*/ char *errorMsg; /* SQL error message */ } RS_DBI_exception; /* The RS-DBI resultSet consists of a pointer to the actual DBMS * resultSet (e.g., MySQL, Oracle) possibly NULL, plus the fields * defined by the RS-DBI implementation. */ typedef struct st_sdbi_resultset { void *drvResultSet; /* the actual (driver's) cursor/result set */ void *drvData; /* a pointer to driver-specific data */ Sint managerId; /* the 3 *Id's are used for */ Sint connectionId; /* validating stuff coming from S */ Sint resultSetId; Sint isSelect; /* boolean for testing SELECTs */ char *statement; /* SQL statement */ Sint rowsAffected; /* used by non-SELECT statements */ Sint rowCount; /* rows fetched so far (SELECT-types)*/ Sint completed; /* have we fetched all rows? */ RS_DBI_fields *fields; } RS_DBI_resultSet; /* A dbConnection consists of a pointer to the actual implementation * (MySQL, Oracle, etc.) connection plus a resultSet and other * goodies used by the RS-DBI implementation. * The connection parameters (user, password, database name, etc.) are * defined by the actual driver -- we just set aside a void pointer. */ typedef struct st_sdbi_connection { void *conParams; /* pointer to connection params (host, user, etc)*/ void *drvConnection; /* pointer to the actual DBMS connection struct*/ void *drvData; /* to be used at will by individual drivers */ RS_DBI_resultSet **resultSets; /* vector to result set ptrs */ Sint *resultSetIds; Sint length; /* max num of concurrent resultSets */ Sint num_res; /* num of open resultSets */ Sint counter; /* total number of queries */ Sint managerId; Sint connectionId; RS_DBI_exception *exception; } RS_DBI_connection; /* dbManager */ typedef struct st_sdbi_manager { char *drvName; /* what driver are we implementing?*/ void *drvData; /* to be used by the drv implementation*/ RS_DBI_connection **connections; /* list of dbConnections */ Sint *connectionIds; /* array of connectionIds */ Sint length; /* max num of concurrent connections */ Sint num_con; /* num of opened connections */ Sint counter; /* num of connections handled so far*/ Sint fetch_default_rec; /* default num of records per fetch */ Sint managerId; /* typically, process id */ RS_DBI_exception *exception; } RS_DBI_manager; /* All RS_DBI functions and their signatures */ /* Note: the following alloc functions allocate the space for the * corresponding manager, connection, resultSet; they all * return handles. All DBI functions (free/get/etc) use the handle * to work with the various dbObjects. */ Mgr_Handle *RS_DBI_allocManager(const char *drvName, Sint max_con, Sint fetch_default_rec, Sint force_realloc); void RS_DBI_freeManager(Mgr_Handle *mgrHandle); RS_DBI_manager *RS_DBI_getManager(Db_Handle *handle); Mgr_Handle *RS_DBI_asMgrHandle(Sint pid); s_object *RS_DBI_managerInfo(Mgr_Handle *mgrHandle); /* dbConnection */ Con_Handle *RS_DBI_allocConnection(Mgr_Handle *mgrHandle, Sint max_res); void RS_DBI_freeConnection(Con_Handle *conHandle); RS_DBI_connection *RS_DBI_getConnection(Db_Handle *handle); Con_Handle *RS_DBI_asConHandle(Sint mgrId, Sint conId); s_object *RS_DBI_connectionInfo(Con_Handle *con_Handle); /* dbResultSet */ Res_Handle *RS_DBI_allocResultSet(Con_Handle *conHandle); void RS_DBI_freeResultSet(Res_Handle *rsHandle); RS_DBI_resultSet *RS_DBI_getResultSet(Res_Handle *rsHandle); Res_Handle *RS_DBI_asResHandle(Sint pid, Sint conId, Sint resId); s_object *RS_DBI_resultSetInfo(Res_Handle *rsHandle); /* utility funs */ s_object *RS_DBI_validHandle(Db_Handle *handle); /* callable from S/R */ int is_validHandle(Db_Handle *handle, HANDLE_TYPE handleType); /* a simple object database (mapping table) -- it uses simple linear * search (we don't expect to have more than a handful of simultaneous * connections and/or resultSets. If this is not the case, we could * use a hash table, but I doubt it's worth it (famous last words!). * These are used for storing/retrieving object ids, such as * connection ids from the manager object, and resultSet ids from a * connection object; of course, this is transparent to the various * drivers -- they should deal with handles exclusively. */ Sint RS_DBI_newEntry(Sint *table, Sint length); Sint RS_DBI_lookup(Sint *table, Sint length, Sint obj_id); Sint RS_DBI_listEntries(Sint *table, Sint length, Sint *entries); void RS_DBI_freeEntry(Sint *table, Sint indx); /* description of the fields in a result set */ RS_DBI_fields *RS_DBI_allocFields(int num_fields); s_object *RS_DBI_getFieldDescriptions(RS_DBI_fields *flds); void RS_DBI_freeFields(RS_DBI_fields *flds); /* we (re)allocate the actual output list in here (with the help of * RS_DBI_fields). This should be some kind of R/S "relation" * table, not a dataframe nor a list. */ void RS_DBI_allocOutput(s_object *output, RS_DBI_fields *flds, Sint num_rec, Sint expand); void RS_DBI_makeDataFrame(s_object *data); /* TODO: We need to elevate RS_DBI_errorMessage to either * dbManager and/or dbConnection methods. I still need to * go back and re-code the error-handling throughout, darn! */ void RS_DBI_errorMessage(char *msg, DBI_EXCEPTION exceptionType); void RS_DBI_setException(Db_Handle *handle, DBI_EXCEPTION exceptionType, int errorNum, const char *errorMsg); /* utility funs (copy strings, convert from R/S types to string, etc.*/ char *RS_DBI_copyString(const char *str); char *RS_DBI_nCopyString(const char *str, size_t len, int del_blanks); /* We now define a generic data type name-Id mapping struct * and initialize the RS_dataTypeTable[]. Each driver could * define similar table for generating friendly type names */ struct data_types { char *typeName; Sint typeId; }; /* return the primitive type name for a primitive type id */ char *RS_DBI_getTypeName(Sint typeCode, const struct data_types table[]); /* same, but callable from S/R and vectorized */ s_object *RS_DBI_SclassNames(s_object *types); s_object *RS_DBI_createNamedList(char **names, Stype *types, Sint *lengths, Sint n); s_object *RS_DBI_copyFields(RS_DBI_fields *flds); void RS_na_set(void *ptr, Stype type); int RS_is_na(void *ptr, Stype type); extern const struct data_types RS_dataTypeTable[]; #ifdef __cplusplus } #endif #endif /* _RS_DBI_H */ RMySQL/src/S4R.h0000644000175100001440000001631311705321752012736 0ustar hornikusers/* $Id$ * * ---- * The name of the project is RMySQL, not RSMySQL, so at some point we * will inevitably break compatibility with Splus. * * FAIR WARNING! * * Jeff Horner Wed Jan 28 10:14:02 CST 2009 * ---- * * S4 (Splus5+) and R portability macros. * * This file provides additional macros to the ones in Rdefines.h (in R) * and S4/Splus5 S.h (see Appendix A of the green book) to * allow portability between R > 1.0.0, S4, and Splus5+ at the C source * level. In addition to the macros in Rdefines.h and Appendix A, * we have macros to do x[[i][j] and x[[i]][j] <- val inside C functions, * macros to test for primitive data types, plus macros to test and * set NA's portably. * TODO: Macros to build and eval functions portably? */ #ifndef S4R_H #define S4R_H #ifdef __cplusplus extern "C" { #endif /* * If using SPLUS, you *need* to define the macro USING_SPLUS=[5|6] * (probably in the compiler command line) to trigger the right * sequence of definitions (we can no longer simply rely on S.h --- * we may need to avoid S.h altogether!) * * Some of these come from MASS, some from packages developed under * the Omega project, and some from RS-DBI itself. * */ #ifdef USING_SPLUS # if USING_SPLUS == 6 # define S_COMPATIBILITY 10 /* changing to the "new" API may be too */ # include "S_engine.h" /* time-consuming. */ # else # include "S.h" # endif #else /* not Splus, is it S4 or R? */ # include "S.h" # if (defined(S_VERSION)) # define USING_S4 /* do we really need S4 any more? */ # else # define USING_R # endif #endif /* Some of these come from MASS, some from packages developed under * the Omega project, and some from RS-DBI itself. */ #ifdef USING_R # include "Rversion.h" # if defined(R_VERSION) && R_VERSION >= R_Version(1,2,0) # define USE_RINTERNALS 1 /* buggy Rdefines.h in 1.2.0/1.2.1 */ # include "Rdefines.h" # ifdef SET_ELEMENT /* workaround for bug in Rdefines.h */ # undef SET_ELEMENT # define SET_ELEMENT(x,i,val) SET_VECTOR_ELT((x),(i),(val)) # endif /* SET_ELEMENT */ # else # include "Rdefines.h" # endif # define singl double # define Sint int # define charPtr SEXP * # define CHAR_DEREF(x) CHAR(x) # define C_S_CPY(p) COPY_TO_USER_STRING(p) /* cpy C string to R */ # define MEM_PROTECT(x) PROTECT(x) # define MEM_UNPROTECT(n) UNPROTECT(n) # define MEM_UNPROTECT_PTR(x) UNPROTECT_PTR(x) #elif (defined(USING_S4) || defined(USING_SPLUS)) # define singl float # define Sint long # define charPtr char ** # define CHAR_DEREF(x) x # define C_S_CPY(p) c_s_cpy((p), S_evaluator) /* cpy C string to S */ # define RAW_DATA(p) (RAW_POINTER(p)) /* missing in S4 S.h */ # define MEM_PROTECT(x) (x) /**/ # define MEM_UNPROTECT(n) /**/ # define MEM_UNPROTECT_PTR(x) /**/ #endif /* The following are macros defined in the Green Book, but missing * in Rdefines.h. The semantics are as close to S4's as possible (?). */ #ifdef USING_R # define COPY(x) duplicate(x) # define COPY_ALL(x) duplicate(x) # define EVAL_IN_FRAME(expr,n) eval(expr,n) # define GET_FROM_FRAME(name,n) findVar(install(name),n) # define ASSIGN_IN_FRAME(name,obj,n) defineVar(install(name),COPY(obj),n) #endif /* data types common to R and S4 */ #ifdef USING_R # define Stype SEXPTYPE # define LOGICAL_TYPE LGLSXP # define INTEGER_TYPE INTSXP # define NUMERIC_TYPE REALSXP # define SINGLE_TYPE REALSXP # define REAL_TYPE REALSXP # define CHARACTER_TYPE STRSXP # define STRING_TYPE STRSXP # define COMPLEX_TYPE CPLXSXP # define LIST_TYPE VECSXP #else # define Stype int # define LOGICAL_TYPE LGL # define INTEGER_TYPE INT # define NUMERIC_TYPE DOUBLE # define SINGLE_TYPE REAL # define REAL_TYPE REAL # define CHARACTER_TYPE CHAR # define STRING_TYPE CHAR # define COMPLEX_TYPE COMPLEX # define LIST_TYPE LIST # define RAW_TYPE RAW #endif #ifdef USING_R # undef INTEGER_DATA # define INTEGER_DATA(x) (INTEGER(x)) # undef S_NULL_ENTRY # define S_NULL_ENTRY R_NilValue #else # define S_NULL_ENTRY NULL_ENTRY #endif /* We simplify one- and two-level access to object and list * (mostly built on top of jmc's macros) * * NOTE: Recall that list element vectors should *not* be set * directly, but only thru SET_ELEMENT (Green book, Appendix A), e.g., * LIST_POINTER(x)[i] = NEW_CHARACTER(100); BAD!! * LST_EL(x,i) = NEW_CHARACTER(100); BAD!! * SET_ELEMENT(x, i, NEW_CHARACTER(100)); Okay * * It's okay to directly set the i'th element of the j'th list element: * LST_CHR_EL(x,i,j) = C_S_CPY(str); Okay (but not in R-1.2.1) * * For R >= 1.2.0 define * SET_LST_CHR_EL(x,i,j,val) */ /* x[i] */ #define LGL_EL(x,i) LOGICAL_POINTER((x))[(i)] #define INT_EL(x,i) INTEGER_POINTER((x))[(i)] #define SGL_EL(x,i) SINGLE_POINTER((x))[(i)] #define FLT_EL(x,i) SGL_EL((x),(i)) #define NUM_EL(x,i) NUMERIC_POINTER((x))[(i)] #define DBL_EL(x,i) NUM_EL((x),(i)) #define RAW_EL(x,i) RAW_POINTER((x))[(i)] #if defined(R_VERSION) && R_VERSION >= R_Version(1,2,0) # define LST_EL(x,i) VECTOR_ELT((x),(i)) # define CHR_EL(x,i) CHAR_DEREF(STRING_ELT((x),(i))) # define SET_CHR_EL(x,i,val) SET_STRING_ELT((x),(i), (val)) #else /* the following are valid for S4/Splus5 and R < 1.2.0 */ # define LST_EL(x,i) LIST_POINTER((x))[(i)] # define CHR_EL(x,i) CHAR_DEREF(CHARACTER_POINTER((x))[(i)]) # define SET_CHR_EL(x,i,val) (CHR_EL(x,i)=val) #endif /* x[[i]][j] -- can be also assigned if x[[i]] is a numeric type */ #define LST_CHR_EL(x,i,j) CHR_EL(LST_EL((x),(i)), (j)) #define LST_LGL_EL(x,i,j) LGL_EL(LST_EL((x),(i)), (j)) #define LST_INT_EL(x,i,j) INT_EL(LST_EL((x),(i)), (j)) #define LST_SGL_EL(x,i,j) SGL_EL(LST_EL((x),(i)), (j)) #define LST_FLT_EL(x,i,j) LST_SGL_EL((x),(i),(j)) #define LST_NUM_EL(x,i,j) NUM_EL(LST_EL((x),(i)), (j)) #define LST_DBL_EL(x,i,j) LST_NUM_EL((x),(i),(j)) #define LST_RAW_EL(x,i,j) RAW_EL(LST_EL((x),(i)), (j)) #define LST_LST_EL(x,i,j) LST_EL(LST_EL((x),(i)), (j)) /* x[[i]][j] -- for the case when x[[i]] is a character type */ #if defined(R_VERSION) && R_VERSION >= R_Version(1,2,0) # define SET_LST_CHR_EL(x,i,j,val) SET_STRING_ELT(LST_EL(x,i), j, val) #else # define SET_LST_CHR_EL(x,i,j,val) (CHR_EL(LST_EL(x,i),j)=val) #endif /* setting and querying NA's -- in the case of R, we need to * use our own RS_na_set and RS_is_na functions (these need work!) */ #ifdef USING_R # define NA_SET(p,t) RS_na_set((p),(t)) # define NA_CHR_SET(p) SET_CHR_EL(p, 0, NA_STRING) # define IS_NA(p,t) RS_is_na((p),(t)) #else # define NA_SET(p,t) na_set((p),(t)) # define NA_CHR_SET(p) (p) = C_S_CPY(NA_STRING) # define IS_NA(p,t) is_na((p), (t)) #endif /* SET_ROWNAMES() and SET_CLASS_NAME() don't exist in S4 */ #ifdef USING_R # define SET_ROWNAMES(df,n) setAttrib(df, R_RowNamesSymbol, n) # define GET_CLASS_NAME(x) GET_CLASS(x) # define SET_CLASS_NAME(x,n) SET_CLASS(x, n) #else # define SET_ROWNAMES(df,n) error("un-implemented macro SET_ROWNAMES") # define SET_CLASS_NAME(x,n) error("un-implemented macro SET_CLASS_NAME") #endif /* end of RS-DBI macros */ #ifdef __cplusplus } #endif #endif /* S4R_H */ RMySQL/src/RS-DBI.c0000644000175100001440000011154511705321752013244 0ustar hornikusers/* * $Id$ * * * Copyright (C) 1999-2002 The Omega Project for Statistical Computing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "RS-DBI.h" /* TODO: monitor memory/object size consumption against S limits * in $SHOME/include/options.h we find "max_memory". We then * mem_size to make sure we're not bumping into problems. * But, is mem_size() reliable? How should we do this? * * TODO: invoke user-specified generators * * TODO: Implement exception objects for each dbObject. */ static RS_DBI_manager *dbManager = NULL; Mgr_Handle * RS_DBI_allocManager(const char *drvName, Sint max_con, Sint fetch_default_rec, Sint force_realloc) { /* Currently, the dbManager is a singleton (therefore we don't * completly free all the space). Here we alloc space * for the dbManager and return its mgrHandle. force_realloc * means to re-allocate number of connections, etc. (in this case * we require to have all connections closed). (Note that if we * re-allocate, we don't re-set the counter, and thus we make sure * we don't recycle connection Ids in a giver S/R session). */ Mgr_Handle *mgrHandle; RS_DBI_manager *mgr; Sint counter; Sint mgr_id = (Sint) getpid(); int i; mgrHandle = RS_DBI_asMgrHandle(mgr_id); if(!dbManager){ /* alloc for the first time */ counter = 0; /* connections handled so far */ mgr = (RS_DBI_manager*) malloc(sizeof(RS_DBI_manager)); } else { /* we're re-entering */ if(dbManager->connections){ /* and mgr is valid */ if(!force_realloc) return mgrHandle; else RS_DBI_freeManager(mgrHandle); /* i.e., free connection arrays*/ } counter = dbManager->counter; mgr = dbManager; } /* Ok, we're here to expand number of connections, etc.*/ if(!mgr) RS_DBI_errorMessage("could not malloc the dbManger", RS_DBI_ERROR); mgr->drvName = RS_DBI_copyString(drvName); mgr->drvData = (void *) NULL; mgr->managerId = mgr_id; mgr->connections = (RS_DBI_connection **) calloc((size_t) max_con, sizeof(RS_DBI_connection)); if(!mgr->connections){ free(mgr); RS_DBI_errorMessage("could not calloc RS_DBI_connections", RS_DBI_ERROR); } mgr->connectionIds = (Sint *) calloc((size_t)max_con, sizeof(Sint)); if(!mgr->connectionIds){ free(mgr->connections); free(mgr); RS_DBI_errorMessage("could not calloc vector of connection Ids", RS_DBI_ERROR); } mgr->counter = counter; mgr->length = max_con; mgr->num_con = (Sint) 0; mgr->fetch_default_rec = fetch_default_rec; for(i=0; i < max_con; i++){ mgr->connectionIds[i] = -1; mgr->connections[i] = (RS_DBI_connection *) NULL; } dbManager = mgr; return mgrHandle; } /* We don't want to completely free the dbManager, but rather we * re-initialize all the fields except for mgr->counter to ensure we don't * re-cycle connection ids across R/S DBI sessions in the the same pid * (S/R session). */ void RS_DBI_freeManager(Mgr_Handle *mgrHandle) { RS_DBI_manager *mgr; mgr = RS_DBI_getManager(mgrHandle); if(mgr->num_con > 0){ char *errMsg = "all opened connections were forcebly closed"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(mgr->drvData){ char *errMsg = "mgr->drvData was not freed (some memory leaked)"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(mgr->drvName){ free(mgr->drvName); mgr->drvName = (char *) NULL; } if(mgr->connections) { free(mgr->connections); mgr->connections = (RS_DBI_connection **) NULL; } if(mgr->connectionIds) { free(mgr->connectionIds); mgr->connectionIds = (Sint *) NULL; } return; } Con_Handle * RS_DBI_allocConnection(Mgr_Handle *mgrHandle, Sint max_res) { RS_DBI_manager *mgr; RS_DBI_connection *con; Con_Handle *conHandle; Sint i, indx, con_id; mgr = RS_DBI_getManager(mgrHandle); indx = RS_DBI_newEntry(mgr->connectionIds, mgr->length); if(indx < 0){ char buf[128], msg[128]; (void) strcat(msg, "cannot allocate a new connection -- maximum of "); (void) strcat(msg, "%d connections already opened"); (void) sprintf(buf, msg, (int) mgr->length); RS_DBI_errorMessage(buf, RS_DBI_ERROR); } con = (RS_DBI_connection *) malloc(sizeof(RS_DBI_connection)); if(!con){ char *errMsg = "could not malloc dbConnection"; RS_DBI_freeEntry(mgr->connectionIds, indx); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } con->managerId = MGR_ID(mgrHandle); con_id = mgr->counter; con->connectionId = con_id; con->drvConnection = (void *) NULL; con->drvData = (void *) NULL; /* to be used by the driver in any way*/ con->conParams = (void *) NULL; con->counter = (Sint) 0; con->length = max_res; /* length of resultSet vector */ /* result sets for this connection */ con->resultSets = (RS_DBI_resultSet **) calloc((size_t) max_res, sizeof(RS_DBI_resultSet)); if(!con->resultSets){ char *errMsg = "could not calloc resultSets for the dbConnection"; RS_DBI_freeEntry(mgr->connectionIds, indx); free(con); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } con->num_res = (Sint) 0; con->resultSetIds = (Sint *) calloc((size_t) max_res, sizeof(Sint)); if(!con->resultSetIds) { char *errMsg = "could not calloc vector of resultSet Ids"; free(con->resultSets); free(con); RS_DBI_freeEntry(mgr->connectionIds, indx); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } for(i=0; iresultSets[i] = (RS_DBI_resultSet *) NULL; con->resultSetIds[i] = -1; } /* Finally, update connection table in mgr */ mgr->num_con += (Sint) 1; mgr->counter += (Sint) 1; mgr->connections[indx] = con; mgr->connectionIds[indx] = con_id; conHandle = RS_DBI_asConHandle(MGR_ID(mgrHandle), con_id); return conHandle; } /* the invoking (freeing) function must provide a function for * freeing the conParams, and by setting the (*free_drvConParams)(void *) * pointer. */ void RS_DBI_freeConnection(Con_Handle *conHandle) { RS_DBI_connection *con; RS_DBI_manager *mgr; Sint indx; con = RS_DBI_getConnection(conHandle); mgr = RS_DBI_getManager(conHandle); /* Are there open resultSets? If so, free them first */ if(con->num_res > 0) { char *errMsg = "opened resultSet(s) forcebly closed"; int i; Res_Handle *rsHandle; for(i=0; i < con->num_res; i++){ rsHandle = RS_DBI_asResHandle(con->managerId, con->connectionId, (Sint) con->resultSetIds[i]); RS_DBI_freeResultSet(rsHandle); } RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(con->drvConnection) { char *errMsg = "internal error in RS_DBI_freeConnection: driver might have left open its connection on the server"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(con->conParams){ char *errMsg = "internal error in RS_DBI_freeConnection: non-freed con->conParams (tiny memory leaked)"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(con->drvData){ char *errMsg = "internal error in RS_DBI_freeConnection: non-freed con->drvData (some memory leaked)"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } /* delete this connection from manager's connection table */ if(con->resultSets) free(con->resultSets); if(con->resultSetIds) free(con->resultSetIds); /* update the manager's connection table */ indx = RS_DBI_lookup(mgr->connectionIds, mgr->length, con->connectionId); RS_DBI_freeEntry(mgr->connectionIds, indx); mgr->connections[indx] = (RS_DBI_connection *) NULL; mgr->num_con -= (Sint) 1; free(con); con = (RS_DBI_connection *) NULL; return; } Res_Handle * RS_DBI_allocResultSet(Con_Handle *conHandle) { RS_DBI_connection *con = NULL; RS_DBI_resultSet *result = NULL; Res_Handle *rsHandle; Sint indx, res_id; con = RS_DBI_getConnection(conHandle); indx = RS_DBI_newEntry(con->resultSetIds, con->length); if(indx < 0){ char msg[128], fmt[128]; (void) strcpy(fmt, "cannot allocate a new resultSet -- "); (void) strcat(fmt, "maximum of %d resultSets already reached"); (void) sprintf(msg, fmt, con->length); RS_DBI_errorMessage(msg, RS_DBI_ERROR); } result = (RS_DBI_resultSet *) malloc(sizeof(RS_DBI_resultSet)); if(!result){ char *errMsg = "could not malloc dbResultSet"; RS_DBI_freeEntry(con->resultSetIds, indx); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } result->drvResultSet = (void *) NULL; /* driver's own resultSet (cursor)*/ result->drvData = (void *) NULL; /* this can be used by driver*/ result->statement = (char *) NULL; result->managerId = MGR_ID(conHandle); result->connectionId = CON_ID(conHandle); result->resultSetId = con->counter; result->isSelect = (Sint) -1; result->rowsAffected = (Sint) -1; result->rowCount = (Sint) 0; result->completed = (Sint) -1; result->fields = (RS_DBI_fields *) NULL; /* update connection's resultSet table */ res_id = con->counter; con->num_res += (Sint) 1; con->counter += (Sint) 1; con->resultSets[indx] = result; con->resultSetIds[indx] = res_id; rsHandle = RS_DBI_asResHandle(MGR_ID(conHandle),CON_ID(conHandle),res_id); return rsHandle; } void RS_DBI_freeResultSet(Res_Handle *rsHandle) { RS_DBI_resultSet *result; RS_DBI_connection *con; Sint indx; con = RS_DBI_getConnection(rsHandle); result = RS_DBI_getResultSet(rsHandle); if(result->drvResultSet) { char *errMsg = "internal error in RS_DBI_freeResultSet: non-freed result->drvResultSet (some memory leaked)"; RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } if(result->drvData){ char *errMsg = "internal error in RS_DBI_freeResultSet: non-freed result->drvData (some memory leaked)"; RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } if(result->statement) free(result->statement); if(result->fields) RS_DBI_freeFields(result->fields); free(result); result = (RS_DBI_resultSet *) NULL; /* update connection's resultSet table */ indx = RS_DBI_lookup(con->resultSetIds, con->length, RES_ID(rsHandle)); RS_DBI_freeEntry(con->resultSetIds, indx); con->resultSets[indx] = (RS_DBI_resultSet *) NULL; con->num_res -= (Sint) 1; return; } RS_DBI_fields * RS_DBI_allocFields(int num_fields) { RS_DBI_fields *flds; size_t n; flds = (RS_DBI_fields *)malloc(sizeof(RS_DBI_fields)); if(!flds){ char *errMsg = "could not malloc RS_DBI_fields"; RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } n = (size_t) num_fields; flds->num_fields = num_fields; flds->name = (char **) calloc(n, sizeof(char *)); flds->type = (Sint *) calloc(n, sizeof(Sint)); flds->length = (Sint *) calloc(n, sizeof(Sint)); flds->precision= (Sint *) calloc(n, sizeof(Sint)); flds->scale = (Sint *) calloc(n, sizeof(Sint)); flds->nullOk = (Sint *) calloc(n, sizeof(Sint)); flds->isVarLength = (Sint *) calloc(n, sizeof(Sint)); flds->Sclass = (Stype *) calloc(n, sizeof(Stype)); return flds; } void RS_DBI_freeFields(RS_DBI_fields *flds) { int i; if(flds->name) { /* (as per Jeff Horner's patch) */ for(i = 0; i < flds->num_fields; i++) if(flds->name[i]) free(flds->name[i]); free(flds->name); } if(flds->type) free(flds->type); if(flds->length) free(flds->length); if(flds->precision) free(flds->precision); if(flds->scale) free(flds->scale); if(flds->nullOk) free(flds->nullOk); if(flds->isVarLength) free(flds->isVarLength); if(flds->Sclass) free(flds->Sclass); free(flds); flds = (RS_DBI_fields *) NULL; return; } /* Make a data.frame from a named list by adding row.names, and class * attribute. Use "1", "2", .. as row.names. * NOTE: Only tested under R (not tested at all under S4 or Splus5+). */ void RS_DBI_makeDataFrame(s_object *data) { S_EVALUATOR s_object *row_names, *df_class_name; #ifndef USING_R s_object *S_RowNamesSymbol; /* mimic Rinternal.h R_RowNamesSymbol */ s_object *S_ClassSymbol; #endif Sint i, n; char buf[1024]; #ifndef USING_R if(IS_LIST(data)) data = AS_LIST(data); else RS_DBI_errorMessage( "internal error in RS_DBI_makeDataFrame: could not corce named-list into data.frame", RS_DBI_ERROR); #endif MEM_PROTECT(data); MEM_PROTECT(df_class_name = NEW_CHARACTER((Sint) 1)); SET_CHR_EL(df_class_name, 0, C_S_CPY("data.frame")); /* row.names */ n = GET_LENGTH(LST_EL(data,0)); /* length(data[[1]]) */ MEM_PROTECT(row_names = NEW_CHARACTER(n)); for(i=0; inum_fields; if(expand){ for(j = 0; j < (Sint) num_fields; j++){ /* Note that in R-1.2.3 (at least) we need to protect SET_LENGTH */ s_tmp = LST_EL(output,j); MEM_PROTECT(SET_LENGTH(s_tmp, num_rec)); SET_ELEMENT(output, j, s_tmp); MEM_UNPROTECT(1); } #ifndef USING_R output = AS_LIST(output); /* this is only for S4's sake */ #endif MEM_UNPROTECT(1); return; } fld_Sclass = flds->Sclass; for(j = 0; j < (Sint) num_fields; j++){ switch((int)fld_Sclass[j]){ case LOGICAL_TYPE: SET_ELEMENT(output, j, NEW_LOGICAL(num_rec)); break; case CHARACTER_TYPE: SET_ELEMENT(output, j, NEW_CHARACTER(num_rec)); break; case INTEGER_TYPE: SET_ELEMENT(output, j, NEW_INTEGER(num_rec)); break; case NUMERIC_TYPE: SET_ELEMENT(output, j, NEW_NUMERIC(num_rec)); break; case LIST_TYPE: SET_ELEMENT(output, j, NEW_LIST(num_rec)); break; #ifndef USING_R /* should we map BLOBS to RAWs? what do we return? an external pointer?*/ case RAW: /* we use a list as a container for raw objects */ SET_ELEMENT(output, j, NEW_LIST(num_rec)); break; #endif default: RS_DBI_errorMessage("unsupported data type", RS_DBI_ERROR); } } MEM_PROTECT(names = NEW_CHARACTER((Sint) num_fields)); for(j = 0; j< (Sint) num_fields; j++){ SET_CHR_EL(names,j, C_S_CPY(flds->name[j])); } SET_NAMES(output, names); #ifndef USING_R output = AS_LIST(output); /* again this is required only for S4 */ #endif MEM_UNPROTECT(2); return; } s_object * /* boolean */ RS_DBI_validHandle(Db_Handle *handle) { S_EVALUATOR s_object *valid; int handleType = 0; switch( (int) GET_LENGTH(handle)){ case MGR_HANDLE_TYPE: handleType = MGR_HANDLE_TYPE; break; case CON_HANDLE_TYPE: handleType = CON_HANDLE_TYPE; break; case RES_HANDLE_TYPE: handleType = RES_HANDLE_TYPE; break; } MEM_PROTECT(valid = NEW_LOGICAL((Sint) 1)); LGL_EL(valid,0) = (Sint) is_validHandle(handle, handleType); MEM_UNPROTECT(1); return valid; } void RS_DBI_setException(Db_Handle *handle, DBI_EXCEPTION exceptionType, int errorNum, const char *errorMsg) { HANDLE_TYPE handleType; handleType = (int) GET_LENGTH(handle); if(handleType == MGR_HANDLE_TYPE){ RS_DBI_manager *obj; obj = RS_DBI_getManager(handle); obj->exception->exceptionType = exceptionType; obj->exception->errorNum = errorNum; obj->exception->errorMsg = RS_DBI_copyString(errorMsg); } else if(handleType==CON_HANDLE_TYPE){ RS_DBI_connection *obj; obj = RS_DBI_getConnection(handle); obj->exception->exceptionType = exceptionType; obj->exception->errorNum = errorNum; obj->exception->errorMsg = RS_DBI_copyString(errorMsg); } else { RS_DBI_errorMessage( "internal error in RS_DBI_setException: could not setException", RS_DBI_ERROR); } return; } void RS_DBI_errorMessage(char *msg, DBI_EXCEPTION exception_type) { char *driver = "RS-DBI"; /* TODO: use the actual driver name */ switch(exception_type) { case RS_DBI_MESSAGE: PROBLEM "%s driver message: (%s)", driver, msg WARN; /* was PRINT_IT */ break; case RS_DBI_WARNING: PROBLEM "%s driver warning: (%s)", driver, msg WARN; break; case RS_DBI_ERROR: PROBLEM "%s driver: (%s)", driver, msg ERROR; break; case RS_DBI_TERMINATE: PROBLEM "%s driver fatal: (%s)", driver, msg ERROR; /* was TERMINATE */ break; } return; } /* wrapper to strcpy */ char * RS_DBI_copyString(const char *str) { char *buffer; buffer = (char *) malloc((size_t) strlen(str)+1); if(!buffer) RS_DBI_errorMessage( "internal error in RS_DBI_copyString: could not alloc string space", RS_DBI_ERROR); return strcpy(buffer, str); } /* wrapper to strncpy, plus (optionally) deleting trailing spaces */ char * RS_DBI_nCopyString(const char *str, size_t len, int del_blanks) { char *str_buffer, *end; str_buffer = (char *) malloc(len+1); if(!str_buffer){ char errMsg[128]; (void) sprintf(errMsg, "could not malloc %ld bytes in RS_DBI_nCopyString", (long) len+1); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } if(len==0){ *str_buffer = '\0'; return str_buffer; } (void) strncpy(str_buffer, str, len); /* null terminate string whether we delete trailing blanks or not*/ if(del_blanks){ for(end = str_buffer+len-1; end>=str_buffer; end--) if(*end != ' ') { end++; break; } *end = '\0'; } else { end = str_buffer + len; *end = '\0'; } return str_buffer; } s_object * RS_DBI_copyfields(RS_DBI_fields *flds) { S_EVALUATOR s_object *S_fields; Sint n = (Sint) 8; char *desc[]={"name", "Sclass", "type", "len", "precision", "scale","isVarLength", "nullOK"}; Stype types[] = {CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, LOGICAL_TYPE, LOGICAL_TYPE}; Sint lengths[8]; int i, j, num_fields; num_fields = flds->num_fields; for(j = 0; j < n; j++) lengths[j] = (Sint) num_fields; S_fields = RS_DBI_createNamedList(desc, types, lengths, n); #ifndef USING_R if(IS_LIST(S_fields)) S_fields = AS_LIST(S_fields); else RS_DBI_errorMessage( "internal error in RS_DBI_copyfields: could not alloc named list", RS_DBI_ERROR); #endif /* copy contentes from flds into an R/S list */ for(i = 0; i < num_fields; i++){ SET_LST_CHR_EL(S_fields,0,i, C_S_CPY(flds->name[i])); LST_INT_EL(S_fields,1,i) = (Sint) flds->Sclass[i]; LST_INT_EL(S_fields,2,i) = (Sint) flds->type[i]; LST_INT_EL(S_fields,3,i) = (Sint) flds->length[i]; LST_INT_EL(S_fields,4,i) = (Sint) flds->precision[i]; LST_INT_EL(S_fields,5,i) = (Sint) flds->scale[i]; LST_INT_EL(S_fields,6,i) = (Sint) flds->isVarLength[i]; LST_INT_EL(S_fields,7,i) = (Sint) flds->nullOk[i]; } return S_fields; } s_object * RS_DBI_createNamedList(char **names, Stype *types, Sint *lengths, Sint n) { S_EVALUATOR s_object *output, *output_names, *obj = S_NULL_ENTRY; Sint num_elem; int j; MEM_PROTECT(output = NEW_LIST(n)); MEM_PROTECT(output_names = NEW_CHARACTER(n)); for(j = 0; j < n; j++){ num_elem = lengths[j]; switch((int)types[j]){ case LOGICAL_TYPE: MEM_PROTECT(obj = NEW_LOGICAL(num_elem)); break; case INTEGER_TYPE: MEM_PROTECT(obj = NEW_INTEGER(num_elem)); break; case NUMERIC_TYPE: MEM_PROTECT(obj = NEW_NUMERIC(num_elem)); break; case CHARACTER_TYPE: MEM_PROTECT(obj = NEW_CHARACTER(num_elem)); break; case LIST_TYPE: MEM_PROTECT(obj = NEW_LIST(num_elem)); break; #ifndef USING_R /* this should work in R, but it needs testing first */ case RAW_TYPE: MEM_PROTECT(obj = NEW_RAW(num_elem)); break; #endif default: RS_DBI_errorMessage("unsupported data type", RS_DBI_ERROR); } SET_ELEMENT(output, (Sint)j, obj); SET_CHR_EL(output_names, j, C_S_CPY(names[j])); } SET_NAMES(output, output_names); MEM_UNPROTECT(n+2); return(output); } s_object * RS_DBI_SclassNames(s_object *type) { s_object *typeNames; Sint *typeCodes; Sint n; int i; char *s; if(type==S_NULL_ENTRY) RS_DBI_errorMessage( "internal error in RS_DBI_SclassNames: input S types must be nonNULL", RS_DBI_ERROR); n = LENGTH(type); typeCodes = INTEGER_DATA(type); MEM_PROTECT(typeNames = NEW_CHARACTER(n)); for(i = 0; i < n; i++) { s = RS_DBI_getTypeName(typeCodes[i], RS_dataTypeTable); if(!s){ RS_DBI_errorMessage( "internal error RS_DBI_SclassNames: unrecognized S type", RS_DBI_ERROR); s = ""; } SET_CHR_EL(typeNames, i, C_S_CPY(s)); } MEM_UNPROTECT(1); return typeNames; } /* The following functions roughly implement a simple object * database. */ Mgr_Handle * RS_DBI_asMgrHandle(Sint mgrId) { Mgr_Handle *mgrHandle; MEM_PROTECT(mgrHandle = NEW_INTEGER((Sint) 1)); MGR_ID(mgrHandle) = mgrId; MEM_UNPROTECT(1); return mgrHandle; } Con_Handle * RS_DBI_asConHandle(Sint mgrId, Sint conId) { Con_Handle *conHandle; MEM_PROTECT(conHandle = NEW_INTEGER((Sint) 2)); MGR_ID(conHandle) = mgrId; CON_ID(conHandle) = conId; MEM_UNPROTECT(1); return conHandle; } Res_Handle * RS_DBI_asResHandle(Sint mgrId, Sint conId, Sint resId) { Res_Handle *resHandle; MEM_PROTECT(resHandle = NEW_INTEGER((Sint) 3)); MGR_ID(resHandle) = mgrId; CON_ID(resHandle) = conId; RES_ID(resHandle) = resId; MEM_UNPROTECT(1); return resHandle; } RS_DBI_manager * RS_DBI_getManager(Mgr_Handle *handle) { RS_DBI_manager *mgr; if(!is_validHandle(handle, MGR_HANDLE_TYPE)) RS_DBI_errorMessage("invalid dbManager handle", RS_DBI_ERROR); mgr = dbManager; if(!mgr) RS_DBI_errorMessage( "internal error in RS_DBI_getManager: corrupt dbManager handle", RS_DBI_ERROR); return mgr; } RS_DBI_connection * RS_DBI_getConnection(Con_Handle *conHandle) { RS_DBI_manager *mgr; Sint indx; mgr = RS_DBI_getManager(conHandle); indx = RS_DBI_lookup(mgr->connectionIds, mgr->length, CON_ID(conHandle)); if(indx < 0) RS_DBI_errorMessage( "internal error in RS_DBI_getConnection: corrupt connection handle", RS_DBI_ERROR); if(!mgr->connections[indx]) RS_DBI_errorMessage( "internal error in RS_DBI_getConnection: corrupt connection object", RS_DBI_ERROR); return mgr->connections[indx]; } RS_DBI_resultSet * RS_DBI_getResultSet(Res_Handle *rsHandle) { RS_DBI_connection *con; Sint indx; con = RS_DBI_getConnection(rsHandle); indx = RS_DBI_lookup(con->resultSetIds, con->length, RES_ID(rsHandle)); if(indx<0) RS_DBI_errorMessage( "internal error in RS_DBI_getResultSet: could not find resultSet in connection", RS_DBI_ERROR); if(!con->resultSets[indx]) RS_DBI_errorMessage( "internal error in RS_DBI_getResultSet: missing resultSet", RS_DBI_ERROR); return con->resultSets[indx]; } /* Very simple objectId (mapping) table. newEntry() returns an index * to an empty cell in table, and lookup() returns the position in the * table of obj_id. Notice that we decided not to touch the entries * themselves to give total control to the invoking functions (this * simplify error management in the invoking routines.) */ Sint RS_DBI_newEntry(Sint *table, Sint length) { Sint i, indx, empty_val; indx = empty_val = (Sint) -1; for(i = 0; i < length; i++) if(table[i] == empty_val){ indx = i; break; } return indx; } Sint RS_DBI_lookup(Sint *table, Sint length, Sint obj_id) { Sint i, indx; indx = (Sint) -1; for(i = 0; i < length; ++i){ if(table[i]==obj_id){ indx = i; break; } } return indx; } /* return a list of entries pointed by *entries (we allocate the space, * but the caller should free() it). The function returns the number * of entries. */ Sint RS_DBI_listEntries(Sint *table, Sint length, Sint *entries) { int i,n; for(i=n=0; i3) return 0; mgr_id = MGR_ID(handle); if( ((Sint) getpid()) != mgr_id) return 0; /* at least we have a potential valid dbManager */ mgr = dbManager; if(!mgr || !mgr->connections) return 0; /* expired manager*/ if(handleType == MGR_HANDLE_TYPE) return 1; /* valid manager id */ /* ... on to connections */ indx = RS_DBI_lookup(mgr->connectionIds, mgr->length, CON_ID(handle)); if(indx<0) return 0; con = mgr->connections[indx]; if(!con) return 0; if(!con->resultSets) return 0; /* un-initialized (invalid) */ if(handleType==CON_HANDLE_TYPE) return 1; /* valid connection id */ /* .. on to resultSets */ indx = RS_DBI_lookup(con->resultSetIds, con->length, RES_ID(handle)); if(indx < 0) return 0; if(!con->resultSets[indx]) return 0; return 1; } /* The following 3 routines provide metadata for the 3 main objects * dbManager, dbConnection and dbResultSet. These functions * an object Id and return a list with all the meta-data. In R/S we * simply invoke one of these and extract the metadata piece we need, * which can be NULL if non-existent or un-implemented. * * Actually, each driver should modify these functions to add the * driver-specific info, such as server version, client version, etc. * That's how the various RS_MySQL_managerInfo, etc., were implemented. */ s_object * /* named list */ RS_DBI_managerInfo(Mgr_Handle *mgrHandle) { S_EVALUATOR RS_DBI_manager *mgr; s_object *output; Sint i, num_con; Sint n = (Sint) 7; char *mgrDesc[] = {"connectionIds", "fetch_default_rec","managerId", "length", "num_con", "counter", "clientVersion"}; Stype mgrType[] = {INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, CHARACTER_TYPE}; Sint mgrLen[] = {1, 1, 1, 1, 1, 1, 1}; mgr = RS_DBI_getManager(mgrHandle); num_con = (Sint) mgr->num_con; mgrLen[0] = num_con; output = RS_DBI_createNamedList(mgrDesc, mgrType, mgrLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage( "internal error: could not alloc named list", RS_DBI_ERROR); #endif for(i = 0; i < num_con; i++) LST_INT_EL(output,0,i) = (Sint) mgr->connectionIds[i]; LST_INT_EL(output,1,0) = (Sint) mgr->fetch_default_rec; LST_INT_EL(output,2,0) = (Sint) mgr->managerId; LST_INT_EL(output,3,0) = (Sint) mgr->length; LST_INT_EL(output,4,0) = (Sint) mgr->num_con; LST_INT_EL(output,5,0) = (Sint) mgr->counter; SET_LST_CHR_EL(output,6,0,C_S_CPY("NA")); /* client versions? */ return output; } /* The following should be considered templetes to be * implemented by individual drivers. */ s_object * /* return a named list */ RS_DBI_connectionInfo(Con_Handle *conHandle) { S_EVALUATOR RS_DBI_connection *con; s_object *output; Sint i; Sint n = (Sint) 8; char *conDesc[] = {"host", "user", "dbname", "conType", "serverVersion", "protocolVersion", "threadId", "rsHandle"}; Stype conType[] = {CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE}; Sint conLen[] = {1, 1, 1, 1, 1, 1, 1, -1}; con = RS_DBI_getConnection(conHandle); conLen[7] = con->num_res; /* number of resultSets opened */ output = RS_DBI_createNamedList(conDesc, conType, conLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage( "internal error in RS_DBI_connectionInfo: could not alloc named list", RS_DBI_ERROR); #endif /* dummy */ SET_LST_CHR_EL(output,0,0,C_S_CPY("NA")); /* host */ SET_LST_CHR_EL(output,1,0,C_S_CPY("NA")); /* dbname */ SET_LST_CHR_EL(output,2,0,C_S_CPY("NA")); /* user */ SET_LST_CHR_EL(output,3,0,C_S_CPY("NA")); /* conType */ SET_LST_CHR_EL(output,4,0,C_S_CPY("NA")); /* serverVersion */ LST_INT_EL(output,5,0) = (Sint) -1; /* protocolVersion */ LST_INT_EL(output,6,0) = (Sint) -1; /* threadId */ for(i=0; i < con->num_res; i++) LST_INT_EL(output,7,(Sint) i) = con->resultSetIds[i]; return output; } s_object * /* return a named list */ RS_DBI_resultSetInfo(Res_Handle *rsHandle) { S_EVALUATOR RS_DBI_resultSet *result; s_object *output, *flds; Sint n = (Sint) 6; char *rsDesc[] = {"statement", "isSelect", "rowsAffected", "rowCount", "completed", "fields"}; Stype rsType[] = {CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, LIST_TYPE}; Sint rsLen[] = {1, 1, 1, 1, 1, 1}; result = RS_DBI_getResultSet(rsHandle); if(result->fields) flds = RS_DBI_copyfields(result->fields); else flds = S_NULL_ENTRY; output = RS_DBI_createNamedList(rsDesc, rsType, rsLen, n); #ifndef USING_R if(IS_LIST(output)) output = AS_LIST(output); else RS_DBI_errorMessage( "internal error in RS_DBI_resultSetInfo: could not alloc named list", RS_DBI_ERROR); #endif SET_LST_CHR_EL(output,0,0,C_S_CPY(result->statement)); LST_INT_EL(output,1,0) = result->isSelect; LST_INT_EL(output,2,0) = result->rowsAffected; LST_INT_EL(output,3,0) = result->rowCount; LST_INT_EL(output,4,0) = result->completed; SET_ELEMENT(LST_EL(output, 5), (Sint) 0, flds); return output; } s_object * /* named list */ RS_DBI_getFieldDescriptions(RS_DBI_fields *flds) { S_EVALUATOR s_object *S_fields; Sint n = (Sint) 7; Sint lengths[7]; char *desc[]={"name", "Sclass", "type", "len", "precision", "scale","nullOK"}; Stype types[] = {CHARACTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, INTEGER_TYPE, LOGICAL_TYPE}; Sint i, j; int num_fields; num_fields = flds->num_fields; for(j = 0; j < n; j++) lengths[j] = (Sint) num_fields; PROTECT(S_fields = RS_DBI_createNamedList(desc, types, lengths, n)); #ifndef USING_R if(IS_LIST(S_fields)) S_fields = AS_LIST(S_fields); else RS_DBI_errorMessage( "internal error in RS_DBI_getFieldDescription: could not alloc named list", RS_DBI_ERROR); #endif /* copy contentes from flds into an R/S list */ for(i = 0; i < (Sint) num_fields; i++){ SET_LST_CHR_EL(S_fields,0,i,C_S_CPY(flds->name[i])); LST_INT_EL(S_fields,1,i) = (Sint) flds->Sclass[i]; LST_INT_EL(S_fields,2,i) = (Sint) flds->type[i]; LST_INT_EL(S_fields,3,i) = (Sint) flds->length[i]; LST_INT_EL(S_fields,4,i) = (Sint) flds->precision[i]; LST_INT_EL(S_fields,5,i) = (Sint) flds->scale[i]; LST_INT_EL(S_fields,6,i) = (Sint) flds->nullOk[i]; } UNPROTECT(1); return(S_fields); } /* given a type id return its human-readable name. * We define an RS_DBI_dataTypeTable */ char * RS_DBI_getTypeName(Sint t, const struct data_types table[]) { int i; char buf[128]; for (i = 0; table[i].typeName != (char *) 0; i++) { if (table[i].typeId == t) return table[i].typeName; } sprintf(buf, "unknown type (%ld)", (long) t); RS_DBI_errorMessage(buf, RS_DBI_WARNING); return (char *) 0; /* for -Wall */ } /* Translate R/S identifiers (and only R/S names!!!) into * valid SQL identifiers; overwrite input vector. Currently, * (1) translate "." into "_". * (2) first character should be a letter (traslate to "X" if not), * but a double quote signals a "delimited identifier" * (3) check that length <= 18, but only warn, since most (all?) * dbms allow much longer identifiers. * (4) SQL reserved keywords are handled in the R/S calling * function make.SQL.names(), not here. * BUG: Compound SQL identifiers are not handled properly. * Note the the dot "." is a valid SQL delimiter, used for specifying * user/table in a compound identifier. Thus, it's possible that * such compound name is mapped into a legal R/S identifier (preserving * the "."), and then we incorrectly map such delimiting "dot" into "_" * thus loosing the original SQL compound identifier. */ #define RS_DBI_MAX_IDENTIFIER_LENGTH 18 /* as per SQL92 */ s_object * RS_DBI_makeSQLNames(s_object *snames) { S_EVALUATOR long nstrings; char *name, c; char errMsg[128]; size_t len; Sint i; nstrings = (Sint) GET_LENGTH(snames); for(i = 0; i RS_DBI_MAX_IDENTIFIER_LENGTH){ (void) sprintf(errMsg,"SQL identifier %s longer than %d chars", name, RS_DBI_MAX_IDENTIFIER_LENGTH); RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } /* check for delimited-identifiers (those in double-quotes); * if missing closing double-quote, warn and treat as non-delim */ c = *name; len = strlen(name); if(c=='"' && name[len-1] =='"') continue; if(!isalpha(c) && c!='"') *name = 'X'; name++; while((c=*name)){ /* TODO: recognize SQL delim "." instances that may have * originated in SQL and R/S make.names() left alone */ if(c=='.') *name='_'; name++; } } return snames; } #ifdef USING_R /* These 2 R-specific functions are used by the C macros IS_NA(p,t) * and NA_SET(p,t) (in this way one simply use macros to test and set * NA's regardless whether we're using R or S. */ void RS_na_set(void *ptr, Stype type) { double *d; Sint *i; char *c; switch(type){ case INTEGER_TYPE: i = (Sint *) ptr; *i = NA_INTEGER; break; case LOGICAL_TYPE: i = (Sint *) ptr; *i = NA_LOGICAL; break; case NUMERIC_TYPE: d = (double *) ptr; *d = NA_REAL; break; case STRING_TYPE: c = (char *) ptr; c = (char *) CHR_EL(NA_STRING, 0); break; } } int RS_is_na(void *ptr, Stype type) { int *i, out = -2; char *c; double *d; switch(type){ case INTEGER_TYPE: case LOGICAL_TYPE: i = (int *) ptr; out = (int) ((*i) == NA_INTEGER); break; case NUMERIC_TYPE: d = (double *) ptr; out = ISNA(*d); break; case STRING_TYPE: c = (char *) ptr; out = (int) (strcmp(c, CHR_EL(NA_STRING, 0))==0); break; } return out; } #endif /* the codes come from from R/src/main/util.c */ const struct data_types RS_dataTypeTable[] = { #ifdef USING_R { "NULL", NILSXP }, /* real types */ { "symbol", SYMSXP }, { "pairlist", LISTSXP }, { "closure", CLOSXP }, { "environment", ENVSXP }, { "promise", PROMSXP }, { "language", LANGSXP }, { "special", SPECIALSXP }, { "builtin", BUILTINSXP }, { "char", CHARSXP }, { "logical", LGLSXP }, { "integer", INTSXP }, { "double", REALSXP }, /*- "real", for R <= 0.61.x */ { "complex", CPLXSXP }, { "character", STRSXP }, { "...", DOTSXP }, { "any", ANYSXP }, { "expression", EXPRSXP }, { "list", VECSXP }, { "raw", RAWSXP }, /* aliases : */ { "numeric", REALSXP }, { "name", SYMSXP }, { (char *)0, -1 } #else { "logical", LGL }, { "integer", INT }, { "single", REAL }, { "numeric", DOUBLE }, { "character", CHAR }, { "list", LIST }, { "complex", COMPLEX }, { "raw", RAW }, { "any", ANY }, { "structure", STRUCTURE }, { (char *)0, -1 } #endif }; RMySQL/src/Makevars.win640000755000175100001440000000012511703617102014607 0ustar hornikusersPKG_CPPFLAGS = -I"${MYSQL_HOME}"/include PKG_LIBS = "${MYSQL_HOME}"/bin/libmySQL.dll RMySQL/src/getopt.h0000644000175100001440000001114211705321752013623 0ustar hornikusers/* Declarations for getopt. Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if ( defined (__STDC__) && __STDC__ ) || defined(__cplusplus) || defined(MSDOS) #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (int argc, char *const *argv, const char *optstring); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ RMySQL/R/0000755000175100001440000000000011705114705011561 5ustar hornikusersRMySQL/R/MySQLSupport.R0000644000175100001440000006664711703617102014266 0ustar hornikusers## ## $Id$ ## ## Copyright (C) 1999 The Omega Project for Statistical Computing. ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either ## version 2 of the License, or (at your option) any later version. ## ## This library is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public ## License along with this library; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## "mysqlInitDriver" <- function(max.con=16, fetch.default.rec = 500, force.reload=FALSE) ## create a MySQL database connection manager. By default we allow ## up to "max.con" connections and single fetches of up to "fetch.default.rec" ## records. These settings may be changed by re-loading the driver ## using the "force.reload" = T flag (note that this will close all ## currently open connections). ## Returns an object of class "MySQLManger". ## Note: This class is a singleton. { if(fetch.default.rec<=0) stop("default num of records per fetch must be positive") config.params <- as(c(max.con, fetch.default.rec), "integer") force <- as.logical(force.reload) drvId <- .Call("RS_MySQL_init", config.params, force, PACKAGE = .MySQLPkgName) new("MySQLDriver", Id = drvId) } "mysqlCloseDriver"<- function(drv, ...) { if(!isIdCurrent(drv)) return(TRUE) drvId <- as(drv, "integer") .Call("RS_MySQL_closeManager", drvId, PACKAGE = .MySQLPkgName) } "mysqlDescribeDriver" <- function(obj, verbose = FALSE, ...) ## Print out nicely a brief description of the connection Driver { info <- dbGetInfo(obj) print(obj) cat(" Driver name: ", info$drvName, "\n") cat(" Max connections:", info$length, "\n") cat(" Conn. processed:", info$counter, "\n") cat(" Default records per fetch:", info$"fetch_default_rec", "\n") if(verbose){ cat(" DBI API version: ", dbGetDBIVersion(), "\n") cat(" MySQL client version: ", info$clientVersion, "\n") } cat(" Open connections:", info$"num_con", "\n") if(verbose && !is.null(info$connectionIds)){ for(i in seq(along = info$connectionIds)){ cat(" ", i, " ") print(info$connectionIds[[i]]) } } invisible(NULL) } "mysqlDriverInfo" <- function(obj, what="", ...) { if(!isIdCurrent(obj)) stop(paste("expired", class(obj))) drvId <- as(obj, "integer") info <- .Call("RS_MySQL_managerInfo", drvId, PACKAGE = .MySQLPkgName) ## replace drv/connection id w. actual drv/connection objects conObjs <- vector("list", length = info$"num_con") ids <- info$connectionIds for(i in seq(along = ids)) conObjs[[i]] <- new("MySQLConnection", Id = c(drvId, ids[i])) info$connectionIds <- conObjs info$managerId <- new("MySQLDriver", Id = drvId) if(!missing(what)) info[what] else info } "mysqlNewConnection" <- function(drv, dbname=NULL, username=NULL, password=NULL, host=NULL, unix.socket=NULL, port = 0, client.flag = 0, groups = 'rs-dbi', default.file = NULL) { if(!isIdCurrent(drv)) stop("expired manager") if (!is.null(dbname) && !is.character(dbname)) stop("Argument dbname must be a string or NULL") if (!is.null(username) && !is.character(username)) stop("Argument username must be a string or NULL") if (!is.null(password) && !is.character(password)) stop("Argument password must be a string or NULL") if (!is.null(host) && !is.character(host)) stop("Argument host must be a string or NULL") if (!is.null(unix.socket) && !is.character(unix.socket)) stop("Argument unix.socket must be a string or NULL") if (is.null(port) || !is.numeric(port)) stop("Argument port must be an integer value") if (is.null(client.flag) || !is.numeric(client.flag)) stop("Argument client.flag must be an integer value") if (!is.null(groups) && !is.character(groups)) stop("Argument groups must be a string or NULL") if(!is.null(default.file) && !is.character(default.file)) stop("Argument default.file must be a string") if(!is.null(default.file) && !file.exists(default.file[1])) stop(sprintf("mysql default file %s does not exist", default.file)) drvId <- as(drv, "integer") conId <- .Call("RS_MySQL_newConnection", drvId, dbname, username, password, host, unix.socket, as.integer(port), as.integer(client.flag), groups, default.file[1], PACKAGE = .MySQLPkgName) new("MySQLConnection", Id = conId) } "mysqlCloneConnection" <- function(con, ...) { if(!isIdCurrent(con)) stop(paste("expired", class(con))) conId <- as(con, "integer") newId <- .Call("RS_MySQL_cloneConnection", conId, PACKAGE = .MySQLPkgName) new("MySQLConnection", Id = newId) } "mysqlDescribeConnection" <- function(obj, verbose = FALSE, ...) { info <- dbGetInfo(obj) print(obj) cat(" User:", info$user, "\n") cat(" Host:", info$host, "\n") cat(" Dbname:", info$dbname, "\n") cat(" Connection type:", info$conType, "\n") if(verbose){ cat(" MySQL server version: ", info$serverVersion, "\n") cat(" MySQL client version: ", dbGetInfo(as(obj, "MySQLDriver"), what="clientVersion")[[1]], "\n") cat(" MySQL protocol version: ", info$protocolVersion, "\n") cat(" MySQL server thread id: ", info$threadId, "\n") } if(length(info$rsId)>0){ for(i in seq(along = info$rsId)){ cat(" ", i, " ") print(info$rsId[[i]]) } } else cat(" No resultSet available\n") invisible(NULL) } "mysqlCloseConnection" <- function(con, ...) { if(!isIdCurrent(con)) return(TRUE) rs <- dbListResults(con) if(length(rs)>0){ if(dbHasCompleted(rs[[1]])) dbClearResult(rs[[1]]) else stop("connection has pending rows (close open results set first)") } conId <- as(con, "integer") .Call("RS_MySQL_closeConnection", conId, PACKAGE = .MySQLPkgName) } "mysqlConnectionInfo" <- function(obj, what="", ...) { if(!isIdCurrent(obj)) stop(paste("expired", class(obj), deparse(substitute(obj)))) id <- as(obj, "integer") info <- .Call("RS_MySQL_connectionInfo", id, PACKAGE = .MySQLPkgName) rsId <- vector("list", length = length(info$rsId)) for(i in seq(along = info$rsId)) rsId[[i]] <- new("MySQLResult", Id = c(id, info$rsId[i])) info$rsId <- rsId if(!missing(what)) info[what] else info } "mysqlExecStatement" <- function(con, statement) ## submits the sql statement to MySQL and creates a ## dbResult object if the SQL operation does not produce ## output, otherwise it produces a resultSet that can ## be used for fetching rows. { if(!isIdCurrent(con)) stop(paste("expired", class(con))) conId <- as(con, "integer") statement <- as(statement, "character") rsId <- .Call("RS_MySQL_exec", conId, statement, PACKAGE = .MySQLPkgName) new("MySQLResult", Id = rsId) } ## helper function: it exec's *and* retrieves a statement. It should ## be named somehting else. "mysqlQuickSQL" <- function(con, statement) { if(!isIdCurrent(con)) stop(paste("expired", class(con))) nr <- length(dbListResults(con)) if(nr>0){ ## are there resultSets pending on con? new.con <- dbConnect(con) ## yep, create a clone connection on.exit(dbDisconnect(new.con)) rs <- dbSendQuery(new.con, statement) } else rs <- dbSendQuery(con, statement) if(dbHasCompleted(rs)){ dbClearResult(rs) ## no records to fetch, we're done invisible() return(NULL) } res <- fetch(rs, n = -1) if(dbHasCompleted(rs)) dbClearResult(rs) else warning("pending rows") res } "mysqlDescribeFields" <- function(res, ...) { flds <- dbGetInfo(res, "fieldDescription")[[1]][[1]] if(!is.null(flds)){ flds$Sclass <- .Call("RS_DBI_SclassNames", flds$Sclass, PACKAGE = .MySQLPkgName) flds$type <- .Call("RS_MySQL_typeNames", as.integer(flds$type), PACKAGE = .MySQLPkgName) ## no factors structure(flds, row.names = paste(seq(along=flds$type)), class = "data.frame") } else data.frame(flds) } "mysqlDBApply" <- function(res, INDEX, FUN = stop("must specify FUN"), begin = NULL, group.begin = NULL, new.record = NULL, end = NULL, batchSize = 100, maxBatch = 1e6, ..., simplify = TRUE) ## (Experimental) ## This function is meant to handle somewhat gracefully(?) large amounts ## of data from the DBMS by bringing into R manageable chunks (about ## batchSize records at a time, but not more than maxBatch); the idea ## is that the data from individual groups can be handled by R, but ## not all the groups at the same time. ## ## dbApply apply functions to groups of rows coming from a remote ## database resultSet upon the following fetching events: ## begin (prior to fetching the first record) ## group.begin (the record just fetched begins a new group) ## new_record (a new record just fetched) ## group.end (the record just fetched ends the current group) ## end (the record just fetched is the very last record) ## ## The "begin", "begin.group", etc., specify R functions to be ## invoked upon the corresponding events. (For compatibility ## with other apply functions the arg FUN is used to specify the ## most common case where we only specify the "group.end" event.) ## ## The following describes the exact order and form of invocation for the ## various callbacks in the underlying C code. All callback functions ## (except FUN) are optional. ## begin() ## group.begin(group.name) ## new.record(df.record) ## FUN(df.group, group.name, ...) (aka group.end) ## end() ## ## TODO: (1) add argument output=F/T to suppress the creation of ## an expensive(?) output list. ## (2) allow INDEX to be a list as in tapply() ## (3) add a "counter" event, to callback every k rows ## (3) should we implement a simplify argument, as in sapply()? ## (4) should it report (instead of just warning) when we're forced ## to handle partial groups (groups larger than maxBatch). ## (5) extend to the case where even individual groups are too ## big for R (as in incremental quantiles). ## (6) Highly R-dependent, not sure yet how to port it to S-plus. { if(dbHasCompleted(res)) stop("result set has completed") if(is.character(INDEX)){ flds <- tolower(as.character(dbColumnInfo(res)$name)) INDEX <- match(tolower(INDEX[1]), flds, 0) } if(INDEX<1) stop(paste("INDEX field", INDEX, "not in result set")) "null.or.fun" <- function(fun) # get fun obj, but a NULL is ok { if(is.null(fun)) fun else match.fun(fun) } begin <- null.or.fun(begin) group.begin <- null.or.fun(group.begin) group.end <- null.or.fun(FUN) ## probably this is the most important end <- null.or.fun(end) new.record <- null.or.fun(new.record) rsId <- as(res, "integer") con <- as(res, "MySQLConnection") on.exit({ rc <- dbGetException(con) if(!is.null(rc$errorNum) && rc$errorNum!=0) cat("dbApply aborted with MySQL error ", rc$errorNum, " (", rc$errorMsg, ")\n", sep = "") }) ## BEGIN event handler (re-entrant, only prior to reading first row) if(!is.null(begin) && dbGetRowCount(res)==0) begin() rho <- environment() funs <- list(begin = begin, end = end, group.begin = group.begin, group.end = group.end, new.record = new.record) out <- .Call("RS_MySQL_dbApply", rs = rsId, INDEX = as.integer(INDEX-1), funs, rho, as.integer(batchSize), as.integer(maxBatch), PACKAGE = .MySQLPkgName) if(!is.null(end) && dbHasCompleted(res)) end() out } "mysqlFetch" <- function(res, n=0, ...) ## Fetch at most n records from the opened resultSet (n = -1 means ## all records, n=0 means extract as many as "default_fetch_rec", ## as defined by MySQLDriver (see describe(drv, T)). ## The returned object is a data.frame. ## Note: The method dbHasCompleted() on the resultSet tells you whether ## or not there are pending records to be fetched. ## ## TODO: Make sure we don't exhaust all the memory, or generate ## an object whose size exceeds option("object.size"). Also, ## are we sure we want to return a data.frame? { n <- as(n, "integer") rsId <- as(res, "integer") rel <- .Call("RS_MySQL_fetch", rsId, nrec = n, PACKAGE = .MySQLPkgName) if(length(rel)==0 || length(rel[[1]])==0) return(NULL) ## create running row index as of previous fetch (if any) cnt <- dbGetRowCount(res) nrec <- length(rel[[1]]) indx <- seq(from = cnt - nrec + 1, length = nrec) attr(rel, "row.names") <- as.integer(indx) class(rel) <- "data.frame" rel } ## Note that originally we had only resultSet both for SELECTs ## and INSERTS, ... Later on we created a base class dbResult ## for non-Select SQL and a derived class resultSet for SELECTS. "mysqlResultInfo" <- function(obj, what = "", ...) { if(!isIdCurrent(obj)) stop(paste("expired", class(obj), deparse(substitute(obj)))) id <- as(obj, "integer") info <- .Call("RS_MySQL_resultSetInfo", id, PACKAGE = .MySQLPkgName) if(!missing(what)) info[what] else info } "mysqlDescribeResult" <- function(obj, verbose = FALSE, ...) { if(!isIdCurrent(obj)){ print(obj) invisible(return(NULL)) } print(obj) cat(" Statement:", dbGetStatement(obj), "\n") cat(" Has completed?", if(dbHasCompleted(obj)) "yes" else "no", "\n") cat(" Affected rows:", dbGetRowsAffected(obj), "\n") cat(" Rows fetched:", dbGetRowCount(obj), "\n") flds <- dbColumnInfo(obj) if(verbose && !is.null(flds)){ cat(" Fields:\n") out <- print(dbColumnInfo(obj)) } invisible(NULL) } "mysqlCloseResult" <- function(res, ...) { if(!isIdCurrent(res)) return(TRUE) rsId <- as(res, "integer") .Call("RS_MySQL_closeResultSet", rsId, PACKAGE = .MySQLPkgName) } "mysqlReadTable" <- function(con, name, row.names = "row_names", check.names = TRUE, ...) ## Use NULL, "", or 0 as row.names to prevent using any field as row.names. { out <- dbGetQuery(con, paste("SELECT * from", name)) if(check.names) names(out) <- make.names(names(out), unique = TRUE) ## should we set the row.names of the output data.frame? nms <- names(out) j <- switch(mode(row.names), "character" = if(row.names=="") 0 else match(tolower(row.names), tolower(nms), nomatch = if(missing(row.names)) 0 else -1), "numeric" = row.names, "NULL" = 0, 0) if(j==0) return(out) if(j<0 || j>ncol(out)){ warning("row.names not set on output data.frame (non-existing field)") return(out) } rnms <- as.character(out[,j]) if(all(!duplicated(rnms))){ out <- out[,-j, drop = FALSE] row.names(out) <- rnms } else warning("row.names not set on output (duplicate elements in field)") out } "mysqlImportFile" <- function(con, name, value, field.types = NULL, overwrite = FALSE, append = FALSE, header, row.names, nrows = 50, sep = ",", eol="\n", skip = 0, quote = '"', ...) { if(overwrite && append) stop("overwrite and append cannot both be TRUE") ## Do we need to clone the connection (ie., if it is in use)? if(length(dbListResults(con))!=0){ new.con <- dbConnect(con) ## there's pending work, so clone on.exit(dbDisconnect(new.con)) } else new.con <- con if(dbExistsTable(con,name)){ if(overwrite){ if(!dbRemoveTable(con, name)){ warning(paste("table", name, "couldn't be overwritten")) return(FALSE) } } else if(!append){ warning(paste("table", name, "exists in database: aborting dbWriteTable")) return(FALSE) } } ## compute full path name (have R expand ~, etc) fn <- file.path(dirname(value), basename(value)) if(missing(header) || missing(row.names)){ f <- file(fn, open="r") if(skip>0) readLines(f, n=skip) txtcon <- textConnection(readLines(f, n=2)) flds <- count.fields(txtcon, sep) close(txtcon) close(f) nf <- length(unique(flds)) } if(missing(header)){ header <- nf==2 } if(missing(row.names)){ if(header) row.names <- if(nf==2) TRUE else FALSE else row.names <- FALSE } new.table <- !dbExistsTable(con, name) if(new.table){ ## need to init table, say, with the first nrows lines d <- read.table(fn, sep=sep, header=header, skip=skip, nrows=nrows, ...) sql <- dbBuildTableDefinition(new.con, name, obj=d, field.types = field.types, row.names = row.names) rs <- try(dbSendQuery(new.con, sql)) if(inherits(rs, ErrorClass)){ warning("could not create table: aborting mysqlImportFile") return(FALSE) } else dbClearResult(rs) } else if(!append){ warning(sprintf("table %s already exists -- use append=TRUE?", name)) } fmt <- paste("LOAD DATA LOCAL INFILE '%s' INTO TABLE %s ", "FIELDS TERMINATED BY '%s' ", if(!is.null(quote)) "OPTIONALLY ENCLOSED BY '%s' " else "", "LINES TERMINATED BY '%s' ", "IGNORE %d LINES ", sep="") if(is.null(quote)) sql <- sprintf(fmt, fn, name, sep, eol, skip + as.integer(header)) else sql <- sprintf(fmt, fn, name, sep, quote, eol, skip + as.integer(header)) rs <- try(dbSendQuery(new.con, sql)) if(inherits(rs, ErrorClass)){ warning("could not load data into table") return(FALSE) } dbClearResult(rs) TRUE } "mysqlWriteTable" <- function(con, name, value, field.types, row.names = TRUE, overwrite = FALSE, append = FALSE, ..., allow.keywords = FALSE) ## Create table "name" (must be an SQL identifier) and populate ## it with the values of the data.frame "value" ## TODO: This function should execute its sql as a single transaction, ## and allow converter functions. ## TODO: In the unlikely event that value has a field called "row_names" ## we could inadvertently overwrite it (here the user should set ## row.names=F) I'm (very) reluctantly adding the code re: row.names, ## because I'm not 100% comfortable using data.frames as the basic ## data for relations. { if(overwrite && append) stop("overwrite and append cannot both be TRUE") if(!is.data.frame(value)) value <- as.data.frame(value) if(row.names){ value <- cbind(row.names(value), value) ## can't use row.names= here names(value)[1] <- "row.names" } if(missing(field.types) || is.null(field.types)){ ## the following mapping should be coming from some kind of table ## also, need to use converter functions (for dates, etc.) field.types <- lapply(value, dbDataType, dbObj = con) } ## Do we need to coerce any field prior to write it out? ## TODO: MySQL 4.1 introduces the boolean data type. for(i in seq(along = value)){ if(is(value[[i]], "logical")) value[[i]] <- as(value[[i]], "integer") } i <- match("row.names", names(field.types), nomatch=0) if(i>0) ## did we add a row.names value? If so, it's a text field. field.types[i] <- dbDataType(dbObj=con, field.types$row.names) names(field.types) <- make.db.names(con, names(field.types), allow.keywords = allow.keywords) ## Do we need to clone the connection (ie., if it is in use)? if(length(dbListResults(con))!=0){ new.con <- dbConnect(con) ## there's pending work, so clone on.exit(dbDisconnect(new.con)) } else { new.con <- con } if(dbExistsTable(con,name)){ if(overwrite){ if(!dbRemoveTable(con, name)){ warning(paste("table", name, "couldn't be overwritten")) return(FALSE) } } else if(!append){ warning(paste("table",name,"exists in database: aborting mysqlWriteTable")) return(FALSE) } } if(!dbExistsTable(con,name)){ ## need to re-test table for existence ## need to create a new (empty) table sql1 <- paste("create table ", name, "\n(\n\t", sep="") sql2 <- paste(paste(names(field.types), field.types), collapse=",\n\t", sep="") sql3 <- "\n)\n" sql <- paste(sql1, sql2, sql3, sep="") rs <- try(dbSendQuery(new.con, sql)) if(inherits(rs, ErrorClass)){ warning("could not create table: aborting mysqlWriteTable") return(FALSE) } else dbClearResult(rs) } ## TODO: here, we should query the MySQL to find out if it supports ## LOAD DATA thru pipes; if so, should open the pipe instead of a file. fn <- tempfile("rsdbi") fn <- gsub("\\\\", "/", fn) # Since MySQL on Windows wants \ double (BDR) safe.write(value, file = fn) on.exit(unlink(fn), add = TRUE) sql4 <- paste("LOAD DATA LOCAL INFILE '", fn, "'", " INTO TABLE ", name, " LINES TERMINATED BY '\n' ", "( ", paste(names(field.types), collapse=", "), ");", sep="") rs <- try(dbSendQuery(new.con, sql4)) if(inherits(rs, ErrorClass)){ warning("could not load data into table") return(FALSE) } else dbClearResult(rs) TRUE } "dbBuildTableDefinition" <- function(dbObj, name, obj, field.types = NULL, row.names = TRUE, ...) { if(!is.data.frame(obj)) obj <- as.data.frame(obj) if(!is.null(row.names) && row.names){ obj <- cbind(row.names(obj), obj) ## can't use row.names= here names(obj)[1] <- "row.names" } if(is.null(field.types)){ ## the following mapping should be coming from some kind of table ## also, need to use converter functions (for dates, etc.) field.types <- lapply(obj, dbDataType, dbObj = dbObj) } i <- match("row.names", names(field.types), nomatch=0) if(i>0) ## did we add a row.names value? If so, it's a text field. field.types[i] <- dbDataType(dbObj, field.types$row.names) names(field.types) <- make.db.names(dbObj, names(field.types), allow.keywords = FALSE) ## need to create a new (empty) table flds <- paste(names(field.types), field.types) paste("CREATE TABLE", name, "\n(", paste(flds, collapse=",\n\t"), "\n)") } ## the following is almost exactly from the ROracle driver "safe.write" <- function(value, file, batch, ...) ## safe.write makes sure write.table doesn't exceed available memory by batching ## at most batch rows (but it is still slowww) { N <- nrow(value) if(N<1){ warning("no rows in data.frame") return(NULL) } digits <- options(digits = 17) on.exit(options(digits)) if(missing(batch) || is.null(batch)) batch <- 10000 else if(batch<=0) batch <- N from <- 1 to <- min(batch, N) conb <- file(file,open="wb") while(from<=N){ write.table(value[from:to,, drop=FALSE], file = conb, append = TRUE, quote = FALSE, sep="\t", na = .MySQL.NA.string, row.names=FALSE, col.names=FALSE, eol = '\n', ...) from <- to+1 to <- min(to+batch, N) } close(conb) invisible(NULL) } "mysqlDataType" <- function(obj, ...) ## find a suitable SQL data type for the R/S object obj ## TODO: Lots and lots!! (this is a very rough first draft) ## need to register converters, abstract out MySQL and generalize ## to Oracle, Informix, etc. Perhaps this should be table-driven. ## NOTE: MySQL data types differ from the SQL92 (e.g., varchar truncate ## trailing spaces). MySQL enum() maps rather nicely to factors (with ## up to 65535 levels) { rs.class <- data.class(obj) ## this differs in R 1.4 from older vers rs.mode <- storage.mode(obj) if(rs.class=="numeric" || rs.class == "integer"){ sql.type <- if(rs.mode=="integer") "bigint" else "double" } else { sql.type <- switch(rs.class, character = "text", logical = "tinyint", ## but we need to coerce to int!! factor = "text", ## up to 65535 characters ordered = "text", "text") } sql.type } ## the following code was kindly provided ny J. T. Lindgren. "mysqlEscapeStrings" <- function(con, strings) { ## Escapes the given strings if(!isIdCurrent(con)) stop(paste("expired", class(con))) strings <- as(strings, "character") conId <- as(con, "integer"); out <- .Call("RS_MySQL_escapeStrings", conId, strings, PACKAGE = .MySQLPkgName) names(out) <- names(strings) out } ## For testing compiled against loaded mysql client library versions "mysqlClientLibraryVersions" <- function() { .Call("RS_MySQL_clientLibraryVersions",PACKAGE=.MySQLPkgName) } ## the following reserved words were taken from Section 6.1.7 ## of the MySQL Manual, Version 4.1.1-alpha, html format. ".MySQLKeywords" <- c("ADD", "ALL", "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "AUTO_INCREMENT", "BDB", "BEFORE", "BERKELEYDB", "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", "COLLATE", "COLUMN", "COLUMNS", "CONDITION", "CONNECTION", "CONSTRAINT", "CONTINUE", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURSOR", "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", "DAY_SECOND", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELAYED", "DELETE", "DESC", "DESCRIBE", "DISTINCT", "DISTINCTROW", "DIV", "DOUBLE", "DROP", "ELSE", "ELSEIF", "ENCLOSED", "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE", "FETCH", "FIELDS", "FLOAT", "FOR", "FORCE", "FOREIGN", "FOUND", "FROM", "FULLTEXT", "GRANT", "GROUP", "HAVING", "HIGH_PRIORITY", "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", "IGNORE", "IN", "INDEX", "INFILE", "INNER", "INNODB", "INOUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERVAL", "INTO", "IO_THREAD", "IS", "ITERATE", "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", "LIMIT", "LINES", "LOAD", "LOCALTIME", "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MASTER_SERVER_ID", "MATCH", "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "NATURAL", "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", "OUTFILE", "PRECISION", "PRIMARY", "PRIVILEGES", "PROCEDURE", "PURGE", "READ", "REAL", "REFERENCES", "REGEXP", "RENAME", "REPEAT", "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "RETURNS", "REVOKE", "RIGHT", "RLIKE", "SECOND_MICROSECOND", "SELECT", "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SMALLINT", "SOME", "SONAME", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL", "STARTING", "STRAIGHT_JOIN", "STRIPED", "TABLE", "TABLES", "TERMINATED", "THEN", "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRUE", "TYPES", "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE", "USAGE", "USE", "USER_RESOURCES", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "WHEN", "WHERE", "WHILE", "WITH", "WRITE", "XOR", "YEAR_MONTH", "ZEROFILL" ) RMySQL/R/S4R.R0000644000175100001440000000056511703617102012317 0ustar hornikusers## ## $Id$ ## ## R/S-Plus compatibility usingR <- function(major=0, minor=0){ if(is.null(version$language)) return(FALSE) if(version$language!="R") return(FALSE) version$major>=major && version$minor>=minor } ## constant holding the appropriate error class returned by try() if(usingR()){ ErrorClass <- "try-error" } else { ErrorClass <- "Error" } RMySQL/R/dbObjectId.R0000644000175100001440000000512111703617102013671 0ustar hornikusers## ## $Id$ ## ## Copyright (C) 1999-2002 The Omega Project for Statistical Computing. ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either ## version 2 of the License, or (at your option) any later version. ## ## This library is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public ## License along with this library; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ## Class: dbObjectId ## ## This mixin helper class is NOT part of the database interface definition, ## but it is extended by the Oracle, MySQL, and SQLite implementations to ## MySQLObject and OracleObject to allow us to conviniently (and portably) ## implement all database foreign objects methods (i.e., methods for show(), ## print() format() the dbManger, dbConnection, dbResultSet, etc.) ## A dbObjectId is an identifier into an actual remote database objects. ## This class and its derived classes Object need to ## be VIRTUAL to avoid coercion (green book, p.293) during method dispatching. ## ## TODO: Convert the Id slot to be an external object (as per Luke Tierney's ## implementation), even at the expense of S-plus compatibility? setClass("dbObjectId", representation(Id = "integer", "VIRTUAL")) ## coercion methods setAs("dbObjectId", "integer", def = function(from) as(slot(from,"Id"), "integer") ) setAs("dbObjectId", "numeric", def = function(from) as(slot(from, "Id"), "integer") ) setAs("dbObjectId", "character", def = function(from) as(slot(from, "Id"), "character") ) ## formating, showing, printing,... setMethod("format", "dbObjectId", def = function(x, ...) { paste("(", paste(as(x, "integer"), collapse=","), ")", sep="") }, valueClass = "character" ) setMethod("show", "dbObjectId", def = function(object) print(object)) setMethod("print", "dbObjectId", def = function(x, ...){ expired <- if(isIdCurrent(x)) "" else "Expired " str <- paste("<", expired, class(x), ":", format(x), ">", sep="") cat(str, "\n") invisible(NULL) } ) "isIdCurrent" <- function(obj) ## verify that obj refers to a currently open/loaded database { obj <- as(obj, "integer") .Call("RS_DBI_validHandle", obj, PACKAGE = .MySQLPkgName) } RMySQL/R/MySQL.R0000644000175100001440000003244011703617102012651 0ustar hornikusers## ## $Id$ ## ## Copyright (C) 1999 The Omega Project for Statistical Computing. ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License ## as published by the Free Software Foundation; either ## version 2 of the License, or (at your option) any later version. ## ## This library is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public ## License along with this library; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ## Constants ## .MySQLRCS <- "$Id$" .MySQLPkgName <- "RMySQL" ## should we set thru package.description()? .MySQLVersion <- "0.5-12" ##package.description(.MySQLPkgName, fields = "Version") .MySQL.NA.string <- "\\N" ## on input, MySQL interprets \N as NULL (NA) ## The following client flags were copied from mysql_com.h (version 4.1.13) ## but it may not make sense to set some of this from RMySQL. CLIENT_LONG_PASSWORD <- 1 # new more secure passwords CLIENT_FOUND_ROWS <- 2 # Found instead of affected rows CLIENT_LONG_FLAG <- 4 # Get all column flags CLIENT_CONNECT_WITH_DB <- 8 # One can specify db on connect CLIENT_NO_SCHEMA <- 16 # Don't allow database.table.column CLIENT_COMPRESS <- 32 # Can use compression protocol CLIENT_ODBC <- 64 # Odbc client CLIENT_LOCAL_FILES <- 128 # Can use LOAD DATA LOCAL CLIENT_IGNORE_SPACE <- 256 # Ignore spaces before '(' CLIENT_PROTOCOL_41 <- 512 # New 4.1 protocol CLIENT_INTERACTIVE <- 1024 # This is an interactive client CLIENT_SSL <- 2048 # Switch to SSL after handshake CLIENT_IGNORE_SIGPIPE <- 4096 # IGNORE sigpipes CLIENT_TRANSACTIONS <- 8192 # Client knows about transactions CLIENT_RESERVED <- 16384 # Old flag for 4.1 protocol CLIENT_SECURE_CONNECTION <- 32768 # New 4.1 authentication CLIENT_MULTI_STATEMENTS <- 65536 # Enable/disable multi-stmt support CLIENT_MULTI_RESULTS <- 131072 # Enable/disable multi-results setOldClass("data.frame") ## to appease setMethod's signature warnings... ## ## Class: DBIObject ## setClass("MySQLObject", representation("DBIObject", "dbObjectId", "VIRTUAL")) ## ## Class: dbDriver ## "MySQL" <- function(max.con=16, fetch.default.rec = 500, force.reload=FALSE) { mysqlInitDriver(max.con = max.con, fetch.default.rec = fetch.default.rec, force.reload = force.reload) } ## ## Class: DBIDriver ## setClass("MySQLDriver", representation("DBIDriver", "MySQLObject")) ## coerce (extract) any MySQLObject into a MySQLDriver setAs("MySQLObject", "MySQLDriver", def = function(from) new("MySQLDriver", Id = as(from, "integer")[1:2]) ) setMethod("dbUnloadDriver", "MySQLDriver", def = function(drv, ...) mysqlCloseDriver(drv, ...), valueClass = "logical" ) setMethod("dbGetInfo", "MySQLDriver", def = function(dbObj, ...) mysqlDriverInfo(dbObj, ...) ) setMethod("dbListConnections", "MySQLDriver", def = function(drv, ...) dbGetInfo(drv, "connectionIds")[[1]] ) setMethod("summary", "MySQLDriver", def = function(object, ...) mysqlDescribeDriver(object, ...) ) ## ## Class: DBIConnection ## setClass("MySQLConnection", representation("DBIConnection", "MySQLObject")) setMethod("dbConnect", "MySQLDriver", def = function(drv, ...) mysqlNewConnection(drv, ...), valueClass = "MySQLConnection" ) setMethod("dbConnect", "character", def = function(drv, ...) mysqlNewConnection(dbDriver(drv), ...), valueClass = "MySQLConnection" ) ## clone a connection setMethod("dbConnect", "MySQLConnection", def = function(drv, ...) mysqlCloneConnection(drv, ...), valueClass = "MySQLConnection" ) setMethod("dbDisconnect", "MySQLConnection", def = function(conn, ...) mysqlCloseConnection(conn, ...), valueClass = "logical" ) setMethod("dbSendQuery", signature(conn = "MySQLConnection", statement = "character"), def = function(conn, statement,...) mysqlExecStatement(conn, statement,...), valueClass = "MySQLResult" ) setMethod("dbGetQuery", signature(conn = "MySQLConnection", statement = "character"), def = function(conn, statement, ...) mysqlQuickSQL(conn, statement, ...) ) setMethod("dbGetException", "MySQLConnection", def = function(conn, ...){ if(!isIdCurrent(conn)) stop(paste("expired", class(conn))) .Call("RS_MySQL_getException", as(conn, "integer"), PACKAGE = .MySQLPkgName) }, valueClass = "list" ) setMethod("dbGetInfo", "MySQLConnection", def = function(dbObj, ...) mysqlConnectionInfo(dbObj, ...) ) setMethod("dbListResults", "MySQLConnection", def = function(conn, ...) dbGetInfo(conn, "rsId")[[1]] ) setMethod("summary", "MySQLConnection", def = function(object, ...) mysqlDescribeConnection(object, ...) ) ## convenience methods setMethod("dbListTables", "MySQLConnection", def = function(conn, ...){ tbls <- dbGetQuery(conn, "show tables") if(length(tbls)>0) tbls <- tbls[,1] else tbls <- character() tbls }, valueClass = "character" ) setMethod("dbReadTable", signature(conn="MySQLConnection", name="character"), def = function(conn, name, ...) mysqlReadTable(conn, name, ...), valueClass = "data.frame" ) setMethod("dbWriteTable", signature(conn="MySQLConnection", name="character", value="data.frame"), def = function(conn, name, value, ...){ mysqlWriteTable(conn, name, value, ...) }, valueClass = "logical" ) ## write table from filename (TODO: connections) setMethod("dbWriteTable", signature(conn="MySQLConnection", name="character", value="character"), def = function(conn, name, value, ...){ mysqlImportFile(conn, name, value, ...) }, valueClass = "logical" ) setMethod("dbExistsTable", signature(conn="MySQLConnection", name="character"), def = function(conn, name, ...){ ## TODO: find out the appropriate query to the MySQL metadata avail <- dbListTables(conn) if(length(avail)==0) avail <- "" match(tolower(name), tolower(avail), nomatch=0)>0 }, valueClass = "logical" ) setMethod("dbRemoveTable", signature(conn="MySQLConnection", name="character"), def = function(conn, name, ...){ if(dbExistsTable(conn, name)){ rc <- try(dbGetQuery(conn, paste("DROP TABLE", name))) !inherits(rc, ErrorClass) } else FALSE }, valueClass = "logical" ) ## return field names (no metadata) setMethod("dbListFields", signature(conn="MySQLConnection", name="character"), def = function(conn, name, ...){ flds <- dbGetQuery(conn, paste("describe", name))[,1] if(length(flds)==0) flds <- character() flds }, valueClass = "character" ) setMethod("dbCommit", "MySQLConnection", def = function(conn, ...) .NotYetImplemented() ) setMethod("dbRollback", "MySQLConnection", def = function(conn, ...) .NotYetImplemented() ) setMethod("dbCallProc", "MySQLConnection", def = function(conn, ...) .NotYetImplemented() ) ## ## Class: DBIResult ## setClass("MySQLResult", representation("DBIResult", "MySQLObject")) setAs("MySQLResult", "MySQLConnection", def = function(from) new("MySQLConnection", Id = as(from, "integer")[1:3]) ) setAs("MySQLResult", "MySQLDriver", def = function(from) new("MySQLDriver", Id = as(from, "integer")[1:2]) ) setMethod("dbClearResult", "MySQLResult", def = function(res, ...) mysqlCloseResult(res, ...), valueClass = "logical" ) setMethod("fetch", signature(res="MySQLResult", n="numeric"), def = function(res, n, ...){ out <- mysqlFetch(res, n, ...) if(is.null(out)) out <- data.frame(out) out }, valueClass = "data.frame" ) setMethod("fetch", signature(res="MySQLResult", n="missing"), def = function(res, n, ...){ out <- mysqlFetch(res, n=0, ...) if(is.null(out)) out <- data.frame(out) out }, valueClass = "data.frame" ) setMethod("dbGetInfo", "MySQLResult", def = function(dbObj, ...) mysqlResultInfo(dbObj, ...), valueClass = "list" ) setMethod("dbGetStatement", "MySQLResult", def = function(res, ...){ st <- dbGetInfo(res, "statement")[[1]] if(is.null(st)) st <- character() st }, valueClass = "character" ) setMethod("dbListFields", signature(conn="MySQLResult", name="missing"), def = function(conn, name, ...){ flds <- dbGetInfo(conn, "fields")$fields$name if(is.null(flds)) flds <- character() flds }, valueClass = "character" ) setMethod("dbColumnInfo", "MySQLResult", def = function(res, ...) mysqlDescribeFields(res, ...), valueClass = "data.frame" ) ## NOTE: The following is experimental (as suggested by Greg Warnes) setMethod("dbColumnInfo", "MySQLConnection", def = function(res, ...){ dots <- list(...) if(length(dots) == 0) stop("must specify one MySQL object (table) name") if(length(dots) > 1) warning("dbColumnInfo: only one MySQL object name (table) may be specified", call.=FALSE) dbGetQuery(res, paste("describe", dots[[1]])) }, valueClass = "data.frame" ) setMethod("dbGetRowsAffected", "MySQLResult", def = function(res, ...) dbGetInfo(res, "rowsAffected")[[1]], valueClass = "numeric" ) setMethod("dbGetRowCount", "MySQLResult", def = function(res, ...) dbGetInfo(res, "rowCount")[[1]], valueClass = "numeric" ) setMethod("dbHasCompleted", "MySQLResult", def = function(res, ...) dbGetInfo(res, "completed")[[1]] == 1, valueClass = "logical" ) setMethod("dbGetException", "MySQLResult", def = function(conn, ...){ id <- as(conn, "integer")[1:2] .Call("RS_MySQL_getException", id, PACKAGE = .MySQLPkgName) }, valueClass = "list" ## TODO: should be a DBIException? ) setMethod("summary", "MySQLResult", def = function(object, ...) mysqlDescribeResult(object, ...) ) setMethod("dbDataType", signature(dbObj = "MySQLObject", obj = "ANY"), def = function(dbObj, obj, ...) mysqlDataType(obj, ...), valueClass = "character" ) setMethod("make.db.names", signature(dbObj="MySQLObject", snames = "character"), def = function(dbObj, snames, keywords = .MySQLKeywords, unique, allow.keywords, ...){ # make.db.names.default(snames, keywords = .MySQLKeywords, unique = unique, # allow.keywords = allow.keywords) "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 } 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) # We could check to see if the database we are connected to is # running in ANSI mode. That would allow double quoted strings # as database identifiers. Until then, the backtick needs to be used. snames[kwi] <- paste("`", snames[kwi], "`", sep = "") } gsub("\\.", "_", snames) }, valueClass = "character" ) setMethod("SQLKeywords", "MySQLObject", def = function(dbObj, ...) .MySQLKeywords, valueClass = "character" ) setMethod("isSQLKeyword", signature(dbObj="MySQLObject", name="character"), def = function(dbObj, name, keywords = .MySQLKeywords, case, ...){ isSQLKeyword.default(name, keywords = .MySQLKeywords, case = case) }, valueClass = "character" ) ## extension to the DBI 0.1-4 setGeneric("dbEscapeStrings", def = function(con, strings, ...) standardGeneric("dbEscapeStrings")) setMethod("dbEscapeStrings", sig = signature(con = "MySQLConnection", strings = "character"), def = mysqlEscapeStrings, valueClass = "character" ) setMethod("dbEscapeStrings", sig = signature(con = "MySQLResult", strings = "character"), def = function(con, strings, ...) mysqlEscapeStrings(as(con, "MySQLConnection"), strings), valueClass = "character" ) setGeneric("dbApply", def = function(res, ...) standardGeneric("dbApply")) setMethod("dbApply", "MySQLResult", def = function(res, ...) mysqlDBApply(res, ...), ) setGeneric("dbMoreResults", def = function(con, ...) standardGeneric("dbMoreResults"), valueClass = "logical" ) setMethod("dbMoreResults", signature(con = "MySQLConnection"), def = function(con, ...) .Call("RS_MySQL_moreResultSets", as(con, "integer"), PACKAGE=.MySQLPkgName) ) setGeneric("dbNextResult", def = function(con, ...) standardGeneric("dbNextResult") #valueClass = "DBIResult" or NULL ) setMethod("dbNextResult", signature(con = "MySQLConnection"), def = function(con, ...){ for(rs in dbListResults(con)){ dbClearResult(rs) } id = .Call("RS_MySQL_nextResultSet", as(con, "integer"), PACKAGE=.MySQLPkgName) new("MySQLResult", Id = id) } ) RMySQL/R/zzz.R0000644000175100001440000000620611705114710012541 0ustar hornikusers## ## $Id$ ## .conflicts.OK <- TRUE .onLoad <- if(.Platform$OS.type == "windows") { # It looks in for MySQL in the following directory trees: # MYSQL_HOME, registry, %ProgramFiles%\MySQL, C:\MySQL, ..., # and C:\Apps\MySQL, ... (where ... means check other disks too) # # Thanks to Gabor Grothendieck ggrothendieck@gmail.com # function(libname, pkgname) { verbose <- TRUE dir.exists <- function(x) { !is.null(x) && file.exists(x) && file.info(x)$isdir } # check MYSQL_HOME environment variable mysql <- Sys.getenv("MYSQL_HOME") if (verbose && dir.exists(mysql)) cat("MYSQL_HOME defined as", mysql, "\n") # check registry if (!dir.exists(mysql)) { reg <- utils::readRegistry("SOFTWARE\\MySQL AB", hive="HLM", maxdepth=2) for (i in reg){ mysql <- i$Location if (dir.exists(mysql)) { if (verbose) cat(mysql, "found in registry\n") break } } } # check %ProgramFiles%:\MySQL and these # C:\MySQL, ..., C:\Apps\MySQL, ... if (!dir.exists(mysql)) { ProgramFilesMySQL <- file.path(Sys.getenv("ProgramFiles"), "MySQL") default.disks <- c("C:", "D:", "E:", "F:", "G:") default.dirs <- file.path(c("", "/xampp", "/Apps"), "MySQL") g <- with(expand.grid(disk = default.disks, dir = default.dirs), paste(disk, dir, sep = "")) lookup.paths <- c(ProgramFilesMySQL, g) if (verbose) cat("Looking in", toString(lookup.paths), "\n") mysql <- Find(dir.exists, lookup.paths) if (dir.exists(mysql) && verbose) cat("Found", mysql, "\n") # if still not found find other disks and look in them # we save this until the end since running wmic takes a bit longer if (!dir.exists(mysql)) { # wmic should exist on Vista and Win7 wmic.out <- if (nzchar(Sys.which("wmic"))) { shell("wmic logicaldisk get name", intern = TRUE) } else character(0) all.disks <- grep(":", gsub("[^[:graph:]]", "", wmic.out), value = TRUE) other.disks <- setdiff(all.disks, default.disks) more <- with(expand.grid(disk = default.disks, dir = default.dirs), paste(disk, dir, sep = "")) if (verbose) cat("Looking in", toString(more), "\n") mysql <- Find(dir.exists, more) if (verbose && dir.exists(mysql)) cat("Found", mysql, "\n") } } if (dir.exists(mysql)) { if (Sys.getenv("MYSQL_HOME")=="") { bin <- dir(path = mysql, pattern = "^bin$", recursive = TRUE, full = TRUE, ignore.case = TRUE) cwd <- getwd() setwd(bin) setwd("..") Sys.setenv(MYSQL_HOME=getwd()) setwd(cwd) } lib <- dir(path = mysql, pattern = "^libmysql.lib$", recursive = TRUE, full = TRUE, ignore.case = TRUE) dll <- dir(path = mysql, pattern = "^libmysql.dll$", recursive = TRUE, full = TRUE, ignore.case = TRUE) dll <- dirname(dll) include <- dir(path = mysql, pattern = "^include$", include.dirs = TRUE, recursive = TRUE, full = TRUE, ignore.case = TRUE) library.dynam("RMySQL", pkgname, libname, DLLpath = dll) #c(home = mysql, lib = lib, dll = dll, include = include) } else { stop("Cannot find a suitable MySQL install") } } } else { function(libname, pkgname) library.dynam("RMySQL", pkgname, libname) } RMySQL/tests/0000755000175100001440000000000011705321425012521 5ustar hornikusersRMySQL/tests/tests.R0000755000175100001440000000362711705321425014021 0ustar hornikuserslibrary(RMySQL) ## 0 dbConnect() user <- Sys.getenv("MYSQL_USER", unset = NA) password <- Sys.getenv("MYSQL_PASSWORD", unset = '') dbname <- Sys.getenv("MYSQL_DATABASE", unset = "test") drv <- dbDriver("MySQL") conn <- try(if (is.na(user)) { # in this leg user and password should be set in my.ini or my.cnf files dbConnect(drv, dbname = dbname) } else { dbConnect(drv, user = user, password = password, dbname = dbname) }) if (inherits(conn, "try-error")) { cat("unable to connect to MySQL\n") q() } ## 1 Ensure that dbWriteTable doesn't add trailing \r dbRemoveTable(conn, "myDF") # precaution ## RMySQL is not very clever: it does not convert to factor, ## and converts row names to character. myDF <- data.frame(x = paste("x", 1:5, sep = ""), y = paste("y", 1:5, sep = ""), row.names = letters[1:5], stringsAsFactors = FALSE) dbWriteTable(conn, name= "myDF", value = myDF) myDF2 <- dbReadTable(conn, "myDF") stopifnot(identical(myDF, myDF2)) dbRemoveTable(conn, "myDF") ## 2 Exercise fetch.default.rec and dbGetRowCount... along with ## dbSendQuery() and fetch() dbRemoveTable(conn, "iris") # precaution dbWriteTable(conn,name='iris',value=iris,row.names=FALSE) rso <- dbSendQuery(conn,"select * from iris where Species='versicolor'") x <- fetch(rso,n=2) rowCount <- nrow(x) stopifnot(rowCount==2) stopifnot(rowCount==dbGetRowCount(rso)) while(nrow(x)) { x <- fetch(rso) rowCount <- rowCount + nrow(x) stopifnot(rowCount==dbGetRowCount(rso)) } ## 2 Exercise dbRowsAffected() nrows <- nrow(iris[iris$Species=='versicolor',]) rso <- dbSendQuery(conn,"delete from iris where Species='versicolor'") stopifnot(nrows==dbGetRowsAffected(rso)) ## 3 Exercise dbGetQuery() stopifnot( identical( iris[iris$Species!='versicolor','Sepal.Length'], dbGetQuery(conn,'select * from iris')$Sepal_Length ) ) dbDisconnect(conn) dbUnloadDriver(drv) RMySQL/tests/tests.Rout.save0000644000175100001440000000535711705321552015506 0ustar hornikusers R version 2.14.1 (2011-12-22) Copyright (C) 2011 The R Foundation for Statistical Computing ISBN 3-900051-07-0 Platform: i486-pc-linux-gnu (32-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(RMySQL) Loading required package: DBI > > > ## 0 dbConnect() > user <- Sys.getenv("MYSQL_USER", unset = NA) > password <- Sys.getenv("MYSQL_PASSWORD", unset = '') > dbname <- Sys.getenv("MYSQL_DATABASE", unset = "test") > > drv <- dbDriver("MySQL") > > conn <- try(if (is.na(user)) { + # in this leg user and password should be set in my.ini or my.cnf files + dbConnect(drv, dbname = dbname) + } else { + dbConnect(drv, user = user, password = password, dbname = dbname) + }) > > if (inherits(conn, "try-error")) { + cat("unable to connect to MySQL\n") + q() + } > > ## 1 Ensure that dbWriteTable doesn't add trailing \r > dbRemoveTable(conn, "myDF") # precaution [1] FALSE > ## RMySQL is not very clever: it does not convert to factor, > ## and converts row names to character. > myDF <- data.frame(x = paste("x", 1:5, sep = ""), + y = paste("y", 1:5, sep = ""), + row.names = letters[1:5], + stringsAsFactors = FALSE) > dbWriteTable(conn, name= "myDF", value = myDF) [1] TRUE > myDF2 <- dbReadTable(conn, "myDF") > stopifnot(identical(myDF, myDF2)) > dbRemoveTable(conn, "myDF") [1] TRUE > > ## 2 Exercise fetch.default.rec and dbGetRowCount... along with > ## dbSendQuery() and fetch() > > dbRemoveTable(conn, "iris") # precaution [1] TRUE > dbWriteTable(conn,name='iris',value=iris,row.names=FALSE) [1] TRUE > rso <- dbSendQuery(conn,"select * from iris where Species='versicolor'") > x <- fetch(rso,n=2) > rowCount <- nrow(x) > stopifnot(rowCount==2) > stopifnot(rowCount==dbGetRowCount(rso)) > while(nrow(x)) { + x <- fetch(rso) + rowCount <- rowCount + nrow(x) + stopifnot(rowCount==dbGetRowCount(rso)) + } > > ## 2 Exercise dbRowsAffected() > nrows <- nrow(iris[iris$Species=='versicolor',]) > rso <- dbSendQuery(conn,"delete from iris where Species='versicolor'") > stopifnot(nrows==dbGetRowsAffected(rso)) > > ## 3 Exercise dbGetQuery() > stopifnot( + identical( + iris[iris$Species!='versicolor','Sepal.Length'], + dbGetQuery(conn,'select * from iris')$Sepal_Length + ) + ) > > dbDisconnect(conn) [1] TRUE > dbUnloadDriver(drv) [1] TRUE > RMySQL/inst/0000755000175100001440000000000011704070051012327 5ustar hornikusersRMySQL/inst/THANKS0000644000175100001440000000104411703617102013244 0ustar hornikusersAcknowledgements Many thanks to Christoph M. Friedrich, John Heuer, Kurt Hornik, Torsten Hothorn, Saikat Debroy, Matthew Kelly, Brian D. Ripley, Mikhail Kondrin, Jake Luciani, Jens Nieschulze, Deepayan Sarkar, Louis Springer, Duncan Temple Lang, Luis Torgo, Arend P. van der Veen, Felix Weninger, J. T. Lindgren, Crespin Miller, and Michal Okonlewski, Seth Falcon and Paul Gilbert for comments, suggestions, bug reports, and patches. Special thanks to Prof. Ripley for solving some tough Windows porting issues that had completely stumped us. RMySQL/inst/README.windows0000644000175100001440000000066311703617102014710 0ustar hornikusersRMySQL Windows Binary distribution. You need a Windows installation of MySQL 5. RMySQL should be able to find from the Windows Registry where it is, but if this fails set the environment variable MYSQL_HOME to the top level of the MySQL distribution. MySQL will need to be running. It is normally installed as a service that is started automatically, but you might need to start the service or launch a daemon process to start it. RMySQL/inst/FindMySQLhome.R0000755000175100001440000000107111703617102015076 0ustar hornikusersrequire(utils,quietly=TRUE) # Find first existing Mysql home reg <- readRegistry("SOFTWARE\\MySQL AB", hive="HLM", maxdepth=2) if (!is.null(reg)){ cat("Try setting MYSQL_HOME to one of the following (you may have to use the non-8dot3 file name):\r\n\r\n") invisible(lapply(reg,function(i){ MySQLhome <- file.path(i$Location,".") if (utils::file_test("-d",MySQLhome) && utils::file_test("-d",file.path(MySQLhome,"include")) && utils::file_test("-d",file.path(MySQLhome,"lib/opt"))){ cat(MySQLhome,"\r\n",sep='') } } )) } q(save="no") RMySQL/inst/WindowsPath.txt0000644000175100001440000000114211703617102015340 0ustar hornikusersThis is the process I used to include RMySQL's libs directory on the Windows path on Windows 2000 and Windows NT 4, Service Pack 6. NOTE: This procedure has to be done prior to invoking R. 1. Single click "My Computer" 2. Go to the environement variables: In Window 2000 Select "System Properties" -> "Advanced" Tab In Windows NT 4 Select "System "Properties" -> "Environment" 3. Click on "Environment Variables" 4. Under "User variables for dj", I added PATH=c:\R\rw1051\library\RMySQL\libs Click OK. Invoke R, > > library(RMySQL) > ... RMySQL/inst/newFunctionNames.txt0000644000175100001440000000341411703617102016360 0ustar hornikusersAs of version 0.5-0, RMySQL functions have different names as suggested by the R/S-Plus database interface DBI. prior to 0.5 DBI 0.1-4 / RMySQL 0.5-0 and later ---------------------- ---------------------------------- dbManager dbDriver dbConnect dbConnect dbExecStatement dbSendQuery dbExec dbSendQuery quickSQL dbGetQuery fetch fetch getTables dbListTables getConnections dbListConnections getResultSets dbListResults getConnection NA getFields dbColumnInfo # for a result set getFields dbListFields # for a table name in a conn getStatement dbGetStatement getRowsAffected dbGetRowsAffected getRowCount dbGetRowCount hasCompleted dbHasCompleted getInfo dbGetInfo describe summary getTableFields dbListFields getTable dbReadTable assignTable dbWriteTable existsTable dbExistsTable SQLDataType dbDataType make.SQL.name make.db.name isSQLKeyword isSQLKeyword removeTable dbRemoveTable getException dbGetException load dbDriver unload dbUnloadDriver commit dbCommit rollback dbRollback callProc dbCallProc close dbDisconnect close dbClearResult getVersion NA getCurrentDatabase NA getNumRows NA getNullOk NA getNumCols NA getDatabases NA getTableIndices NA NA dbGetDBIVersion RMySQL/inst/GPL0000644000175100001440000004311011703617102012676 0ustar hornikusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. RMySQL/inst/TODO0000644000175100001440000000554211703617102013030 0ustar hornikusersIn no particular order: * MySQL 4.1 introduces a number of enhancements that we should incorporate into RMySQL. E.g., (a) a boolean type (finally!) -- we'll need to get rid of the coercion to integers in mysqlWriteTable(). (b) prepared statements, which we could implement in RMySQL with a modest effort by mimicking the implementation in ROracle. (c) multiple sql statments per call (what we call "scripts"). For this we'll need to define in DBI a method like "nextResult" to move over a collection of result sets created by a "script". * Embedding MySQL. Add code to handle the embedded MySQL (this should be pretty easy). This does bring up a configuration issue. We may be able to easily define a macro based on which library we're linking against (libmysqlclient or libmysqld). * Transactions have been available since 4.0 (and optionally before then). We need to implement them in RMySQL. * dbApply. Move the dbApply C code into the fetch C code. Extend dbApply to work with multiple fields and report which field(s) has/have changed group. * Allow users to specify whether to transfer all the data to the MySQL client or not (say, we could add a cache=T/F argument to fetch). Currently when we execute a query we leave all the data in the MySQL server and fetch row by row. This has performance implications (dbExec returns quickly but we incur many tcp round trips), and we run the risk of the server dropping some of the output records. We could instead have the server send the entire result set to the client MySQL, and have the MySQL library (not R/Splus) cache the result set for us (this can cause a big increase in the amount of memory that R/Splus is using, although R itself is not managing the MySQL result set cache proper). Some advantages of this approach is that small and medium size result sets could be sped up quite a bit, and the R/S code that builds up the data.frame where the output goes need not be built up dynamically but in one go. * Also, we should allow the user to specify whether to lock or not the tables we're querying. * Need to add a test for libz to the configure script. * Need to look at asynchronous fetches (this brings the issue of threads and thread safety). * Move the dbApply code to it's own file dbApply.c so that we can conditionally compile RMySQL on Splus (currently we abort because I haven't abstracted out the callback mechanism). * Should the default for fetch(rs, n = 0) should be n=-1? The issue is safety (chunking) vs. convenience for small data sets). A possibility would be to set it to -1, but define an absolute threshold "max.records" that would cause to stop the fetching at that value and issue a warning message. * Benchmark batch size and exec time... RMySQL/inst/README0000644000175100001440000000230111703617102013206 0ustar hornikusers$Id$ R/S-Plus Database Interface and the MySQL driver For details, see the Adobe PDF file "DBI.pdf"" in this library directory or help(MySQL). This package implements an R/S4/Splus5+ to MySQL interface according to the RS-Database Interface specification, see http://www.omegahat.org/contrib/RS-DBI The R/S MySQL implementation can handle multiple connections to multiple MySQL servers. Basic usage: ------------ # initialize S/Splus as a MySQL client mgr <- dbDriver("MySQL") # create a connection to a MySQL server con <- dbConnect(mgr, user="user", pass="pass", host="host", dbname="database") # run a query, leave results on the server rs <- dbSendQuery(con, "select * from A_TABLE") # fetch up to, say, 50 records a.table <- fetch(rs, n = 50) # close resultSet rs and connection con dbClearResult(rs); dbDisconnect(con) Basic Methods: -------------- summary(dbObj) # prints metadata for dbObj (e.g, mgr, con, rs) dbGetInfo(dbObj) # returns a list of available metadata for dbObj dbDisconnect(con) # closes dbObj (connection or resultSet) dbClearReasults(res) dbListTables(con) dbListConnections(drv) dbListResults(con) RMySQL/inst/INSTALL0000644000175100001440000000740511704067463013403 0ustar hornikusers$Id$ 1. LINUX/MAC Installation: R CMD INSTALL [-l] RMySQL_.tar.gz During installation, RMySQL looks for the MySQL headers and libraries in the system directories. If these are not installed in system-wide directories (or if you want to use an alternate MySQL distribution), you may specify which MySQL directory(ies) to use through one of the following: 1. The shell variables PKG_CPPFLAGS and PKG_LIBS (using Bourne shell) export PKG_CPPFLAGS="-I" export PKG_LIBS="-L -lmysqlclient" For instance, on some 64 systems (e.g., Linux) you may need to set export PKG_CPPFALGS="-I/usr/include/mysql" export PKG_LIBS="-L/usr/lib64/mysql -lmysqlclient" or 2. Use the RMySQL configuration shell variables export MYSQL_INC=" export MYSQL_LIB=" You may also specify the base directory (this is the directory that has sub-directories "lib/mysql" and "include/mysql" directories) export MYSQL_DIR="" or 3. Use the --with-mysql-* RMySQL configuration arguments --with-mysql-dir= --with-mysql-inc= --with-mysql-lib= e.g., R CMD INSTALL --configure-args="--with-mysql-dir=$HOME/mysql" ... Also, besure that RMySQL can find the non-system libraries at run-time. This is typically managed by an environment variable (LD_LIBRARY_PATH or DYLD_LIBRARY_PATH for OSX) or the /etc/ld.so.cache. S/W Requirements: ----------------- MySQL client library ("libmysqlclient.so") and header files (see www.mysql.com). For Linux/intel you may use the binary rpms client+devel+shared, and make sure you also have the header files, they are *NOT* included in the following MySQL-client-4.1.7-1.i386.rpm MySQL-shared-4.1.7-1.i386.rpm but they are included in the latest 4.1.7 rpm versions. The library libz. This is a standard library on many (but not all) systems. Under Red Hat, it's included in the rpm zlib-devel. I've been told that on debian it's in the zlib1g-dev package. Testing MySQL ------------- This section is for users who wish to test RMySQL itself. Most users will not need this. To run tests in the tests directory, set MYSQL_USER, MYSQL_PASSWORD and MYSQL_DATABASE, to appropriate values. If MYSQL_USER and MYSQL_PASSWORD are missing then it assumes that user and password have been set in the MySQL option files -- typically my.cnf (or my.cnf or my.ini on Windows) but see: http://dev.mysql.com/doc/refman/5.1/en/option-files.html If MYSQL_DATABASE is unspecified it defaults to "test". 2. WINDOWS You need to have installed 'C Include Files / Lib Files' as part of your MySQL installation when installing the MySQL binary distribution. Then just set MYSQL_HOME to point to the top of the MySQL installation and install via Rcmd INSTALL in the usual way. (Note that when running MySQL, as opposed to installing it, do not need to set MYSQL_HOME if its in a place it can find such as registry, %ProgramFiles%\MySQL, C:\MySQL, C:\xampp\MySQL, C:\Apps\MySQL or the same directories on other disks.) e.g. assuming that MySQL is installed in the indicated location you might enter this into the Windows command line (not into R): set MYSQL_HOME=C:\\Program Files\\MySQL\\MySQL Server 5.1 R CMD INSTALL RMySQL_*.tar.gz where RMySQL_*.tar.gz is replaced with the source tar.gz file name. Note that unless you have MySQL in a non-standard place you only need to set MYSQL_HOME while installing it but not for running it. If its in a non-standard place where it can't find it then MYSQL_HOME should be set to run RMySQL as well. Also see the Testing MySQL under Linux/Mac above if you wish to test RMySQL itself. RMySQL/inst/doc/0000755000175100001440000000000011703617102013077 5ustar hornikusersRMySQL/inst/doc/DBI.pdf0000644000175100001440000012312511705334641014202 0ustar hornikusers%PDF-1.5 %¿÷¢þ 1 0 obj << /Type /ObjStm /Length 3058 /Filter /FlateDecode /N 73 /First 570 >> stream xœíZÝsÛ6¿¿É\d$’™NæìØN=MjŸÜµMû@Q°„†"U~Ävÿúû-J´%Ûrb·—N*Àbw±»Ø€óYÈÂ4a‚EQÂ"û>“,Ž‹Y¤,aÜ‚¥Œó?>ãæ8ga(… :éûŽ˜äØl$™ ÀT3‚>X”‡*¤H¡)ü‹$3™Ä¿B”!‡bq!$©ÕFؼŒYLôeÂâø ª˜ä‹­ÇI‚gq zØJÊ¡',…$%ÝGBþã»ï˜·Ûµ³ªfÏNGûY›³F5ìl¡rì¨lU­š–½©«nÁ~ÐÙÑ›Ñþޯϟ3ïu­²VW%Ö)ölÿ%O¹øI ŽÿÒ‚¿ÍÞ«ŸØ…nglvµPu­ÎÙ"Ë?eS°ÔÕEUO éYxÁNUa°ƒý½wgpÍ †ß³EÑè¤jÚi­Îþýö{weš¹íè¼®šê¼eè²3UVõ v\gy¡^ИnÑšýš«¦Us–WóyWêÜPî}Ý´µw­šÐÜ¢ku9·'u5ér…]M>ëEÃþi uQ¨³gÝøw•·ìþ~¯Û’Ùe¯º*Y¿;K÷<ËDº¿wDÒ|õÊj£,«¶aq|}vŠãK¿‰ùMÍ/¯i¸mÛ„¶¶‰lcQp‹ã7h£ÙØc àd5út^M÷T5UWçÐj‰xï¡+›ªž¿³9æcKÈ;^¨r7'yc˃w¨["vܵ….ËEÚS›ªwÕ?4j9m†:Н!¨¢š2ï?Z]¨úæ;,‰50ñêUÏÍþŠìO?ÿB'Æy+»¢ NIq\åŽ$ç(’î""WÉ4NÕË{gàíôÈþ<›gºh«—°=MÆÿjڬݙgílGµ³?wò)y{°\ÃGF2ãFΦÃmç{æ-Y àŠ$Ïg2jØáÏoäðšHñ„Sø$ƒ$a§ùÈ€?ÉpIrÍìH D="Én¼¤ºAºˆ ¡(€‘Sˆy"ºë"&ºˆ†.è?Ýu9]űD .=]±‘®àv¿ÑSœu’dR”âP:úO@2ÚD2LcœU$~ò$åF’ˆ&_JÕÉx#IØO)uÛÖ†6¿(Šuµuï Ì« B2å9&PlBü øïšõkøÞkD´Ñ^UL†(ƒk(Å— <­æYy;N¹ Îïß“8ϳ®ÚãvžH¼³Ýþ/»äà²}sÖRæÖAH@ìý 'Í2J®±™Ah{¡ëÙ0-lh6G6ˆÂ>‡p)ÃõpmCøÍ &k‰wønÏ<‚è¶ÌãëåÝÞÑÚÝ[™ÑMt„$Zç·{ dôz–ÕD¾¡²Ò¬^¢“ýtÝ´G•‡Y¼·W]Ræ*Þ%4y¿ËPQ].õ1Zªåm6À`Ùƒf-à®1^cØû¯ž´3:F"X ept‚ûŽŽ¸íè<¾~Sº¾ØÎ=¬Å>­œÓmÔ¸t1áz9È{¿C2kîþAÇm멇 «Äº ñ–•É£kâÞYØÅÂ.ÁAŠ{)¯óÎw!J}‰´1ÄÖ$ÌbÄ(0Y£“âÄ¡¦k¥G¦—®¹fßñÐ8Ń-÷÷·Œ=áBn°”û®`Dü0Kñ —Ì5‚Û$k³’P,žƒÊKž¦kñŽ.Z£˜.Iד¯º¸ºòåEÖ4ª!Ö+èò4&OðþÅÔ'ïS_ú—Å’¤Ë¯[b|ÏVú¸ùØ%O}ÔHËQñF|ËÒóo•Þ¦‚&¹Oz_WЬ2Õ5w/°IϨ™ä_ë·ÏI’J¯Iªï$u«Çû«ê0W5‡ËªÙ©3ZbïÔDg6¹%¤’,NMe²¡¶èVØœÓî?\b}@Q-íÆ¥eLÚtBZÔÖÔ¤#cÅÉݸ«ý¹«°¹«.¹;Üe¿<Ü­¤îøí↛õYÛ.^zÞÅÅÅÎïÙ猞ivòjî-ÌËJÛx¿Oƹ§Ë‰ºÜ™µóâáíôlûôNè³éÂVgãnN§ªÔ—;¥j½ïï½þ¶PÆÈ”^°·e »›­ÅU;ƒw­ê©×V 7^r¿€=$s2ñÍM+=,~%{“±ÞY¨º æ¾à­$¢—NøiŸžE·¼±¹[Vó«æÂXÚ¤Ê;J‰Ì[ŸgÆ¿€Czƒõ¹¹€—ü«Åeޗƪ(FE6n ›4D¼~oðLQDoÞ üΓ=L¬Ý³ z$§Gø¤­éÞôÊ7ƒÈ¾>_¾ÿ}4W»‡+Ÿ»¼è%|‡ÕLJMëDÚfyN®Ì;×ø¿Àÿuf2½YWN³º›Y‡ù· ×ó ×VÓªTØFM¡to\«Ïàb®ËŽ;™÷KžÕ„çO׺4 Õ4šnè¼iÑ¢?:Dö˜ êÌ;18«@ÈOÆn6¢n€4›Né.ܶ9]Ã¶Ï uÉ<œ>x‡®ÉÊ ôà™vº0$ uN·Êà:^‘°£}¯ÖÓºããhU91RPsÛ¶º ݶÎ&jžÕKs“ŠÃP)“x?O4}R )ª@XyW“b®Ð“$Ëê“*Çt„“ï-A½¼Z\õˆêɹ‚´u ŒpX^QMuždOÞìj1S ^«©nèÛì{žåVjZ+0K_XmyíEÕt’® Ãv†éU7Ë»–ôÚ!«(u5!›±XsdE‘Ÿr°Ìͳ&ï Ã]’˜é?º¬nIKø{–玔nÌCˆ·ëLb×ÑÝêq×Éyw%‘]c€Þîé’—‡äÀ!9"9X->rpGîhw´‚;h¡ãñc·èØ-:.:îV‹ç]ÑêEq…Awv>8 †C V+vóïgUM¦¤j±0FLeEæ@²!ŠÌ1‘­PeVLF󥘔C¢5D¢V‹µƒÓNáô N‘˜JG¼r‹*·¨.ªz Õâ‰þ¬ÍRçÖwn}7\ß­Ö]¹ùÖ éj9s«cü濹Áonð›ü?wƒö¶ìÙ~•ÎZXßsfkâëï‚izs0xNßMÚÑ£VÍ T8è Î#=Nå /зe¹½ÝÛ?¾;Z÷¨`‡OP4íï½ |ßÇœ{®·s§£ *Œºç£~´Í‹ö‹á0N²êÑ„CÊ?U UŽLÙÃÝCã]wÆÜÝ¡Üy©Ëƒá&&]™gåhÒä O(ÄpTá/÷— &L-6štãJ74ßœëW¹ ;S9tDÇ}Ö`'ê‘Ùž/úi1PÝ Hð·Ù‘ã6ë—kês=íjc$Üw{6Oˆãaß0 Ghû2Ó«J†#!‘ò#dWC:dWbÐÄÈpADCº’¢Á@LC^²Au_›?/LÒëCÄ[p}ˆØK®‡î›Õáƒ?w_®?Pâî3ÖáDÜ}źö9÷à $R_l˜ ÉúrÄ‘`!×çK¨wújÚ•’ÿì#Bmendstream endobj 75 0 obj << /Filter /FlateDecode /Length 1369 >> stream H‰ÄWKÛ6¾ûWèV²ˆñMÞº»n dÝ\²=ȶÖV`Ù†$'ØüúÎph¯7MŠ¢Z±i’óúføÍìõ|òü…+d1¿ŸH/”´EÿòRz'¤+œ³B©bÞMªb=yþòVëaR‰ª‚Íåä»â¥2–Ýì»n¿ƒµölÊKÉê±^ÔCC;³ÝØô÷ܳz™v*vǦ׳;Îÿ˜¿šH)¢ÍÆi©X…ÓN˜l<{WN³ÞÔ8Ín¹a‡fÙÖ[øm j†‘~½DGúýñ@f„7Î¥ÒŞ) Iš{®4+¹fC».W‹_†±EWÑŒ›/b¹I*@4ªˆÆë“ŠŒ„r…dWÇõ1y`Spš$Ÿ¿0i#´q,-¥Ö"ÖZa ÆZžÝT!žÝ8ðùÇIÑé$G«,Ÿ9?žH^ƨØ{kú;Ö¦ÜDe5¢?UQ*!#ŠN/,B(kÙ  ØA‰lÏKÏVÇeÚhyE¨ÒW¢|T©*ó¨R“J*SYv=ÃÄv³­a— X!–a6AOÚÚ­º×édDCÌãW¸ÂÛÒ*Š ÚS µÃì€ö”›€Š¬ o¸¬Ø@©1ÝÝÕ(Rc„WÒΗéÅr}³øØ‹³I'*mì鮉žŒ !À˜Âï¿Y|ï>!f“[à³ðÖ©T·À¿„¥~4¬iß~júÿ1¬ofKÿhXðvv.¬üËЂPÁÅo…öïCr9$ öƒûn¦Ì†ô®ŽÛÿ®ÃSæ‚#¡L —ÏÝsd¢‹!À+·ÈýD…s4{8p !j¯1ô7ðË‘D[£à£ÖP,&«óŸ/ÙÙ"ƒhö;ÜÛm;¶‰ÿƒƒëY¢ú§e>t(îØä’Cƒ4„Ô\8†cúÛ ¸à¬b+òÿ7HPÛµ@BŽÎҪݧk #c¨*t!\ºp N¦@HöŽ+®{¶?ö\j¶Lqxç–‰—p;uZ©€ß…šG »'\}µÀˆ†±¯–žPaªE ýj1hm¿¦ä9º¼oZ œÐœÕ~yìd}Ð×eO”·ä<VheËDÌÔù¡•ѽ]©I‚÷PÝ©çãíE“N>#àM“EÒz’/Ýâ>‚\²ÝúX¯ñÐD˜ÎÞ ¸Ö´)z„ðBL´¢ejÑ06`ïG ±©»@o¼EJôä-®¶¨÷˜Š 0éÛ¨‘=˜R@$<_Ç]yÖÕ;p1C'ñMƒßÃØtWÓ´ó:™De_˜ò³Í­9U¸,}$—sŒŠbkÒ óPå[5w8_`Ó̹Q!±²ÔSÁ³ä–ì¥-L‚rÐÂïqS±%A=ÐL嫌:êë(g›ý*k’g]›Õæ$õh3ž3ƒ’ÉØ!í<ÖP¶tî©é¿Eÿ©Z’¾Ÿ¸‰4¸<2àÑ ?ž¨!•²¡R~Usà¬O\…9Ê’÷ìÕÅ®Qí ~<ÃgÑ$ÐЗy¼ØïÎB^²G™?®ð'IÌN:´#[„ÐZ‹zð­@X"ëHõ¥3oPÑW‰6* _Â’Fª÷@§G<ìrOàÛÓ¢R^„ó´xâ‚M›< €\ ±ib«eß.š|ç`Èõx@c%$ªÂ»B–6T[P㦡q/é¢7by³…áþ025ÔÃÕÛ ãc‡ýÃaÛ.ÓK$STÕïË‹W“ç‡lÝ×]×îÖpSU¬½T~Ç kéDÄ?1J/\0>ñ4âŸ'€+4×_ç“?a»øç endstream endobj 76 0 obj << /Type /ObjStm /Length 1672 /Filter /FlateDecode /N 73 /First 620 >> stream xœÍYÛnÛH }ïWð±yˆ=÷Ë¢ÐÆ›n€î6HÚÅ^ÇQ[·ŽØrÓýû=”K–5Nb¸h Öeæ<䜑÷$ȇê/’4‚ ¥IÚ+ ŠŒ4Y< †\Ä;‹Á†®&xŠ^ã’¤ðxƉ‚¤R†¢$©îàÆj£ÒÚHÑ’tïI/-°ð‹ÁxÁá=ð¢ÁKÅ„Â[!IIÁO.*¹š”rüÊ@y Â’2 *`œ2ŒÑÊz”³<&’òjI Áz™M’ÈÑA3©I cØ$ÒRÁ¨¨%+'iŤIOZ[~ÂyV$m1CBm™ÌÔΦ¼ŒQ@ŽP\‚##_X2l¥TŽŒ‚éÖͶƒ?cª1‘Œå1Zq–¹•ðÞƒd2ÙÓšLdKµ!+ª1–¬<Æáî“Ú“5–DzVó˜HÖ±,#ÈzËÞ’p:ócÙÈÓÁ¬"Àˆ“Ì!,q ºHÌtÚótO®BF 8Ç:›HÎ+ÿìÅ êè_Ò¹sêÿõ÷?˜KbòùdB—Ô?ÏF%Xáz+#zN¶JW¿ ¿üü’ŽŽhÙ¬¤ç3ÌyOPÿì[É‘\I8N³¼¬¨îßËIFÏÿ̦3Œ?èFQ÷(X(gÓì+¯—&äi^N‹ëy…°Â=.æ˜whÚ4$œŒ§x„%U¡¼òYÜ,„ÛmÂ×í¼:¥ãÉp6Ëf4̯é÷¬üT\ÏÚöͯV ÔTa!6åÜÛ¼D®Pél ß¾“·å þnnòòÞ^}Ö6 5ºSBeȽý‰LÇ_³é6qz%Îl§'î¸ÈólÝ—"ÍABŠ~œ”ól6Ÿlp¸„7+{Ü–@h¹k0,‡ôî¿ÛŒ~ÞÞŽó1°D·+t¿ Ý®¡¿/Ç“q9ÎR n¶º5з·YN§³Ù|»oÆ7ãrÈx)1þ …ì×Ao1ŸŽšênä…,™È=(n‘|$§eizÑ72ϯßÊ×P4#¾{}Á%©‚>:Ââ. ??Aò\’q‚Œ¸Ôö%I¬ŸM‹ÑEÆ¢ûgƒ¨Ï^6uV{L˜p¨6)LXQ ­[g J‰¤f&_Ó‰:ßæökæ:œ I3¥“j¥›D¡|P7‹ª™ÒMHQƒE3.©™r¢ö€²²Ëë`:&#Z+ajw¢ÅÙæ9JUÌ)»ð'»ÁœYpgðtÓ z¿¡Û„ã^Ϫ ƒSK?¸Pðq(Œë@ÜoеàœMÆ ºØ¸òFT~Óm,‘Æ2ªÆBû×÷kgÜ[1f¯š™ð=áœLgíjKѹw˜jÅ^ukÁil&RK?º:ûêà;²¯ÝïJmÁ9ìdR¼)_ë†-Ôúé´nÚ™F޳¶#Ç5Áx¿â7<ºÊqQ·r§óMS÷›BZp ;¾ÔÒ–¼®©Øûmëöq-8‡­bÊ«ÒÙÚ«Âëu³1½´l3¿™®üÖs…ašÕÞ·«ý˪q» þûóÓÅ¿çŸÊòö—~†v¯w•M&‡“áÕ¬7*nªGý‹«¢ørPõr¯Šéu6…0ÖF²ðãêF.n~£þéJ5È®zKĤå÷ó«’»÷þ›qþ`uý2Ï‹ò^»n²º½LnŒÖäÞÍóÁ‚õ—ÛE±N:_‰æ’Ží%¦øîî®7÷ÊùÝ8Ë{ÃQôb3ö!C»N¾?¸8>TBÈض¹\’Ѽ®åÎV›ôŽAYS–2¶£lƒÙ4˜ov~®«ókƒé4XðuVT>¨Çúãóðë°7›çU°Š»|R ¯Í.±îPƒž=< Âîìo)qR× G £‚˜Ã ×w(1(L;[Í'€Éz'V[ùpšÕ˜ ®Q<½t˜0…7ãÑ´˜Ê*V®‡å°_\_úO§Maˬ¢À<‘bgÚTH‹‘ºÞ¤!¨ÂO,¥T• ”V»[-ÓG^4ú'â÷8ÒèŸðZ|äéFeÌŒ­7‹£9>O^ü.s˜2HÎrŒ’ný¬Ò.e¯zª#çÅPEÕÙðcÖdJîy´·ã.èG…›[ÖC÷”zØ6Ú¥ bh´§¾«;ÝÀJ×Cìöë–"Ú'uÓÃÛiÁçÕ½búqGªørïcv§J%òQsóØ.÷?*B¬×U„X¤ÒG™ýô²[âX|Zñ÷ßQî¿Æ,¾£„%ȳÿýmì±endstream endobj 150 0 obj << /Filter /FlateDecode /Length 2063 >> stream H‰ŒWÛnãÈ}÷W(Þ‡mC.ټه±eïNàÉìÚZ,‚(PdKbL‘ /– ÿž:ÕM]lO †nu×½ª«O]-.~¸ fÞl±¾ðÇ¢™KÿÌÒó}'™ÅnìÁîÂm.~øéÁ›mú Ûu\ן-ò‹¿ iÙžëºâ“eÇ¢,;å¢ÁªsÞ)‰HïÔÖ?!µ‘V›:iä³V½ÒJ£$pℵ-¶Š¤Ä©(,ÛÙ­²ÞŠ6S4¤]ukËóD–Ò¥˜_Y lóÄÒ¢o"3µY— ªÇN$†­’[de]«|(-™ˆ'(*‡È’bh@tB=·¤€ôÏÄõI‰±Âfšl)¥¿îšz°U]Ѐ#àÎlÏñRÎsr.«á•€É÷$3­²üqâq,;ñ‘T¶mUæÙP65™/ÓPŒ& >e¡©«-h S`)¤)ËóÅsÛ0!)’‰ûŽY¶Œ#ññ—O˜|oÈ4!-«r()dë¥ë‡m6ÀYWäÍn7Ö°Aб§à”Ö„»)…>-y"T^.]Wæ`’ÈQ,>?€†Â%¾tY^©8 Ä/ ˜Ë›N=üzg¶•åŠ!wSIyÎ:î@KïÊÊSYÀU/rÅ ›Èb³ÛÄ[(ûmPl.¶§Ò EÎB¥(:*‡”ÊÁs…êz®ã‡¢ƒw­2 H¨-? >)EóÈܰˆR–àkÀ·Ë°duYE_üÑT«HŠ:Œ=ˆ¥”D½³Òæ(KFZ! ³ƒžÎ¢HPjeèÔBÒšBÑLZ°íÙìÍÛ,»:0 n<[6•÷÷¹Å²¢$C¢O¹®ª[ý`.˜ôcÊ;÷ƒH0 (_o¬±ÉCFÓÙüŠ®¬ cŠ +ÈVøš ü“i!R·¶2 ]9¥PjK¿ûŽ”QH®·MÓ+½æ»‹EÛ5­êôz~…ÚÊý4íò ¹¤¹#Ð8á&¹þQP¯:°˜pI'pS}'ŠîISüÙ6ÂWs¿—_æW×—T»§h6ÒöšíZ°„Èڌˢ¯/§õØw¼&âËv_œ>1gŠÆb2¼änÉ’½ÌŒÞ}Ó=𠿝vy[n¶Sp*õ¤*#g×6ÝPRÉèe«ê´I=›, ®Íò jáκËv¨’0ŠtÄq¢žÏDžÒ$œ'NkuÞøMÑ»+ûaÁÇK—‚³øçëî«©nKUš á qù¯1{TýYªŽ]¯\SJV7ÏÄÚ³†3ÖZí¿vª«üF‚çÄi¿V~¯vÍ“:Añx%‚ØG GCŠÕï]9¨ÿmƒ©ÚršqhÇá´Lü4þÿÊ$«ªfoÒ@+ÕÙS)ÐÆ)í{w…óõN ;Õ¿®ùz”~U÷r6ërE*I)Çgr.nîn®ZÆÆ)‹ÓrWv]Ó™lœ¢ÌvæL9OM5Pÿ¤½ó._ÞÞùl¤¨f÷• íX…po3IªTþu§²~ì^ê™ð{ÿùæþæh®^ýh.ÁaãЉ&?†—ÖØð£>ø¾¬{zî¾ÿ†_îç7÷šòêoÆhŽÁ±0í÷âIurž—¿þvwÇä‹?^ˆý¶D¹ý¡Xýœõ×Í®­Ô Š%² ±ÿÆ={¯ÞóíX?žË]«!ß2çT¥ÚJ àK÷ý;xf"hó%öLJЦ¤¶É ž¾½Aü´Ñg!þcºÃáJ¼ó ÜvÊôØj¥dx3vù«¾št]©¬»çkh¢shA“xÊ>Ÿý¡O!ÎÅê·ºj²bz=èЇýæ µÁKÀABO@„! J¤aLè¼"ÐEH甎h7–÷c€+/$¸ˆ2Nù¸$N†›~ài¬szÕ¯>:{ i¶‘ÖnÄ#.£'7Z¥Œ´ŠŒX`u?ŠE£më "ô* ¢.TKÝ@a¶ð a4kœùÚÖô^aŒ|0&$ ,$¡ßzÃÇüÄtL ´^ZŽéÔAêGç•û©.4[1Â"!ÅÁ§8¤˜2d¾A‹„€|4Á7ÆÞ!©o€ƒ„õïàC åjÇNJ?bÃ5.#™î9 =ÆmŠ=ÔÍj³Èg¶Òø4hö³1„P64Kèi¨ZàkOwdòþpG¨¬<]VÜKtx²r HÇ£]oilEÇÌ@lElÖam x¤ø—f0œÈ+ä€Ê·ÙQO”6ÞFÝpžy:L hÁ¿J¿:æä5Ó±Dàèà˜Pó3ë$ûk䌜xbÌË|펆£ F¡ô8 }˜ZáÉܰB|G„Û$rO.04N9!ãf£¦Äø‘˜Ð9¹°Í4tGÕèâ<&}*àÅîâGªÆ6’¦'AIó+WQÖ™‚ñø!µ9× — íó£¨]4ùÈußiÖùVùÃI_;©Ç‡á à6 ,R¾gÀ&}i¦±À=Ì XÓó5|¾Ä2àxNº¯ÈŸO©¾í:2ÐoRIùjBó¨F‚ÄõØÈ!2“„{©¯ÃÁ·_PÒ_yj2£ØNqœ›gÔV–ÔÊhɧ©Œ‡'*/‘ÂÇ3'¤3ϽIÂe$w;êX¸’^rò$8³§ ê8V˜ÜÚf2ç+ΤIEá[©0i P(©]mˆ¬çë28II:6´VÀG’Z•r6޹8ôŒH¼išÊÃãH/=87‹‹ÿ 0• ˜“ endstream endobj 151 0 obj << /Filter /FlateDecode /Length 3197 >> stream H‰¬WËrÜÆÍz¾b*«FJ¢»ñÌNí„.)¶D&YˆY€„3/c@ÉüûœsocÑŒâJ©Äiôãö}žsûÍÕììÊÎíüêv–ÄÖÍü[ÈÈIœ§ó")b,¯gÉünvö—K;¿Ûc|ÕðÏ—™¹Nl]ý<;û>W1U\å^äèÈ–sóÉ4Ûh‘›ÍáOÛ gKºý3KÑÂ%©°àÒ ÷2,3çÑš7ï/£]ýðßÌÈ+Û” |«ÆÇIœ$ŽC÷¾­^ŸZSG‰Ù,9Π‘uæ×¨„Ʋns³r3DÞàÀºÝ {µ Ûè‰á>ˆ9`DT˜÷÷m¦YlK ”úf{ŽÇ`U{ ·…Þ èÓ×âlW˜¾Ý?pj5ì϶È×9³›|ÉÖÛ^6¬ñå=,ÆÍ)ƒdE=¹ÿ&˲*vî·ìxlbY¯ªõgG›V :Ya lbî9®EÑ¥XÝÉøî›N}ìG(ŽÇ °W…»Íí¶_×PŽŠ¹Ä\zpÝõbYõuD}Kº\Üm©.³«¾©÷ÈI§Älo~FÕ|›»]§¿ÃÝÇcGí‘>j$R¼“¬€gë;ÉjïƒQÛwÕ+ØD=.F‘»ùÂÆUUeó«sÕ蓹@X3 °/E :‡;þA]¥Inê>lX¡žÚ[\—:ËüNûœ©›#¶M7¬yÂ3Ìì£T×Û¦»F­·G¯°Íï±\ÓÙœJ+T> “ã.;@’ º¦– Ἠ>¬-u¢œ3Ÿ-wØìktFB7Àêx8UWüòÐöÐÜg4‹¢ÚÜ=À¹PÊç‰LpaÀÿûíÃDz_™N¦p,—áž›ss_÷K•Åí[BBµ Û–[¹!÷¦.µ·mßnš–§}r8ƒÕKXñ ÷ŽŸVµ ’ûvÔ“û)‘!¯þƒÔa \Š ¡ðúIÆ9JóHrÀíz¯Š\JÌǨ„z@hu¢Ò*AÀ$µàK¤Ç4µ>‡`¦% ·ï"WÁd$IÛkÍ÷geUMRQ6g6ì]Ø¢ÐÈ2ñl鯭Vms ¿-ÄS¹¹åžŒ?é$ñž?î–d¶ù˜ðÏÂVÎt’ÿšÀLn-M6î/Ÿ¤!U¹}á ÑyÕ <êÌò½Ì|eÝ¥*^ßðkûùå¼d`7JÈ’zBÙ ÛÄ,²)ëÐ)q¤tŠ£7È€ 쥇}Ô!R¥qþ\‚ʈ¾â”ëL|óË•f-É÷î•ßé˜J9¿¾}?F?ä$k<î)¸Û‰YwÌ´¤B¦ñ*v#!‘CE»Ô›”Ù$;Þ—³eàuï§Â|…Be©Ô=‘OCâ³§/´T¸»(ÍMËK¿ Ã[†ÜWG·@H~¨"K1Z!èÅÈ»X&gX §ÀŒŠÄ+á’ úš»ú:Ü(Ö“RY¸*•“€š•‚…«¬¨¾Þ­$â -â*š0áÚ9(|j0“Â<¨ºëE y¢ x6¹[z ¹]Ê_ã ÷FîXIˆ€ctÛuD€Üpæ!ä OJ½¢&¦“›ûíB£wðª0ø¡^ÒR¸úa„$ [„”^@e2x3‹8¼çI¶ô(‡ÄSUvè3¤UéÂÕíðEP‚ç.µš¦ÍÇWùÿÃ컋هٛ«¯ZNç@ÄΊ0íñõÖCšÄe–9Õj1éÿ;úÅ#@ÈÀ>8SèÚÞ„t:Ò…ZûíßÙ¥2Ìæ°oˆgÍ+}ÞÔ²¸|êËW"ÞUÉèO§®‰Ÿªéâ$-Šã®l$Oá|—¢+ØCM­¬Ä€Ç´: ¹€”g¬yh8êc¬dI’ë¾õ"´ÓIŒ~Ï?­ÜÝöa¤_¢Qÿ£ß)ÝQÖ’P­bÁ AùŠhµ2ùÂð¢Òà…4öi.q Cë}\Î=_§O3-*pÂ94xsA·§æíªÞï¥j½¸Ÿ% ¤‚Å÷-J …°ðÒ{ë…¢·¦eìÇKC›ruÏX”Ý*Ï,¡ôÌåBß>@îxf]‡.ç@¿—íc—KÀ !pj^Œ£ùyTñ›–!æhl¢ÉZáÊi—¤8¹YÊv4cÂlAˆ(³TR”Ný¡^=GVÏuØèÙoêæß‹v³¤»³"47ã'á.ró#ÂÜ×ðL˜’^¤!r¢‹-שRRKiŒŸÒvîS¸üà6»~Ë}Ÿy.<>ÜHJ#ú®YîŸc%-W‚ÆcwSDúžÒë&4w«0qx_DN3olYúÐ cª£7!öD;ÌÙc»Ãžþ¨GxùNCÒ 3@ã:oµ±£ $Žíò:Ë® e§•ÏŸúâoôã–J±VY³Ö~÷µäj.Óã­ÁG¾é-xQµ\okA"$KÁ©; ë# zÚ;…#¦/ ZkRzÍÊ$Þ‘›í tx_fz;'°Ší·zRE®ôw6[<1wƒR¤ì íy+€CͨÜQÁ*´)‹£+ŽùÿES©›ê˜¬äÿ¡¬r™‹N½örúâë_uÖ¯•B½z?669œ˜.Í?"+—y6ƒªe7JžÉs6*üyÁheõ}@Ü[·*-T³©?×£ õÄŠ+ÉÈ”þ‘êd!œá&þjPŸ©ž)iZ[)ê ¡Ž… ´'+™ZfAVéú^Ç«î†_à¨LçûǪLb›dÕ)UÂL±Qè2$v õ|9é5>‘‰>Ïå­Ë~ÈÛ64v 5ä™SŒô•öRðbÒtûvÅi`ßp?Ò:>ÎR‡·šF6NÕ R›¼¦ZqD×Dcÿ÷eL?@2ÚŒaòô—Tùi—ø~Òj¤Õz¤å§…«èÏ¥I8”Rw,k‹ ç¿…“OÐ 0»½ >Äð}Ä(’á­<Jl JOXƉOC¼øñæg>)¦}N§Ié§Mâ+]wc»–¦YqšuÞwŸáêÿ‹¬·ÛÍFzþÍyE\•Óô“Î@Ü?•Šw€/í3R?¶û‡Õ©µ¾ÊÝTØëH®ôQ"TÙëÕŠžgœ0‡Ï ˺?¸»¥[¤Ð‰¾Ÿ”jû@V#óOÍ2KƒS>aïú™ÎÄ'‰9Ÿ4ÙÙâɤÄ;¾b%cJþÒùÌ)Šz˜ú&òž-ËÐÑ{1ËmVŠžöx|røõ‹ÃÁ_ä§±øéîòûgòÏä?”WËNÃ0üŽ Ëo'Ü8òÜ£´…HU[UáÀß3³«&¨.­#?²YÏÎÎØr/ÐQ&:¸ˆMm6§ÞANÏÙª÷¬7ñ¬ceH GVv_Ÿ¨ÛÍïïéÖsZÛ"¬­§xa/[û—w³?kdï3œå”t9"ãÓ€*ñúS}P&Ïr‡)¯";›¡DÑÖ:ò1Ø:(}Ou-ñ8ÆóǶ%gz®E|¹*ñ•‡¤‹ÚCÅôþÇõüuåä©¢´ç  ÜVïÅy5ªo:?rÃ(¼ÕrX¥Fq§/±ZTÚ„ÂøÀÖCþ§EMÈF/‡éÈÅhòƒ·GnÒÆ)²R¶Äâ¥6+ž¨k°ôJ(€¡ü®‹(éævîzéI€Öx<³Ö¢6^Ÿ(c°•GÜõƒæ“7ÛÝ}ewna•"% dòSKú(¹§´UƒºžÎú¨¿2Ò÷Mr¬dÁ,»—y’6ÇØËiÆK'U{ó“ê;»F³ŸEY¢ ê.Ç}W¥]œT뇨ÄVCÃqËÈz]s B»XB¸ØÍ2ö­ÉØÍÒØ3õ§E!²Ån°Á8TlŒopx¡€ÓõáNR endstream endobj 152 0 obj << /Filter /FlateDecode /Length 3377 >> stream H‰œWIsÛF¾óWàØp™pïKæ&+ö$5®Œ#ÕÌÁò"!‰H* iGÿ>ßëÆNÉ5žr™^¿þÞ¾€gÿ~¿àÙ¯xø’ñB*Ÿ}ËÏ>dŸ>ól½xóþJd÷‡…È6ÙB8^p)3Ëea­ÉL(´÷™ðEp>kª…0ªPñ@ÂÙ̸Bð-GJJ†ÌX]8ñ ƒ®ÐA¿,Cs^xå¾#CyQx.^–Ñ)anBÈ‚)„—cŽ«ÅÅõâÍ»‰ìúna¡‰ŠÎ“–™0¾:jW8xìz»àñ¸¹ÇÃõjÁ./~¹l6_«&¿þ²øùz!)¬7ƒÄP-Î$ÎI@ cAýv¿ÛU«ãf¿káà¼6ð¿Í¶}$:J}ÆS/R‘œ9/ º'U@ˆ}O©Ïxâ=8€zp…1&£?VŒ‚DŠk/ú(:[È1X\ñªbË0rH'£â9CæïEñOÄZ>30Zr“)­Mîa8ð9‚iÏÁŠÃbîzJ=¢ØB†((¬•…AvÕ#œŽç¿¯²ÝÀÕS¾»* ¨ãÕâãÙõí³"æjüOj…Çàq 9`­¨Þ¡W€ÑÒÁ&áÖk¢àŽ´Ä£!\¶<±h@ñ^ôö‘<$Ì`]u°‹•ÖÏ\ݾ?UAXŽ3P”/$pÛS d¢ý<»Gj#Œ=Àæ £-¸1 ±„;Z–z~§^ܾZˆh 2Ék4လî)u¤xíÆJµƒŒæ^F¥„–ð8rAPÑ)c.ƒ~FH8Ò¶ã©Ïn%åAŽåµ© Ëâ<‡ïé %Ü”ÉHÒ •Qx JËRŸ]ŠÒ$§õØçelž¤¦ øÁ¼1W2OÂá*Ø‘1ó[I “H’±}¥ë Q ]«Ðg4J{ÊdºS… ºç©ç—’8ìa,®£Œü)=*Ϻ‘?Ç\É¡ÒÃÒ‰Cç·¢@ ÄD`Grê 4ŽžŒì€ÎØW ­T…ŒÓ,±Ôg—¢<-@DÆò:ʸh4õr®†‚˜º‚Ñ p7ÔÇìN’&\<Ž^O¹SÃ!”S½7ÇLÉ›ZA¾V#ßÍ.M“¥ï5ÂkD=Lz©@d‚KÝFs×r9gb'E#ˆÉï1ÔRoµ*ŽÇÙ­(𹑠¾8ÑЯ-šÅxöÓlþíö F3Íå¥À 'hfAIo\v}¹`ÿ¾¿úø¯a7X¢S-G,¿]^¼q  9>¶@]ïLÜ„C#ÎE , %)cÂÇÃ9vŸiU³iU£jIáJOíp”h6Å +ZÁ1(±¦}bïrÇ6¹e÷§¦Ê—J[&ò¥`?åK#5{› Îj—¹b‡<àÿK{ +US6«‡'P¤ew¹`û†;âðPÑxv™kvAH¿€© Z`×¹d­Dâßÿ#¡Ëøþ-‘HïOUCòµ`eÓB¯@ÞoÒ‡ô«Ö +ÏöwI•¯tÐ੬óÏ׿Â~Jƒ ù’!“#Vuyˆ 0,çd(š Är¶¦4ŽUå VIX½Ï%gß{80ÐO±ò)¾Yǚ걩"ÌîH(Ú'&a XG‰{ Õ¥c_sæR²%q=V«Í T[Ñ}Á6ÛǺÚ¯ŒÙ·”JÁrDf¦roŸä:Ú·$E2ðå¡Ê1A>Ò 46lÿ•7kú…W¥ röнkÍîNô²£h¤´è %êÍy ‘1Œb¤ä ˜HíÙ-½›²­2o,K 4Ç(aPˆñ8Tä@Óxÿµ*¢oÞÉ”ð0X‘Á“xN¿?Þ¼Ó‰×ÐD–¨ â%>ü|[ Û#S[Aôu…ý‘w€:ùï?¹Õ(Cédb:ÁW¡5PQ">&'r¡Lß}³?=âP„h#eM¤_"y.¹pÿŠLWäCÉ(/¿T6ŽÂ.(g4ûe”r±ºŒ—é¦)›º[”Üà¶Ðì/‚$k·N©¿9¥Çù‡T±lC¦•"AeË5ÊÖ Š¡¥ 4Y•uý”Äß‚J©Ñ>5åqO/M2i¯Ù‰‘eõÚì{yȶI/Ç2þ=nÊ#qÛªÖ¾”«c„¢úJþ´ä<gE? ð·ôó £‡^J®ˆ*“qìõYZ=Ó'R¿a7ù$eÐ9¾N‡¼Z<ïÀ°÷õç=Ö?/ß™3(¬s#ó;P†›0‡º¨š?ªºzº¼8t¤Û¯˜àÑ×¢áB‘¹!sVFÓ±×—’Ãî®Æ¥ô*ŠÅÃc¶4³ˆižr€rŒ²[´N} YœÒ¤Œévˆwk$ñ"Âñê<)ëV³|"FÊAêÄ—®fýc‰EHê—ífíËmäÿï Ê>ÛA´™uôÏuE§ÄÝÈmr‚HŒT*°&òœ’w #ތÆÆfbš·øåÏSÕÄÖœ¦81A—±mÐôÁßbÖ8ŒÇî#üéãO?DLÿý‰ÄÇÆ¯0ËU¬XÛ¶6Ò¾C§çÝý©#=¤‰z[ÑY¼G @¤21oã¾PÇŽ†s$fV2¾3ºPÔ©åH£Î¬6a01šckè¡ù ÷µ ƒHžé}ïì“fJD¿šVµ7XæÛj¸köÛäìKà_@‹(«, Å&ÆVivÃ6EÅ£­ö‡¼Ê kör#Pç…¯vXÉb£Ñ÷ØJŽåM^|NAÓ¤ƒŒyî]?.Û=ð:fPðp,§%…b¸ž™‹Ï'«ÏZÏݾٖÇíaÎË9¶¸ÝGREÊÅ9<ì¿Í`TpßEÁ×Óe}û¾:þ²»ÛO  >|×Mñ]f“÷^c=Å”Ýá—Ãó¯A:*ìLÉÓv[¢ä¦SÄðοŸÚWĚѬŠëTµnëÓ·¥™¨KäL‰•5ûN®Œ«Ðo•ÕúEÇ $Íd*ªnw›Yid0shŸ³H`v¹³ÆøX®þ(ï+ ®Øyîb Bɶm"ÈÒÜyNÐðÝ9²Ä:¥ÎÄÝ–TømßXÅÖ›ú®gTiÎ&Á§¶£;ÐŽŠÝ¼ÜĽ-5ŒÛÔ|b<ð1¨Cðãvð)‚Ð Wý§xÛ½ÚÎÕ·›²ë…û©ñu·N+=¯ÓÌpòåñ5ÝäipìIçÔ|£i)ÄÄ!+½V4±ìZREOÞõj úƒ+~;kbs£ñTQ+ œ|Ñvt@‹çStÐõ«”I*àPчG €ß ÔÌç{ý´Sµj©ßܰ¿`ÊŸEÄIWÛùìQðÆüð|~löëÓŠZ¯°qX —æí~·êT5PÊ (Å‘ÖLº/?ÿ7éÕ²Û( E÷ó%î")ÆÆ˜è¢R5«ÎªÝ0)#E¥ “‡4ýû9ç^CH£Ù%`lß×y˜TÓÄ*[M¨ˆbË€ ­[ßE ±ómLÏ­–:?Ï×±*g*ò¢õQ‰u`lcde&Yž&c*Ý:«€KzèEAúfòçÂð~·y9‡C`6ví¥«¿&«oiÌ.Ù ŸÜÃQ8T*ÄYŠ/YµÛመÚôíÒ¾·lÍM}–“4gòûW/ѬüHÄØg\ЖÉ"Åþ/ª8g¯T$1É«ÙI°0!,Æòóò?¦"GcÖ ó© t*©J¬èz×9¼¬]沑|Åó´Q©¹òP`ÏÌq¿³R¼µà^çã¸Ë w K1 aƒZ\È>ÉdÆ&ŒY3cÇkŒÅ;¢Æ¾Ûr"â¦ý,l‰žáFóÞ¦çZï®ÊŽWüÄ&f®Âpåå >Sô<ØNæ!ñQ\g±rSyš´ž¤ƒË´¢Ä%S4+œf <¥¶”À,Ù/dV¶BHŸéãNЯÊå®ÝšµVì‘ôå2ÒWHôŪð9“ã”Åòéä@,9Öô$Â)Aç';•Pø‚í™E¹|§M’Í0p 2ª#Ä€nFá o¦î0³»ewø2«Öáƒ@šhÙÛÓ—DHÔ*@—G²$†Y’Q*d†KÁ0]‘â2Z…ö”Ó¿mäm½zãkñšë=L ˆ­t 9€cJ M:ƒÝv$ù)ƒ_â[µ¶ Ø~IP”®zxÔšš»ëÊÿŒEÄTùñ.‡Ç‘ÎüRXÙ‹m<‰6ÙFôa›@Hù³7 …yW#zOï±R¿;%¥Ø‰ü£Ïì•b¼*Ñ|ԛɅìZìÃe<7ª=u];ª¬¤ðSæ-,*¼¨D…+ñxg6uÛòB>5ö~fÜ„i]¾ÿxzš$ö®šµà–—-‚œ¨ªÍçÚnÍo>9¥ÇÖh%Ä·.¶_eÒ»M‘tØ.µYîØwCnÛú'ß´XÞèP8)Hÿ>7à yFñðüí¯0¥" endstream endobj 153 0 obj << /Filter /FlateDecode /Length 2843 >> stream H‰¬WMsÛF½ëW¨tT‰ð|`§ö"«’hËI,Ÿ¤=€$(Ñ!.Jv~ýöëH'vÕV*&4ôLw¿~ýúêöìÕÏþ\ß.Ί´pæ\ÒáIYŸºì<—yJï×gòüáìÕ/ÕùÃÓ™L¥¤ÅÙ™øuYw¯“ÛÏdÇ;:ÍdAVn¯y›Å¶;qÝ.#Ås¢”¨Úd¢ -–‰ëDŠÍŠªuUwô[&Fà/›ú‰væZ¬Ë¯ø$3zûØ4OI!*Zñïm’‰Vž?…©/i#^h]J^¯ñ¬·‰2âaËçýçößtsonR%µÛß]³‹/e7òÐ)ã÷ÛTp±ãkHñ”X±I&VT³åâ+1Ñ>UÚfç•j™ÙþË,|¹¤/êù2Ñ…xÆó|[®È;—Qx&¯ŽÖÊɼäßD‹K¸.)Z¤éåÐ %S«è¨¡wb>ý¥ênêEs/æí3™°Îß&¶â_ÉÄI#.Öå—tÖÔu5ë–ÿ‹û$šïÏÈd#X¦^ÎDŠMŒM­V nE±sÓ„ÜPŒr¢{¤Ü!)†¼ t|ÁÝÄÈB,ØçD[äÏ^ž’\l§üÄ[Q  zÍÌ+¼š%J´Ë)Öa+ž5¯ºr¹Â>²YÎÃj³Ào†›°Õð ,¬J,„Eœ<1FQÌågwùe’ªÒ¬0Κíðë È|læÀjc˜ÅQx¬åZ‹Ê˜ÔŸ;“¥yÆÅ¶Ï2™„ý7ázOÃtÓyÁ(®¯n>L?Sx=ªìp˜r)ÎX"ñöøC|³ðö”x^Ȱî«ŒÊ Þ~Å ª&úm³Ý`#EºÄ»ÞyqM%wE1¸ÁŸj`Ô3„ñKpÔV‹Q†A ýqïqh²’‰/x]ñ^Ên„…ï ²õyjýQõ™Øì™X쟃lO½Ãa[à)/(eSàþ€pÝ-ïé:U\ 5âé *£ìÊiÙ#Õ3- XåC`Mª»€Ù¯ø§«Öi2É7xENÕU5GwtX#^LCõÑ‹°£˜V8˜‡ßö’?D[š*iÊ÷›ý9!ƒH"Uõ½øÐ–œü ÉΤø-27 |h«´öû[lÐXŸç"®9Ó£—ÜÉ$0§ s˜Ë¨lÚ†ø –óªD¿ùãPWmÙ5íˆK)‡Òä1ñóiÈû½¸˜óÃûr] q@Ÿ8bÀ=?ÞÉ·Š%È'S¨¢L,×h¬¯qû.QHoÆá¶}¸1&¥õ½­A þÉí” >©œ›!'sb±­g»FŠÍõÐ7tw?nbïØ½yF: PGýÑTDÕ™xÄQL±ÆÇÛ2%ßj‹´õàø54ð²îoÚ·ÿÞ)] œš5m[á«Mä‘™‡ÈÅ6õõC`ÜÁgB]¢CSˆšég`p¶gŒ=¤ú 3ØõçDZ:M–âZèýÞX,Gd öjnT‘ë˜ø*°¡‹&Ÿ…šÑâ…ë T« n/6´/^3;!eÔ}G]øÛ ÎŽÌ{‡ÂN¦>3ѱ;n°”²nY®–ñí ªbF:®O6Ç32@ˆåè{b8ÝàżßIY˜dY!nQ†‡ßó%vp±T£Ò´©öÖ|¿ƒ»»T…ëïÞV‹ªÅ•‰J¡ÚŒ´L¡sHµüwÄe]$73â Rb:Ô ˆT ^Aq2Íh*ûž“ÞQ½¼ `¬NÈ7OÇÊfñÇo{TŠðx˜©Ë\eš¹â®|¸¾zs”–;1ûݶ~½þÙ™"æ“ÊšŠªP¥¹UcÎÎ8[‘åz8,XŠÂëŠÐhú.\ÏðQþt"ŠU`dy1G~L(.˜cåFhú&(àQa[ï'›{f±*Ž#êɸK.E‡eú" DŠfSÕ‘³hý]÷£ÒrZ!Ç¢6¹áiÿãÛ)†V]šg§¦¼´ãÉ(^ú`xÒÒï&$›ñ‰¼»7¾ß'__!èï>’€HGt¢Aæ$`¬x»|êÞì'†ÝxA7LÓt7?ô²ÌßùßÒŒQÇ}fÝ -ƒ®lCW[­÷·Ô †TAët,¦Õ®÷<„¡ñϤ;y‡šÆ~¬²Ôoó29øèÛüˆ—B79¢¥çÑ)såšÄ¨a9 r4${ߕȹËÉáqM´½Ñqï?½};Yóìè8Tâçúâ@Gjc÷Añ³3¢nÂé@pèÐd1Ä–í4\ ñºÐüãRŽmowOMΛl‚Yîý°ƒ× çÚ±FÜn6M‹¿uFíª[nV à]ÆãxHŠs]Æé¤¥:©º-Ôæ…]‹¥bAœöŒLý`)üRu7õ¢¡˜Ò†"pîdèÔ;‘ðEÖr×ß2SÂMå'¦ÏUÌC IâÄ5š‘çfJ!_W“gH ävÕ[_7lxL U*':‰ß2ý²­¦]—»„c•d=Û›6Û.fR¦…4P¹/˜ÐÞ)Î#y`ÝŽw|Œ,87Ä@…㬻×#lgúa|bZ^lW,*–˜m¢˜¢¼ÔFâÜ¢üçV™!fXØÎ«ãü㬓ʪމŽlw1Y|ŽM¤*p3O~§**0¢¡j#YW#™úîjá„”ðÔv{Õ*.¸ý_ühï/ÌQï¿¢dlj¯Hz¼’>øi`7µRºQb•[Jÿ?AIÒS sûÃ-㹟ŽÚ¾{Æ9ˆƒ¸ë™Üh„à`z>n  ¾õ§ qàäímýÞ†wP#ªÈèô‹XC­å6¨çE¨ÐÁæk8tuƒšµñMÉÝPì#±:Öå0´$pŒ¤UTÜ¡ÂIÄÒë§K|žhXÓ‹à^ãò#ÀÈTMô?AocR•k¦Zë‹bhq¶ZR=ÿ_°{y‡ë8ZÁ{¢Å¢Šã°Ö…Öx}E:‰š‘èrŠõ¶l—<e(GŽM—ù–ƒÌ $š¹áYÄœ§Æ›"ÍSãPÒy›ÿü¡kPéÉH9ðkA4C“ñ܆K ,Ÿª@~ñn#É\~”ÕÀß¾Í$«HuÛ“E´.¿¤‡|˜Ú¢Èÿ¾²C1i€L¢ö×ÛuºêízÊó¨ö Ù“d5÷°BIôQWÍÉÕò„¬,D bº?h wbÃ]„‘‘È¥|ÝÅYÚaòŽr¼­X†&$H¨O›pzT»;á»°;b4ìæ.Ìû÷Æ‘c\Û¬bó[‡~¸·S_†1•§mc j;†aV]ÕôØàr/ì·N-{¶~cªÓôwPPÞ„CnƯj_ÑŠI•Ž´À(&ºP½$É ?ÎáM%÷„¤Àš,G¿[¾‘dûT¯šr~Í}è^\„†ôžúìE?èöò-OefbkŸ(@´bΉ›K~®Kü»Â@è³áN;", Ÿ©€E[U,Ã7«U˜-[ÎæMhͶõ¯ïŪ™•ØB2žÂX:ìDAV¤–JëuÓUÿÈE ÔX *ÌAƒ)äš«„´‘J4M õ#0]¤ 5I€Í6KPM`t](v@­ìbHA“IÒ9@­ùé™`›k”äCŒÏÌK –@Û:™@Ui°æ— ¸œ5±»¨49955Ü3:Òo5õ q ê¢)èšéû ˆ¢Ác®!\W`ÝÓ endstream endobj 154 0 obj << /Filter /FlateDecode /Length 3320 >> stream H‰”WM“Û6½Ï¯˜Ê Ü1ÄIÀ{ZÇÙ¬S¶·ÏͳФ$:©P”Çóï·_”(j&qÊe   ûõëׯïo~ü·¹•·÷«)c—¦· ý RëØÞæIÓ„ÝMr»¾ùñ—Oòv}¸Iâ$Q·÷åÍg¡c-œ3â§HŠmq8Dÿ»ÿ•Ì*oÖÄyž[2zÿæF¼yýö§®mërhº6ºÿBÓ2?ÍÅ.Ó¼¹ò{gÖÆÚbóÏâ~Ó¢…ÖJ|múáXléE)QF v2¯Æˆº-‹=ÞÑÂЧ¡Æ‡ÄŠ!ÒbSÃD.Êó)Zæü­Ãz) ?ãÍë(ï?ÝáÍÒ`"ÚÊOhŒ±ï»ÈŠ¯Ø¥©ÆMв¬ÇÃÐQ½]8$¹]ÈX:•ÂpŸñÚb×D)]d¡¤ë¯dÅ Ú]™Dô´;¿·ô…¶W;XQô>NLíèÐX•û ‘â¿ø«¸¯JS±+Úb]ïêƤ–ú¢ÅĢċŸŽ÷‡æeæ·+ã`p§3ÜN%†o·Àõ´¿Þòª¹=¯ÂÂr§27X!ýŠ·-æVøi"•ÁÁü䇎ø¡ÔèÇI?Úû™uOnWI"оÆC*V}'ްB„AÆvÛk·5?×°É[Þð¡á·5Ï¡ÁNÇûÁPâð‰¶CŒù}Íô[Á–x‡ît :ª´–ˆž°`ÿ,LœH9õ'œ“zç´„®†þ#6Nø`œc0" ù‚³h‡SJºMWÁAмV?P“àAÔfJ±|r4caÃ.s™xA§6;‡Œ)àO²ÚÆIj•ŸÿY”ÛÈJU@“öÁ5ŒhyôXÕ¯.÷"7ÆNR–Ð¥œsáRÕ2ìô ªþ+Á2Í2ÇñCVŸÉL;“‡“â”ôóxCœ/‰­&W'³”,ûº| RÂ+Qpæ“'»}Ýrb'Ì©£¤%TñƌۘTRv#H%•Þ£àÊËŠ´rYø%‹~5‡j$¯\œkŠè Ÿ§m꣖;5ú;‰½s )Î G9$æ‚þÒÉ6Îr•ÎãIž½p“Š—º1ŠüÆi•çâÓÈ¢ÊJ¡ùX1eÄô¬´ø¹(7þc…£ätº1ò'ËÅc³ÝâcðØ£TI6¨)7ð æöG_È$Î3kæùBWô±Ùú\DÁ2‰òt`àL¤áê¾®>Æãu|7º¢„JìÜ1?TK"ëú‡ ï¤1%Ù$'2žÚõ~Òh0Vtêk{‡öÒ˜ŽVî ‘+2GîT'á2ÏàÈH'p»y.Ñ}L"ç%(œâx¨ûù1²Džp¡È|Œ;Ú,g¨t|±ÄêëîIQY]~A”˜™ggôa Ž¨š~Ã' ¹©­Wav.Ë¿ŸÏˆµâÌ&é è® …u@½ƒÊ×'\”÷œ°%VF.Q~Tèy"¦”ƒ¦ô~FôÂû§O´è#éŒwØÒxñ‚:硘ó<ÈäÅ’¢‚Ý”Fîóçºp£„ ßrñ¼ :ð ‡B¥‰èV¾Œ”£.› B—›/8ýÇw/JB2–_éƒaÃ`ðÅ¢,ebÛú,f[¦q¢ûþ0ç1ÅXÏàÉœ6Íé…rqšZ;­PTË7Í¡«P®Ról¹Òqîä´\]W*"†ëJ…àuœü(©V]›?S p •Q5A;–Eϲ #ÔÂ(Ùe™-Ok×^61õ¿ß>V±4ò*#‚üãÒIüÁB ›Pô5$@wì¡” ˆá;€ÒiWïºþ)JsqçÑϳËß#¶ðÊåEY'~cÞ£ÑÀÎræÑ)·Ýº)Ñ$¨„$;]£,††ïA§y$¯lêSQ¹ÿ’ˆ2Ž·#Fð-ëºòÒHÏé+%C7Äsr…øÒsò‰\÷‘´üÓEìõ#ÈI¼çöY,8BŸRŠ…çT ÷Kn%Bé“9±$jªÌ}pb‚ üGÞì<Œ´‚éc'‘…I(Η ó-WhPFp¿¢ ólÏr}¥0(õ~«Çí0« 4W:ƒøPKqÖ„{#nU.Ã'@–Ä|kÇ`Œ¹\B`¬ÃC¹ñ‘§ãUPÅdH-‚v)™«ê“ÈÐ&³/Ðü4Ç(g×FçZZ+Ê£uM<^Œã!M»#öG̱†5•…¦º,O†ø%¹rÞ š•k-Õ¤“ Í7·Dâ{jõp+,Ø’'‘[šäYÀkTqÐT µ%®ßO~é’{¿øˆç§¡†ñ}E¦ºQ™mf$^.´*ÚÙ§Æ7Í”Ò(_iÂñ^ ì~_@0wå[ÚÓ\m¡¿ûâÜÿü£ééHs凜GSÎ âvùK=¼mWÝz™<5*žµ kOíµ''ÿ®ŠEåÑ£,Ô:е R]Q–3/Ys,É6ËFŽQѹpЬÍ*µ….1cj„¾]þµ¤#µ8O-‡ØÉ ¢Ùo@T]}ôôømÄ•N“qÞBòbè¢@òjR¯CŒJu~™vAY>Î! %†ŠÌ?°DEDòç9(™÷›q…ú" îÁÐvhxÞ¶Rok‰Ÿ/‘ ÊÒ&sÊUE<ùyˉ¹ÝItTW#ÄÄ«žtù…³3‚Ɉ¹ÅDà4+_È tò9ªU¬d¦ç;œ?S«yœäùKjõŠ˜ ÉÉ31¥pŸ%Ôÿ7ÒÊëGÝú)žz¬ Ù1C’ò¥Î…¥Å1¬ÁòÍIzbÎrb¡ðXÛ¬±×q#s/°+?4 ¤EðJš~¡ÄS²º³fN¥'%¯Ó¹j¤ÚËPíå÷Uûy^þü­¬÷Д©ú Ú¿‘Ž ¨·Àdßz­Ëu¼ÉiͰu’4Q:0,ÕÛzÇÀç%üJâ\«+ª¬ûþÃq7«4¹UsÊ|yÙífÚÊg̽?¬gu±±YúLÆ?òÙu%ؾʡþA`çôåZšù´EµpÀ©ÓéÔ ¾©|óšÔ ¹,ðCÍÙÏ*&cËçZ1òÎPxsk Q7—Н˜ ÝQUÝãÄq"'?Æî™î®®®ö¼>»ð÷¬ nwÏ»^Ý"_øVUÿ|ÓÔH¢ÀñJ¾ì0ï^GGù°Öjy ÑtÈÕÁ fè4Û«|c%6Y´~ ‰lœÝñɆޒhheýÝ0Ʋâyz©²bÍ)3öûE?\„½}Tã¯ú:Ž(±O©sÛæuªeÐLÓB{'6x8g(›=)žyûÀ…üê µl>±Û3ªR!Ž“Ò’XdŠÓx)šäÿ±=sèRåx­‡a ·Ÿ’*TèY!{¾’¦ºÆöô*.ÁÉÐöGÛê!PµòíšÎÿ/ñKÊ‹Y ΄âq¢è{ôp:!êè—}™x‡™j?ülÇ~®èuÂP³¿¥^\Çt"l†7Þ~h&ÇëÈWr· WìßÍ[&½¡ó¿É(ÕOƒVÔ“*Ø­W÷]Rºa®,Êú¾á‹©í®ë•{ݪWÔèþ¤ŠÍ¬0ò8ÙÜ_–ÖPBŠ*¤mÅ$Ÿ–|ãçá\íj/iùz–•à·I^\ùd"“iÃZ{v):‚ãØ´—nmà}ùg·ÌrXÍæÞ'O8ã#Žò9d#‘b$‚;wdÊÂD h’GÇ% =#Ê Ûž‰ZÚ¢¶ž]Ý ÞtI0FITè·:ŸšàË8ÔÎÒÀë ä8r² jñðvá5rW÷çÒ; 3a!”“±)Ò%T’–>›”À˨7˜·"ð«×1ÂÒî J"^Ö~d¢,ý˜(ÔðÃcR±3£îœ€§ J°o’TÅÙfN›Ÿ¾¾û-À¶…' endstream endobj 155 0 obj << /Filter /FlateDecode /Length 3280 >> stream H‰¬WMsÛȽëWè8H™0æp®x½N6eoÅ–¶r|€HH¤C\”ìüú¼îP@ÉvUÊe ˜ôÌt¿~ýúÍåÙËwê\ž_Þžiáôy†áIÚÅüæ,;¿;{ù÷ y~·;ËÒ,Sç—ó3±-w»‡¦]$—_`ÊS&Í3C—oñVáçáL¼ k\X“¥¹–2,š‘=I+¯Ä6™yQ&3-`8‘™hh MfV,’™ÒN\ zYíðf3Ñ-i¾Û•·Õëëä¯ÉçËžÍlê´—ç3™Eaù8ØÈÄÖ‰{ú.+DYÓVß’™,,í¨D‡Ù%=T--±¢l©ÄÝ~SÕ4‡¥×¢­ÈL™„*ü¥Sfž_É,‚©Š†•˜7u]Íidˆ–rM×ÊD•Þ¥/h¥ _µU¹‡¢ådZдtØ?Íü?tìŠwǨ ã/)~I ñ/vFFn€]vÃÕçèOûm[]')wÀÇL¥¦ÐzìM¼¹¸y¿ÚuŸªÝ~Ýí®Ù<j­iš^'ÑTć4©.Ì@¾‡¸É[–A‘‹ÛáUêµQÑê oßüN5ØÁb­¶aí•hn¾Àˆ¨V™˜# û¶E”×Àƒ–@ã¼[%Ê‹{¸¼¢Eì0‡1Ê”L%9dF•=\ꊱéèå<ìÎ8>ްë* ®âRi­_…œ:¸…‚ýãªìGôJ|(¿…oª¡q:ÏÇÆÿãýû‘qçct%V·d°G'Èx üïöôº&:#v=xXIÊådôŸ…ÿÎ8ui‰°[åàÖ&+NÞÚeâm‚œÄnv‹©ÑîbœòÔ(g‡ypHó’¥§Ã)ø¡âlŸ©®i€ (45AòýŠ=Y é.`hÇHá¬$›ÛžG:§3Og@öëèZZ$2n@+÷mFø¸ýQ‡~é¬0J½üËÙŸ^“õ°qṪ˜IA14jsñЖÛ0²¢ËZ)Vu˜)é3ʼn÷Hy$„ŒˆÀ A‡}'~"ïªWØTKðQ AmºÍzÝ<`É*AÝQR+bX£E\1~š:ÑZÜWõªªçœy±+»e³ t…Õ.¸Ãz8ݳ¹Ív½ºý¬t¼!p&škº—¡ñk|#3:5 î¢sƒ|~Äٵؔ¸€0>ÏÅ¢¤È”émBQÊ ¨tŠ¨Ø…«ÛB\ؼ„æùèŽÇîãüæ Ç;š“zImÌ¡°ÐgsÜCì=/6# 5bNQ׺ˆ•izƒâð˜zeוóåµÀ-9óž<3ã¦÷WbÓ„ZDà߸üáHŠ¢µGõ5¬‹+úÌ)Ù@`xf¶ìâ%<ªòax‡ü.DCÅñ[ð… ®ì­5W蜋¥‰ùXh_áYõ…sšž?s¬¤ˆ•j¦SkC­;ö §”øÇªî^©2“S"Æ óCE¦Ôç|f½pHÿº\SòçL\oP­?àòÚÞ]¬:Ú£š9 1ÒÑMt$-ªÊçUpB\pŠÕr…ˆ…¬ÿRùã±WLšV' ‰¶")„Ðñ Úƒ÷z<íl>5Zcš_Üü‰qX§uáÔ±Rxæ{à¦ÆúIÉXÜ\Tõâã¾j¿ ¬9Ä);¬VYâôò-#n$¶‹ ™ùÉao«n¾A¨zAÁΉŞ\S(&ZYxqññ==–h¢BÚkܸ$r %ÊÀŒö'qGÔ³J+–‡i 1y óàrÄ}EŠ…hü.ŽCTƒA›$E¢h†LÜ| óålA3eW37ôFf”Òóþ` Þ$¼é݃øK‰e’J[záÂ|8åãëªìØ#`‚’7Z›Ç#ö7¢»c£Ÿ@  ‘‹‰$m)‚¢:)F/Ë›uõ}-ªS_’÷´5úHVÆúÖVª2uNïÈBŠù²l!v¨ÒKŸAT”›øz-¶ Õ¨¾NÝP´¤W}íA Ä«¶™­«ú®[ö\$qG#Gº¥¹ •9HWŠºÇ]™j’Ò«ŠP‡e` zlµ¦uþxsò:×Cõd¨ÊlZä:fÀ)1æLq”6x§9¤I:Mz Pˆš¶f‡ø}BßÃñ„¯Æmè±ÈNFÒ¡íÔ?ÖU@Ìn"4]£-¥g‹)Ž„»e1æb~8Š^ÐMø‚eJ/Zm¢Ìrp#¸SÑxÖÁuÐÊ4~l¹#la°Ñ(í]ðÆÍ€G%5¹tcZ"ÿŒ£ãÔ$8 ‹;3¥øH’#ö™ú‘>äH‘ki5ý#¡"²KH«V‰#hó%~iÀkÖ=˜&®šž_LÎ §m]Û<¤5ƒ{X.œ“.w!>ÝÓ*Eш)ÿ„%ÄÅÂû± Œ.,Ékô¿ELÉ{7‰ÒbßÅGçÁ·!Ǻ(ÿxœm÷”³ødÁ–Jÿô¶Å)HÞx Ê“,ý$£4‘ÌÄ•MkL„#ZéÉÿÝ®ºjzt¦'kñúó@Ô¡–¦…Ísªî™”ýI,=UîËõþ™ ªc‹Cçòq$¼hcj³²GaB/¬XXÇ|!*¸Ä!AõÄ#|ÆÁ®:E«j'íô”„Q¬sÞùaü–å–`è QÞöÁ"qé='NSµsVô”Pw¡ì„ÅæÐù‚#,ú.–ÀH·!ÞõѾé$šj«Ç^i 1B/c?€cr?uÄ©j•;y+›ŠH€ k}øÁ«84[aO÷³Ï.Ô+â êŸt=íî)-1 êÝjNýšR$ƒxéVÔ+;?®PjÚ ¾:ö>lE¬ã¢«2Vûù¼ª,ð%·° ÁºéÆ2ÉPýÕÇ*‰òàׯP·»Ÿ–GF¬ùqðG.âiéuh_§–ûÔ)ó#êÄæE,`3¬‹ÙV}%Q ÜÍ ¢XÇ`ÍX&ËIÀ58MMÔÁ³ …W¼æê§u“"ò 0àÖ…;†ƒ p¥7± ¢|R°˜HÜÔZ?£p7Íýólö "%*IŠ{Ö Õ\0˜…TC,=Ò"õzÊî'BêseN*NJ„{F2S9Úª\ò4¬}6¿n•ÿ” y]øa^C”¡òu×Ð0ƒ¼v.æµwƒ¼¶nœ×$ƒÚpUˆRíåâI;Ôݾ[UëÅîç ó?Æ«¦7A ˆÞûKð ÙݱI“¦‡ÖÞ¼`ÁÔÁXMÓßy;»|ÖÄ‹a™yó>hÙÙ; cFA×°sAÑâAÐ5Ê2ª²táªÃ7¬•§F‚íÅàñ…7㷹ǒ¾a±ë]ÍM/-ò#–Ûˆ™ƒ/ÛUîÚØž$6¹+1‘:*×åØÜ™2ödw ´{¤ð)'!/KCJ)v«¦ºëçzßláB‡a…ؽgÕóÿ…ÑÞÖaØÑ½™XÖè @…EìO¥œHH(P»5¦/o:¶³âÌoJ¼&Ž÷däC_Á?®lÒ7b Îm£ ?ÚJqÊö¥E«pòƒ¿¢ê€q÷.}5…‹:*JÌ0QïÖ`ï™z$¬†p ûwM¶‘;óºc«\¶¡CÌÞé> stream H‰´WQsܶ~ׯÐ#ØñÑ@‚¤3Œ7©3IÚØÊ“”ŠÄéÎ9‘Wi9ÿ¾ßî‚wö^ü&ǬLjOQÁðÛ7Q©~ü@9`ßÈ ÊOËÆ¾¥T16œyÁJ¬)–èyûæÝ{w²إ¥ytóîö#ŽðœeqÀ@»ÂÐí(Ë­,¿þ€uƒ\Þ¤©ÚÊ@—$+á´ ×;‹‰°¬1å2Dsuœe¶xdà¾ê‰,½&®£÷½þéCäÔ;™¤ÇŸX•Fœ8…«B Û¦êÉl«ƒ“³Lâ]õ¿Ë0çÃíÙ7—$q‘»bž œµÅÿ*²j‡_úO;e©Z÷Ý=ŬDN²™…zO€z¥ê =ü‘­°Ññ6¹ÔðNä§(}FHŒúu‘ȯ,cþR²àæpʧѪ,SõM¤Õ®:,x,ó<.6O›,w±.¤ÚðAWÎ?Ê•ÂÀ«ô‚#{"Qr¢µ£<2 {z&S=)Ñ­ã@ªCÝooOo´:o´Ú„A[ä åï+ñž"ôÆ™HáKÕP aiG3kš¡<†Ë?í¾æÏ™üå¢uç++ùøíÊG[CaÇ{*žÏØ…É’!Ó‰’`Î ¬>±EEü=Õ¸LélZ¨¾ˈW­7t튇o¢'‚¼¯ˆ#¬ lÀøÜQbÐÞÞç15:Ns—-I²ó¼6iû˜ „ôüž¼¯ÅôŠLÈ9ÿÈÊcu¡—ÀcÂ~ŒQdçì÷„ p}fTÙ®kâ kÕ´d?†köJ– qJõ3”Úä;—Húw”»´¦P÷'·ƒz™¢}‘‹žø×·®#ƒ…혿3­n—ß9­Ø¬ µr(XtÇ«¿ÌÙpƒs4›€Q¾SôK ¾CÈ ) 4Jó†ÌBÔSòQ°è–=á tû†zÃÖaªqZm×r±Êî”$Å“Ø}‹v¡fô‚)†ÈY6ŸÅ €¾ÞˆCpp5=°ñ] îäœæÈ› {ÓX"¢ªL¬|!´…Çøœò5iEü)âTƒ þ•àþ˸fûiÛŒÕN$JÓ«~‚½à!ÔDúªR¡|°üZ^›% Ñ=•älÒÞíhEªåØ^6»¥€å¶ûiçÉV²/}%áô=+)\½FvÇŠp¼áœ2FK“âеñ¹yÊ5×?¿¢ÛÆø¦ãoDÓ= $õF5‹Ñ8å뉻qÚˆª»eÕÀßù ôz¡¡aIZº\RžP_Q•M¾¤98;Ã×m'¿M%e/fªp‰“-:æ"™âÞ7šË˜¥çæ²\h GT_ÿJLõؿ׆&M .gQ¾Tæ–´ç Ú3:¨ñ7°!âšÀ@ÄR±&wÜÉH Dwß{ñECÎxµÇ(Ö:Õù3ú˜Óé†EBz“2 ÒS‚8‰óÒ¤áô=þ<\àÄùE¡XÒ9ÅgǃpËèØÐ-u‘*Ñô iR™©Ïòᱹ.gÂM‹³’™ªôèwÌRtJY€Éz!C ‰s]L("œ 1€,Ã5' Z.ôd À45<’ÀE1)˜e[Ù+Íj!ä,‰†Î :ë)a™M ëÀP‰_µ>&‚Qñº¯î=ŠuZhõšf“ )#IµqB:î+Ö‹ ±ÍÜ# ßþu¥õ:×É,š¡‹eÅE5€ÛÔÁ÷{nZýÀúŠÛ°èÆK¯óÞ–×ìv¡€S3êÊ'SsN§^†šifZlœÂ‡ÿ¹!ä>pç«^óˆwTé§pnsÏa÷eˆÜ!“íH€ábËòRÿXš]h[<*e®¡T8’ðž?u\Xè¡”’ÎàìÆž„‹š¡ÌÎιêFíºš‹š›ú W„ î»ÁSP§À†ú0MZ„~ÎöŒJÉ9d²{šg@oâ$×Å£´ï(ÖΩ[é.äìCTrjµøln³\`ž wÔѵ‹ÊƲŠ;é©4æ1Ôé#…è ¡Ÿµ N“!Oº»­¸ ²h‹¨ÔÕÀ‘1¬qÁuí…ì¹aê¸éénéÁî;?¼k×Ý ÿqû‘@o<:gå±@< :p€Ì_‡\rœKŽ ,Mdª=ö>Ò?ÐÓêéšj7NØf·= "ÃXì ъñóáVâØÜ˜YË¢óóe=)©I:ò%õ¯¥ÍçYÍBrðÌ Ç20+PO眣þ¾m‡W È¥fòÈ r¿¼üz܉z"½J¢X3x.‰0 «‡Sšokÿ8¸t~­âAZ5:‡­K§‚Ÿ&…ýcñœù„â¦3V› MÐÀ*0qG Þ D I¦½T, äRªé2À”’‰;©PÝ8’ o´ -€l™’ÂØgò_=‚Ë¿ZxÁÅÆ–é<>(®‡¸ZSs6™; GqÎþ „òØŽ÷·|g—M•keòœ+›ôQT6­”q$3ë®o¢ÆÑ¹@¨mªöÎ7/$ÑO%ÑG"é—gŠB”,"2²Qö¥éÜÉù½@ÙÅà|ý\Š 9?s“Á1kn¢¥ï }ÇšÀÑW⺸îÆÿ7K·éüä6t$2BÇoŃ¡Ù3Vóå¹—A{E!W÷ÏÇ>ØJ€MuÀEîÑÙüIÀ†3!DðÔ}°š l<´žrÿIRÏõëÅŠØ¡à.ÙF®´=ÄúO‰ åt‘‹x¿#£¤ê@7Ü Õäo¿=ªz úa#²ž£šçñ]Iå‡Íy§Pä''ÍÀ\…ãî|ëûjç y8Ò@¨¡iœØìÊÜc•¹ú*ˆ¶#žçmE`±ýnœjm?&M…™¹%þÚÁŒŒ„+¤ ÍÄ@g˜ãà¡>2(ðÄ]{_o)²ÿ¦¼lr„(¼÷$°Ð…öÞ€+‚  C ·wf^±$.Ôuéôç½ò¾éå#/MOw~úÿ¦aoˆâoôgKþÅÿ+ò}ž.K¯½MhTr š,0ldßuªqˆóé…"k’ÿ%{U'Ñ€k”à%x%$-»˜í•;ãUä.0"³[\ÖòZ޼6‚ ”½wfHÑìšRÑx°Û©a= ¨ÌbÞªŽ¹Ð«Œ­˜!Y;‰lϼÚ¶K¹‹¶oÞ Íq?r¼:çên4¯‡ cÍiDvl!åLU¸Ò²!©¨\’z^Ô;µ‡—?fí‰ endstream endobj 157 0 obj << /Filter /FlateDecode /Length 3095 >> stream H‰ÄWÛnãF}÷WóÔ\D4ûÂÛÌÃ"sK²ÈÌc/öÁÎMQ²²)P”=þû=§º©«'ƒ,‚xZd³»êTÕ©Soo.®>f—úòfvQÆef/üçW:-âÌ]æIãýê"¹œ_\ýt­/盋$N{yS_ܪ¾ÙD¹ÚF«–þZ«ø ‰´~ÀoWªªba ÕTõƒ_ÕÝr»j±Ö™Zð_—¨á¡áK§¸[UCÏújÅgÚÈ™Ýv9õßȹ¹î÷á» w¶þ|.ùv-ûjf´êf4°”›~»ù\šèØ$.½¼y£?p&gLŠ‹›°¸KÕÐãru§¢‰“§»G-?¬°V«h’¬€±F 0虯×ü³{ãœ_u|‰MW 1.KŒØ¼5íS?/Úáutóû>n&vFk„-ìsÞ¢ià,mšQªv€“3x´cÛ ŸiUÃ?`ŒçüÈjµÀ²­eã´ æí$Ü #˲LÇÛX9[“¸åebªóߤØZ¤ÁTnÄŸ§ uìOοéV½ûéšøëc¤—ÕýÇå›Ë2œ 3Z–eù’eÃóú;–ýQ ¿•J dB0AhL :«=4â6Dè”ÿÁuúr&³L_(ÞR«• ™—ž}­ŽqÊYÎQ²ã€Lí<¸iL¬S}š:Ÿÿõë¯'žYØ6Á>]x?YD Ì™è\M|€Ll$nº4îÄï­8ö&lÜ!<²ó-ó#SÛO«nÀ‘“<Òª_D6AÈ´á4)îe#-IIZ()óP¡0•¬â“–/g]¿ªx(Ÿtm|Þ.Jk_lH­ûëfxÊúT­×‹v¾¹S³åtƒ¼J‘Wq¼oŽ!3tFÒØc6Ħœ1¥áË…¬ÛŠ—8^‡£²1É@ýnÇl§Ÿ-0üÔø‡yÑF9…"§§Ì §L4ð^ôÆðÔ4|£6Û9]Æ6)Îj+Än ¡o¥À wÐZÀ³Ó©ùHªŒcéöe ëèØ&¹$­PBd„øÖ1ê7ÍÕ¿#0k£oœúºµD Fî÷¸W¸¦™EPc•ˆ„°oŘI)Ѥ”ÊHn:ÐXÈÖôßkRa3Y¡ gpL–áT'œ„ÇM/¿dÍjL3°R´êÃþ‡°cEû:†ƒ†eÚkµ’K ´ºV#É*µ8‚GdkØ-ëQºötÅñð*¼n›fêo_u}¸±%ôàäs-¹¬PˆM¬ghßÔgÏž^*üyœðA¦æMÛôx¡èÀf3PN×sGg 1SªG¡û­dOnvt&\2%m9 -,èq¨°Ç.®eæƒÈÌ•B«[lºyðÍFÓ$ôµ@pó7øKœÅ LjÛ Ï{ô^LIä”$³å‚ÿÖøíX£¶Aù1}ŽtBL0ae[”4ˆB« ò—g~Io9þxâ§BYà}›&Ì"'Jݦ…ÄêNÕcÓ.ÂÙmÍ·yŽÄlÄ›ŽÚÔÊý’!6•úÍÕ×È?í™^U^ÉbQWh’6µÞ’™|…ò‘‡Hf›•þ‚&04;,'L+Þz+nGw/ǺûßéC~Þ§ÁL)¤D\’—¡Àÿ/íâsé(T„¤¿c!Ê(3îõx¹ÿìzÁü¤¢S—;µ×¨÷?5Ã/í¬»cñKK a»gé'g¡³³îRà¹ä/êäÔ $bïc‹GHÔA Ù·Â<Î3§Oë3õgú˜oƒ£a¢“æ…Úýô´mÁ롦;ÎŽlY饖å ]Ý_Ù²úfØömhX¤QÖ»zI!½D…ò‰¸{«¹Ã³Z¤¨.²Ãf÷|ŒåÛnYºãD–{Á,dòA: ‡ ŸãYµXÅE§êî•Ñ(…DüÊs8*x/!·ËádN öçB}$¢tœ—.?ÔŠññ`€þ›:ÿ¦A$¿tO›g3L3Ýó›úÃ$Iþ—DÓí¢ fÝ õKP3½“²:/ö44<‚§…Ë»ÈT ‚½V:Ë,2Nº ¤1 !-â<ÉΪ#¤Ôý³ï!@ ›£ÉA-Ô[Hk|JíòÉXæÓhžÑͳ4/ ’]/]fN¥É/œ&sbùtÁ&¶{.f¿î™qò\ûn=Ôñ©ö~Ao2Ê?W›wÝj-·ýÿê՜իˆ;tËn¾¨«¥±W\-Ðæk 6sÄ¡v?-Ê1‚·û€ukН´ª"(#':Ú½ÈTÆ·A!ØI ƒ&žÇýŠš(¨ÞÜøVî#Õ‡«ÎB;J9çöRÎ%’¨è¤õC3ýû×~#p¾<ßuÛïó¬èÿMi¦˜Æ’⻥i‘ãciZtÃ1÷-Rv,M‹aê´4­M|EòcÂÁm¹¯n[›”æpÅ¥0"Θ5ÞQÑŸ¥¯Ë`zr–ÚÚ¸¸4y——7+N(sÇc̲0GŠôóô.TU†ŸB¾zíüIöȤÆÅæ´2.3+ûU¸7uqÎ{p¼“Ñbœq¬;œq¬ó¢x»^wý8& îùåuª¸¯Dº€+¦'Ï”"¿… ‘Äd+k’½®ZØ¡>Þ}úmûFe/¿xaXq$³¶Ä(–aâ8n9ŸB4š£ÚTL¢…Ê·Ì©Xú~d">¹3Æ™uÏïV¬°…HyŠOÎG„ûÕ‡>ØD]?ÂÍ—L׊Ïçü9ëz0@ÐO_sz´êÇ–§>{ƒv‰n‹_®³iðvS¾ŠqS?›xè°x$BUÿ<Á w ÿ¹‘ótJåû{NQz—dÒû0ì\!ºÒcÐyŒ¿ ©]áçõ‰vuqêŠSéúªö6ý«#’ÅÙN$ ²Ü'zü1r%gWð6MÈ…®dâ;XÔ•4®È¿1H®{?<2:üW³Zm×N~ùðáƒ(.ÄÚÓp¼õéo2ësbtºL`§Ë,XÇ”ñ‰E$3ØØmï÷p"xô¡NŸ#+š~QãC —™3a/–ç4EºˆI9Ç ¥Úù™„òû¹¶ª¼$¶6?›3^-Ú¡™Ÿ†êÔ=šû¬úÜ .êÆ —!’îé;µŒXV¤ ”tûìûéÙ®–Ý(ºï—ؤ¶Ê…­IÝ÷±!!3µMÿ¾çHÒnDÂÌÜÇÜsî=¤Ï=çlj«תûIé>í;ë¥ëÒã¶®um³ÆBë¢5kL­Ýê]7=NÖƒèÜ^4r«­Í6ëüùè[Âm!z¨rXö›ÌšP Ùø(_V@Ù'©¿8 V~ë°°ê¹iHGËDÖ†ÏotüV" 0:ÁqñÔ /šÿA:_ü¡š€ýÀ;¦¼à¶‹» -˜2iÙD3ôWHFI1hU†ƒŸ)>™ÖŽ<ð6Ý0öi2ÇÙxüŽïi`%îÀˆž^ó6KójDoæð''Τ'+J…ÄSõ!ÆDgò `âù¥+´ñ'ßjâ®(Æ®Î3íäÙ| gLc?^*¿&at|Ê?( ‡iWŠ£kbX#áCüKÍ @\çšTû½º¿ ˜Ci«:®PYÁeìÚž'<Œ2˜çP‘V¶ÕÃaùöñð+ÀØOM endstream endobj 158 0 obj << /Filter /FlateDecode /Length 3700 >> stream H‰”W]sÛ¶í3…&OàŠ&~ö­ŽÝF½ùhbåvîÄ÷–([‰Dª”T×ÿþž³©'v<–(X,vÏž=¸œ?e#=š.‚2*3;ŠñçžtRDY1Êã<ÂûuŸoôè~ÄQ'£é,ø¤.ÃR=…c“¦j^/BmTµ_…©ÚaØfjŽ/Uí0Po9bUÕp,±Ç¯Æü\â޵ªñÂ䪽ûÌw3¾ë×ÂzÇשVëj³©iC—ŠSZçÇ Sª®’euGS¥ÚoÃBì7ÜóÞíÏ 4fK[]»é8eþoúK0ÖQRÚl„o'éhz%çÖ<7œ®ÃégDϸèù¹q?ËȬé;Nºž¿.´ã8JŠ‘Î`±ÍÊ4Jñ=[—“àâ·‘.^ñãò×—üš¼íº}L®Fßדà}p9}ž§,‰t&¶$Oêå«?8ß|fM”ÛÄ|ó™[ì›YtFŽ‘±±íƒdÿ>>ÖXuÅL¿¹Á«Õ­z|à¼Ù~k&§P­d}îF¸´úêXùõ³Ši³Z»ÍM% g=¹e«Þ™YÅG¿V\Z´Ýºò©I£¼Ð9S£K#©ù„3LÌTÛ܆L䩺 ¡5¬­úÀmp |òÆ&pÀØlÚPÕE.&&“ç§M-ûÒœF¦Híyž_~üðáúíËÿž„=b›”‡©™Lm»3ÜÄI^žÛ{óîíõ©1SèüÔåYÈx«xÈBN$‰pugꮯ'„`ÆÊÕŒDÑ$QZfæáãÄwí¹§e¦Ï=}Ñì×u·œ½8;z—É3Äݪê¾êá¤=.C¢M+Ûô¨$8Vð¼HTÏÛ½ðF -B“„bž ŒÐµ1(™G%ª×UG.bËá‹gdb›[³³c®_}Ïw1ãfÔdQ§éq¬>©¦êžÂ´à¤GÝ"*¼®‘Ñ,‘GZ'-E·! […®jwõnß9þ"&®3§A)@M*0Æ’ŸÆ–-Á ldzgû®C:Wä?ÔQµÛU³G—†r ¤ 2 ì ó$KiŸ¦ºes†a\F…) FÒ6œß]U»j Õp‹çwwŸÑRXnÝS«(b8­Œ ”ÿÍð¸¨HÎúÒÕE)þ…Û]7ð‡.Kô×݃ƒ¿=ê¤ëK*!žÏ¿GŸÂATx*fÕ®^ 3±sA¸ºAYÖËd¨[¤ç:Ù—ŸÕ‡bòòj^¹ CŠAkÉèøâæ’á ™Ö퀂A®eþ¹¿Hü[¹pÀ:#1ÁŠ\§Ž%ËÌݹ Ä9ç¥jx7³Ç¥: CÜ©£ù]ÔTëz{Z¶[ã¼øjå‚bcþ>± [nX·¸Ÿ|È.pÒWÆÔ%ötooÕr°-yPö_ƒ¹¦4Gçêæýk´"ÒÉ9Ì|3]ÎYË”QHÎ`LôYGά7|³ªfK™rï®FÐ5›Ï½'- Mm&e2ŒR:öÈ,–]è´(³(ËŸå‹èÅ7‹òøÒ:Dˆ|rªc¨ Æ©m ò¾WÄ‹ÌàCeڤǩ’ͯ§ÁïÐI!ZNó;£,F³up9 .~éàâ?.}ɯɛѮÛ×Áäjô]p= Þ—Ó¯C¤…ßYáš]¢^œ$‹¿Mªè亅Jƒ#å7P‹Äÿ»~zl»ùf¿Så¥þë“Xóíþk­°¾MŠþ®DÁmÁ€Ò‰g;¶eóF†Z$,ñ«/®S[æÍ’_צá6/3%ÓÕ=WœW«lÅV:E$|SТWf´X+štž€ƒ§`Ǧh6õ"ÔNЉj#GåZT[-]¦õ;ù¹‹"=²£6”'¢ÐØÌ¸”©Û~qŠ6Ü ò¢ÌÏ!0¥éw’ƒ"²e:”ˆÕ™;ö÷w¡E1îC«©j$PF‘êój÷È péY8ÝhSz›‰^Å!m†kÅÍ·æ3…˜Å1e…Ï%®N;Ø ˆ‡·¹'kŶøa»Ó膄6&©Ìܤj>‡Èl#d¾hKUoåJ"[`ñüy_ úמ°Òœ+µÜ=ñ óÆëËí¡FNK„¬þr,‡ZM“¬Vj¯!/Ô¬±ón*×*ŠÎAâxGEiv(¨Ó£‚B­Eå\Îqâ™É¤Ï t^÷mº[’C¤ AAÂÈû7€i9K®š–Þk34vãD†ˆrM¡Š…paéµÓm¾¿£ØI×NVHoÕÿEÅxkpÓv½r¡Êlç¶®ïë¦îè‚»áŒý™OÆbßÌήm'Ñ´hG¶8/Î#J=‰*š×Až¢L¼T?O•r“7ZéKí½¸*µ`b/½f"Xf ¤ ÒÏ™+|ÎŒ‹AmÙr8=mJú6”{œDU›>×ÀcGàªgLêŽùÔ$qy ÷èäòu2–¦æµµQ1²ÚyÁžv$5²p\âžúD±é¥¡»\M¶Û=GD(äDŽ”6_½fŠ–ëå®"oºÜy¼ƒç]ÕíoJûÊ«e·i Š~‰DM<~³A*„x´•X°rÓZuìÈv@ý{Î9wœ&),XDqÆ“ëñÌ=¯‹ñÏ÷‡r{_¾QØbO×r Ý~»®}g{Mëè\Ÿ½§+ü\&_…:ÎÚj©Â‚YñÉßè;ÿ—”ÊÉÌȶfû¿®Djpº¢Ëý` á=V‚βhÝÊË&s†¸M_3ר(! 5Uj4.ò8ÀcÜI®"F:Þ³h­gmC•^;´’Üq&òÇUµŒô­ä¶L âÁ!r~_±^5Y‰ºµÑ±{&œHL÷¼m熽m´=$!ްi{a¯´Øà”Áµ%h”hÖ•Y>c-ù¢»`v½ùFEùôú´Õâ `’}Ã4.Ÿ…eˆ ¡guÙ6ãÔTÖtâ\J9Mõ–¦xÇêâ|f {ÿ(Ñ–p£-¯p”o5Ïgƒ.ÆñR› «‹¡n‰ŒÃ€&·F¤ LåZߣҊ5´ÍCm |õ.áÍ—3_ÆqâΕwvY—5w)Hâ ýj¥ñì»ÄÁ Ô%NƒÏIýŒ©2uÆæ¾9=ŠHth„[Wû¡™Oå“Çñ3y-Û¶_B.~7J¾brÌÌâ¸<’¦*ž"¶a|SòóÑ&¿4D=ô~çãI¦IæGåE]ˆØÓk@íÊÝðgª™ÕÐì¦ÑüÞ¶ôu× O¼mteUÕ»iö²A^„' o°nýd³ ©•î·~´$iîÚ¦ òv4BȤÄÑjÅÀ3eùf½}W6iq0[¶p -]nž‚‹O`˜=Af2¹‘V¥^ÌÛXÉ%>#…qRêk/5ãÞz^±0=jõÉ^Æwnz˜¯ šF*^íÆðTbPµR£™¨ÇÒ6M[3ã@öåêòí‹¥ ï©wA’¹ô\ñûͺ š®9ë¿<Ìì]x”BÁ£¿ÑûrÆÎ9X]—Pi ^|<Ü™7? 1ä°A¬{g€uïj:3#Ç™jy¤3µ)¥†Q$î(ªR3DÔ0σ$ýϨšE–«˜]…q`òð“¨j‡·†8ÓL]„É*Ȱ¯Yî#í1ˆà¾h o—i,@áüxÞ¼g²JD‰h¸ÛÅ}9šåùŰַûnªÑ®L-èé©·YÒU˜|‹$ȰS Ë8²¢CºÊ\Ãßøüì÷ÔwÖlüz¯/>r> ˜ùøçKÖÍ@ «‹¯jÏ¡å`æä<¯†Î:÷¼ˆ ñ×6[&xº½dt|ÕCy§¦‡T ¦B–K ϰTõÜù€xHQ¸ƒóQP\„+žúäü endstream endobj 159 0 obj << /Filter /FlateDecode /Length 3508 >> stream H‰”WÛrÛÈ|×Wè-ƒ”\“‡-+JRNy“Ý•ªöAÎEl ‚’õ÷é>gQ’7•”Ë€¹kwÏõÝŇ¿¥—ñåÝö¢ «Ü^Fø§O±µayYDEˆáýEtùpñáï·ñåÃñ" £›‹{ó× 7ß‚Ufw˜Ú¡?™ùSðï»`ã\7δJrì{w#+3]9aå.XÅÆ«¤Hñ'ÎÌ7nƒÿöÌR³"ãš]ÝsàTø°JòÌè+KSãO™›5?MÜ2–#†ÃºˆCûC‡_XsÅÖYÓotÒÙÚÍàüÆýÀOYeãıy¤]œ¹™­Ï"³ b3Œâø* «ª²—«8L¢4›Ýök{Fk;ðw„©©7¾ÑÕ47OpuÇw7û_Dæ ÓeÚš?]'«idZÆ}r•Êlu¦›0wÞNÞ\ÿx«!W[&7nœºqëv:ºn+‹èüYQc5-v“erbÝkî¯Äóˆ>ÇU²øœªÏ§~ãÆ7Š#Ä?ÛŒ_¢ÈJ¢“n¯â²b WIRÁA96Á1¥úˆ÷­ŽF×´A&Cü;0H1<ðóžèHR˜ýùq˜‘šþ´w#—4:cSOx©õQcÄâÒÜ $®’a$C•fòö¤VwîÅá%ÉêìžÁÔÜŒNt­|k'·ÑÍ2:ED3ó(Õ–°¢5é˜ö úpúnòmŠêJ++ÕUE6æÁ«³òúx|VvˆM³áà ¯ò{’#rÓÈÛ~êÛ¦æã$† î†y훎mXÕûÞl+,O£uÅH³¶Ò8“~;ÈQ[%f=ø†·U)ƒÏ= úVY´rÍ&ä R'¬´ŸbĸÌß5”U^vIPFÍàýR0*¤Ëcvylº•›§¶`€Ñy‡C·L]%65sœ-®õ¾eç§•TH–˜¯'7>û¥x@.-:³qH7O»¶“¾ÃÞ;A:Á ‹®¯×5qº·<Žð@¨Í–¿lÎÑ£âäfç·Tƒ²Â°[aç±Ã9§>µ¢àD÷è|kщ‰T'æ}™,zqŸõ%+@LÍxT¨°ÚéWÉ´S<>ŠGðâ‘ØéÆ/ái1¡Š^ ýs‹Ò줣K”26Š2+k#Ö‰˜ÄÜ+ÖuÉ<ÀÐf‹º?Í E„ÛÊš+&§ÄÔ§ ³%’hÙä†xó‰Ï%BCÌ=?®—ãœóXÄGtAAÄí³~ÞÍj“d™n+ñ§ç»Çˆö÷0lÚ¡hZÄ^LY™nÔ\|1¤–X\YZ†‰(ÐcÍ zŒëNü=jýÎ~¯?FÖmwdRóØ|d꺣Ìgì€-ú²ŸY¬Š=‹YÔÔè¾rPŽ"z ìhZ1Aí@#(˜Üýñ­™kAjRÝAúªžKÕ´2Ó_±Gäkì÷›WêÛF{…ºcîšÍÒC´\\Xéw|… äþkPVsSj¼”H”5‹Êwm#¨eF{ÜÏÍxO(Í™@›`Kæ\¾žyoÁZ WóûQÖ $064¶(ÞÅ«µ–˜[$¢¼¿zo‘­ƒV O=¶ë³êâ©✺8Ö¬›Åj€î3éû¯bXê¤A΄ ò—›¼®ý3 0³ Ø´ØwöLH ǦÖ5x¦Acñ±´4(6µØ xVÒÈíÂÐô~S=l¤ìÛœ(þm:3MäÂÁ„>›¥Ë>…Å0tÿ7Òþû"ñ²ñÄX‰.Jc ˆ¤"EÚÉ_ ¿µû¶«ÇYu[…ÜЕšçi7ô2FNQ$ñR5 ³2/Fàÿ·éwÄy·ðãî·´)Â4õ¢h%;`¯Pg-à–Õª÷èæ“yýù_Áª2×·þÂ:˜ßÞ ÛwϺ—øÕ¬8‘†×6 ¬#G7Z ø”’u#ÑÐï¤å†×ºz¬ås@åE4F׳|‘„‚›…—K¹î D)ÔǨDèòAH]î.û½Ú(??Q¯!¹ò§Ìµ¥R3ÂVӇʜÓ,n¤ó§8ÑØoÞ—ì½Ñ€Kt+‰å|eô=ù|«[^I.Eë$ïÃÏŻĿÕ2‰’æÕµS´e­dˆÛìž:lÕœ§^eIV’k?ólóø˜#Rñ >ÓDž°¿z@“ +$­æMòApYË ]ïvžlœÂXk~þ¼ªø)á§Ò|üç-ÕlBó'&ü,¡CФLǼ“Ah<]’XÏ=èÓ ÊÛï(Ç·ò[¯ùûÌŸ ÞKü«BÈ•€†é¹+ï{‹wD>l¿ÏÉ,9ŽDøY& Ùâ‡Po*¿•^+pcUpM¬çe SSš¿cºáÍ¡“„¤™òH¤G-P–JD`\ÝiÁ>µ$)~_·½}mÃÿ¢¼ŠB=¹C$ aáRtz!5¡_Eó•”™«B¢ófæËC€Dñ‚cÖ‡l¬{^PEzÙD ï¥î{´ž—ı]. ¸ÄâΩºlŽ´ÑFn¹ |»æ ïµ³þð3gÏ„üÇMÀö,ônª²šuŠ-û yŽð¢ 9ÝÿÆ»*„Ô÷ÞÝ›B Âñ„dÇH¼&;.kd¹gfÏo6³òæß¡ç©q–(¿Ðgi~Ю,wáCxõ†º 8TœÅWJÒlÖŸÛãtSOõº>ºã``ßÎÏÙ,N¬ªÎÅ3~ž.!2Ë¢mžÚß¡e=è®^wîS¿i›ù,àPæïë½Ã±¯b—49{%Ú¯°üµâŽçËžDµÐ¨';H0O½êdäJŠgÜ[¹×Âzb~‘l4ª|…8üa1jé‹(Ì"ÕÕ¯HÛ×ëu+Ä—kòõ(È"Ë×µ\?Ý÷®(HP½'ò—KËÍcºÒò–Ü^7N¹ÇË7AWSe=ÎD1ߺ uÖ|Wu·Q&UÑ…˜<±× r:|=9Avau¡¸r!"‚Çá0¼ßIŽyp=tl§ìÕ¤ÍõÂî‡Óè×2CÉ9û­gí™ý7‹dTù'²ð°×Ëd¨÷ˆO½^(õ8÷ yë$ˆìeR Òþ?tWMoÓ@½ó+rL+Hl¯½±A\€pâ€Ú‘›lHDí§…ϼ7ãԉʡéz½_Þ™yõÆvl£ÙÐÞê Š¤9N²ó§¸ÔŽãÑ`çú‘eîáLz¯Ðû(%žn®kBÒ@$Óséø 8Õ víö†^¥Ú)USMvuoÒ)J†?B’©¼P³@DEi`‹¬Ha„̈M W]Wr1`1IÆ |ü ô8ûø¥¥§Û¬Ô„Àô*ír_N¿›Hèvõ2>½˜øåî¢6Eé:Þ®çí.JZˆ^ËŒ£±Y‡Hƒƒ”Žê¤ÕÙsR1)…(¦'tž:ë¡}9s¹—°$k¦ÎÍÊI–8yš¬š?B‚¢¦ïdÓpŒ'q§¢ÊÌŽÄRåÓ–®%4?Ãyšq®pƒ./ ›¡=> F(iç(QOÎÞ®cÁŸ©ò'&ÑrnT 1`0“Ä´V¬íá!„VÇbÔ ¯Ökâ:þ¶¸xUžÎp”F¤v{£üL™Ò/•Þé¨:_¶r"&Ð×ÅÖ˜oàcÑ6[ÉòÈ4O_L!Þ³&ÛuP™‘úÙ"°‘Š® æ,¾ž—¦(²åêÍ?©¡ÀN endstream endobj 160 0 obj << /Filter /FlateDecode /Length 2522 >> stream H‰ìWÛrÛÈ}×Wè̓*qˆ¹à–7Û´wí²"¯Ä$[%û"!’kPxY­þ>çô ‰v’ª­ÊCÊeÀôLOßNŸ~3>¾OOÍéøö¤ÐEêNcü OÆç:ÍO³8ÓX_ħ³“áOWæt¶9‰u»ÓñääZ}Œ2UF6Q¿GÖàɨWQR¨M4°>U£ryùzSn Yñs¬ÞF¹j꺚puÙ»O^ñˤœU_äðÑsןÏ÷÷÷Qê”þMÎ~ÔMÍ-ÐQ¬&Í*r^v|ø:þFÛØ'§ã‘Øàƒ jÈäZðÃ+$j¾nv³9Þ“<¼C7ooŠX]DNÝUÜ“5ÂKI‰’æ"“ñÂEgaB Zhñ”Èqaóuó ‘–‹®3F̪šòp£®+îâÿ.|ív¦²5Þ7ÑVL¼VŸ£T¼lhêWQKlœ{éæÖê5­»[ʵ5)·íSÃc`´5…»nfërµâR= Ÿ?Ô®"«Ö·‘±ªœðL›íÙt™X=´·ÑÍšb³(‹ŸÙ°¦6Õ>ËáF­—½+’ ·¨¨ßtú‘:jz³ÐwÕz)* Túä 5†ï}(ãµó©ÔAûhœÓùiê2Z€W2áJ—Õm…SèŽU=©6íaÇjÊå:³§©I´“šz2îÚ|¾HÛ%5KbНðÑë?VåúÛ^`ò9œ°˜ÌËjÉÅ\ý#ò^ŠgŠŒÙÑ­ ë§ZW«‡pˆ”ݲâ"<^ÖíÙŸ#ƒÞµ‡QÿŽ5×,xRçž„Fíó»Qñæ0*©9 |wØ ¤ªðGÁêeyò_çê¦i¾õƒ»$iñbx\Îðä Ož„ÇÆD^ oÃ#møqÆ£,ge¹žÒ»`n<¯dŪK8r0ž,‡ãoò% e²×-dOnIú¨‡³ÚDE#ZG ⤪¦ƒöªÀõØ%GÊ®g*E3jnùàzrÊ2Â[™°¡T1\\ã—ï7‘ujÇ/Õ”¢Hç+¾•ü³¿Ï¶õ%ÅœA–¢Ý6Ô±ºÛud.耔Ȩäb)Úˆ‰]¦æo8ˆÏ›»ÃPøòÜ>CÄÇÌt=w<ÇãÉBow÷‹ªÖåD#qÞ6µ4Tä°tSâòèêmÈ1ËW^÷0±rm}’¼”X†Õ¸‹’ˆ¾\ÒDüSÕ5¡ù¨–‹Ñ‰‘,òŽmKª°ÂX’sôï¥Õúrh Äu‚¤W’ɨWŒ*_Ìø©Ü6üYJ:ª6“r½­Èyb´nƨæ:ó¡È¡ß ‘–fÀŒTí¸.BLìƒ|6©6>ÞóYǰBbÃΡ (¨Ë)ð<’í»ËäÚ¥yþävbú8zó6(ƒ‹x…D]ÝU_PçϦ†+vÖû9/]!‘vu°æ\plÝЉü3x̉ØdÏP¶-¥m…ä÷z"ŽÀ~ ³B0¸½þæµI’~ëÀé·ò÷Rovµô´Qs_/›rêÊu¹éƒ:äû©ì´u>?ÖÇò¶#TW#T‚3,Lös³7ëÇ&1§ d,ÀâkTÉâH–R®ª–$žS@¢$‰ –¨EÙž;zÚÊR\Ü-A2œ’rÄw©, q—+nÉžµK ‘OÑÇšï0Â6a¦aÒ„ÎnØ´Š¿ìùà8ý†›è¬pÙ1|bã]HCµ¹ vÀ<&t¤e2»l‰N tOƒîÉÖÉžEÊ/«-ßðÊ`$8‡.)Hg Û¶F>±3š Á#¿Á±mJ¶íu”66„gíY;s¼{bÝfö{SÌË]³’1QŽøðØ5㘯ßíš?žjZä Í ’H ÙÂì騛ÏSß/´pÇ v£ƒKèÌZ{lÖØc„^ç(Æc$Ãq¢QïÖ³&_o½5H–Þñxã‰pN0W^ÆófUndGª„–pYj&"’`˜#•°©Uï0EN§aPà@Ö¥œ’=Rv°ÙG¢/j=…ÿ)W¦˜°ƒ)¼ ÐfÕ-3ö>2…וðc@/ß䯶0Š2sJ“ØÌ‡­O_ÙBl^<ó rE8³ÙÕ2v¥h/}D’ÿ¤ÌRþÿ³Ô³YêYæÿoÌR/DéÏš¥^Æ:ÛbÝOU#öÎHrAL.¡¤ª„nô°îq(jÒñt€„c…>Ü0è³udQ»‚ (ì c ÒÚâpwËŠó®ƒ@ê#xd¯9ÉPj#YÌÓåÕe;yÁ«‚<‰þè&òø®Kä±9B=@„G>§õYÂ+eÊ7@ )LÆíÊX¦Þ»ñÉ¿x;%p endstream endobj 161 0 obj << /Filter /FlateDecode /Length 138 >> stream H‰21R0P0U0S0"s…C®B.cC ˜2ÕaK…ä\.'O.ýp —¾˜t pVRž¾ %E¥©\ž. ÿðÿÿÏÀøÿÃÿ öä00ð```áff```$„‘ÕÃÌ™2d>È} {¹\=¹¹ áê*zendstream endobj 162 0 obj << /Filter /FlateDecode /Length 901 >> stream H‰äTÁ’Û6 ½ë+|g"š HJÊ­»Þv’i;]§=ìæ •¹²Òµ¤‘å8ýû¤íØN&ÐŽÇ$D€øð€›e2ÿÙÍp¶|IJYºl¦è%Ì2YÌr•KRo5k’ù/8k¶‰’JÙÙ²Ná³"5Â@R¤ÖXðž;¸ç³V8^iñ-üÃ9TÝŠk£ÉÁü7‘Á77EŠpvÛ–l‚YŽðÓܲU]M©ï¶äÁð‘8m%ÔäûhíIîø›æ *þ>ä³eП"ø‘¿¥ø¸|Ÿh‰®ÀYŠR+CÏ_$ð®ËOa!DiÊÌ‚¤cŒ²ˆÑ£ Ç}íýªíŠéŒ é9zÌ´ö$8„…ÐÐnEÓHKû,4Ânò+ÖZx˜ª)jÛºzWoE½H3Ø »‰<óiZ)ä†-Øåß=¬û!¼çTùLI[šcÞœ3-ûÞÄÇéh•fZª¢Ð –Ú©ã#×Ó4¼Ï÷û½¬[9íö­ïdUËjšßöÝ‹jð]í·,Ì·)ó4rÊ)éBjcíW(]Œò†Jos«’MÏêrÆÏ?jÞu•Hµvð¡kE¦à¬¾¬g:75i¸4Ú(XŠÜ€¯×]ÏÄé›ùbÔʲ´'à¸!|0¼„Æpp3¶UÇsª1‘Y²lˆ—”ØÀv¯žÉNÞ ë2«áöíXÓÄk̨¦ê9ì[‚òÌaßNëhp/ð‰XJ•—'ø´=Àwÿ»ÐD5O«ƒ}·W\ 1ûŠ»=á®-rþO€Oâ-!‚Åá©¥DxOH†NÚUãÉó2{JUœ#Æ`Ù’æ.EGI-ȧÇåQà_ ¤~ØxêVÒKœ/¡=åš+DæÕæêùË:eâ+£o2\aNT!Xï¨#6C?’O>žÓÿŽºðËñèDIð8ëªÖuƒ ÷ÿm1RûO¾žd?6W¡Œ4FüÚ^€ŠN:êñ žÏfw˜Í‹]W3 q%²ZðÔˆc55D¼_«®á¹ªhrÞmžýjÅMÁ3Åd4}h#¼Â‰y˜*@[³@ÝM¾m°Í®j˜¦Æ”§éj¨{|'ÈÝgv4ö]¨«ƒïØã„ùÏŽØLדç0]‰ÿ6§`©¡F./Ò̹»eò¯ 1­ endstream endobj 163 0 obj << /Type /XRef /Length 94 /Filter /FlateDecode /DecodeParms << /Columns 4 /Predictor 12 >> /W [ 1 2 1 ] /Info 2 0 R /Root 4 0 R /Size 164 /ID [<12dcc3843ccf2a793e18968594e6c27e>] >> stream xœcb&F~ñ‰ Èc%hOüçIßÁÄÀ¶ìïœFƒnÁ.±윑Àç="ªw*àůàY"ÿ>Ä? Á¥$/ æs Ô endstream endobj startxref 42214 %%EOF RMySQL/inst/NEWS0000644000175100001440000003644611703617102013046 0ustar hornikusersVersion 0.7-4 * Fixed a bug whereby NULL was being fed to C_S_CPY() from RS_DBI_getTypeName(). Affected RS_MySQL_typeNames() and RS_DBI_SclassNames(). Changed to empty string. Version 0.7-3 * Added mysqlClientLibraryVersions() which returns the compiled and loaded client library versions as a vector. * RMySQL will now check for MySQL minor version consistency and throw an error when the client and loaded library versions don't match. Version 0.7-2 * New maintainer is Jeffrey Horner . * We no longer distribute libmysql.dll. This library is now found either by reading the MYSQL_HOME environment variable or by reading the windows registry entries. * Removed dependence on MySQL C function load_defaults() as it was meant for command-line tools, not for (re)connecting to a database. * Fixed \r issue with dbWriteTable(). * Tests have been added and depend on proper values set in the environment variables MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWD. Version 0.6-1 * Fixed a dormant bug in code that imporperly used "$" in mysqlWriteTable(). * Fixed typo in some Rd files; got rid of a few gcc warnings; we now silently ignore unrecognized options in mysql config files (thanks to Jon McAuliffe for this patch), etc. * Added method dbColumnInfo(MySQLConnection, "tablename") (similar to Greg Warnes' dbDescribeTable() suggestion). * mysqlWriteTable() now issues a LOAD LOCAL specifying column names, this allows to export data.frames with a subset of fields (as per Greg Warnes patch). * Plugged a memory leak when closing a connection (as per Jeff Horner's patch). Version 0.6-0 * Added an experimental version of multiple result sets processing. There are two new DBI generic function extensions, dbMoreResults() and dbNextResult() that return, respectively, whether there are more results sets and the next result set. Note that to use this feature on a connection, the connection must be created with the CLIENT_MULTI_STATEMENTS client flag. Also note that not all results need return data. (Thanks to Crispin Miller for code patches and testing; also thanks to Michal Okonlewski for initial discussions on this.) * Added connection flags with names after the MySQL C macros CLIENT_COMPRESS, CLIENT_LOCAL_FILES, CLIENT_MULTI_RESULTS, etc. * Added generic function dbEscapeStrings() and a MySQL connection method to escape strings on a connection basis, i.e., each connection can support different char sets. (Thanks to J. T. Lindgren for the original code.) * Enabled the package NAMESPACE. Notice that the mysql*() support functions will be made private in the near future. * The configure script now also looks in lib64 libraries *before* the default library directories /usr/lib, etc. (thanks to Brian Ripley for this patch and Seth Falcon for additional testing). Notice that this behavior will select 64-bit libraries over 32-bit on systems that host both R builds, thus in these cases you may want to explicitly use PKG_CPPFLAGS and PKG_LIBS. See the "R Installation and Administration" for more details, including Section 8 "Choosing between 32- and 64-bit builds". Version 0.5-11 * Fixed a bug that would crash R with a failed mysql_real_connect(). * dbApply() is now working again (but still experimentally). * Re-formatted the C code. [0.5-9 through 0.5-10 were maintenance releases that Seth Falcon kindly put out.] Version 0.5-8 * Added MySQL error message when failing to connect (thanks to Louis Springer for the patch). * Added code to recognize the newer MySQL types BIT (mapped to integers if not too many bytes, otherwise to characters) and NEWDECIMAL. * Fixed a stack imbalance when cloning a connection, e.g., con2 <- dbConnect(con). * Remove abbreviation F for FALSE in call to MySQL(). * Added package documentation page. Version 0.5-7 * Added a method for dbWriteTable to write a table from a text file, e.g., dbWriteTable(con, "tablename", "filename") * Added the argument "default.file" to dbConnect's method to allow parsing options from an alternate mysql options file. If specified only this file is read, as per the MySQL C API. * Re-use RSQLite's helper function "dbBuildTableDefinition" that builds an SQL string with a simple "CREATE TABLE" definition appropriate for exporting a specified data.frame. * Fixed default in dbReadTable's method to used a table field "row_names" (if it exists) as the row.names() of the output. * Modified the configure.win to create windows binaries a bit easier. * Fixed documentation typos. Version 0.5-6 * Fixed a (potential) bug in the safe.write() where it would use the current options(digits), possibly losing precision on double precision data. It now uses digits=17, regardless of option("digits"). * Added a simple configure.win to simplify building the package on windows; removed the inst/libs directory and now provide the MySQL windows binary library in the src/windows directory. Version 0.5-5 * Fixed documentation typos. Version 0.5-4 * Fixed 2 problems in configure.in: Since the MySQL client library requires libz, but now explicitly check for it ourselves; also we now explicitly check for the GNU getopt_long in the C library and set the C preprocessor macro HAVE_GETOPT_LONG accordingly, which we use to conditionally include or exclude the appropriate C code. Version 0.5-3 * Fixed a data.frame subsetting problem introduced (uncovered?) with the new R 1.8.0 data.frame subsetting semantics. (The code was in safe.write(), to be precise). * Fixed the vector .MySQLKeywords of reserved words (it was no 100% accurate). * Yet many more changes to the documentation structure (not the contents) due to yet more changes in the R help system. * Updated S4R.h to include changes to the .Call API in S-Plus 6.x (untested). * Built a Windows binary against MySQL 4.0.16 (see inst/libs). Version 0.5-2 * Added a test to verify whether the MySQL runtime version is different from the version used during compilation. Only a warning is printed if the versions differ. Version 0.5-1 Bug fixes only. * Fixed the bug in dbWriteTable() incorrectly exporting logicals (thanks to christian.ritter@shell.com). A general mechanism for data conversion is still lacking. * Fixed a problem with issuing mysql_options() with MYSQ_OPT_LOCAL_INFILE in version prior to 3.23.49, which is the one introducing this option. This bug only appeared when compiling against MySQL 3.23.39 thru 3.23.48 Version 0.5-0 Made the package DBI-compliant (as of DBI 0.1-4) using version S4 style classes. Simplified quite a bit the MySQLSupport.R file where most of the workhorse functions are. No new functionality in this version. Version 0.4-6 Ported to Windows with some very nasty porting problems beautifully solved by BDR (thanks!) * Added Makevars.win for Windows' sake. * ifdef the code that parses group default (problems with getop.c). The issue is that MySQL C function load_defaults() is not defined in libMySQL.lib, only mysqlclient.lib. Unfortunately the client library is only for static, thread-safe applications. (Need to solve this thread-safety issue). * Need to re-import the libMySQL.lib (see README.windows). Version 0.4-5 A transitional, internal version. * Synchronized the RS-DBI.c and RS-DBI.h with ROracle_0.3-3. * Fixed a bug in getopt_long (being assigned to a char, instead of an int). Apparently this cause problems only on Yellow Dog Linux versions (thanks to DTL for reporting this). * Commented out the S4's idiom "if(IS_LIST(x)) x = AS_LIST(x) in the C code when compiled for R (could this idiom introduce memory protection or garbage collection problems in R?) Version 0.4-4 All but one changes for this point release should be transparent to all users, and were done for compatibility with version 4 classes. * Added compatibility for Version 4 style classes and methods. Namely don't re-define functions such as as(), new(), show(), etc. when running with R 1.4.0 library(methods). Added a function usingV4() that tells us whether we're running with version 4 classes or not (works with R and Splus). * Moved the vector of SQL keywords to .SQL92Keywords in DBI.R. Also, modified make.SQL.names() to use a "keyword" argument (.SQL92Keywords by default). (This will allow us to use the same function with simultaneous drivers, MySQL, Oracle, SQLite, etc). Defined a vector of .MySQLKeywords that we pass to make.SQL.names() in assignTable.MySQLConnection. * Define a new print/show method for MySQLObjects. Version 0.4-3 NOTE: Next release will most likely implement the emerging R/S DBI interface, so I anticipate that the functions will have very different names, although the core functionality will be pretty much the same.) Stay tuned. * Added an *experimental* dbApply() that applies a function to groups of rows, one group at a time, avoiding having to hold the data from all the groups in R/S. It takes a result set, a grouping field, plus one or more functions and invokes them when certain "fetching events" occur (e.g., at the beginning/end of groups). See help(dbApply) for more details. [I must have(?) a bizarre bug in the my C code that causes an R core dump when quantile(x, ..., names=T) is invoked inside the R callback function, but works fine with quantile(x, ..., names=F) -- any hints will be greatly appreciated!] * Fixed the unimplemented append=T in assignTable() (thanks to Jens Nieschulze for the patch). Also, assignTable() now explicitly sets the end-of-line to be '\n' in the call to LOAD DATA -- this should fix the incompatibility in Windows that Brian Ripley alerted me to (thanks!) Also fixed the treatment of NA's when exporting a data.frame to MySQL. (On input MySQL interprets '\N' as an SQL NULL, which is what we use in SQL to denote an NA in R/S.) Re-named the argument from "rownames" to "row.names" for consistency with getTable (see below). * Added row.names= argument to getTable(). The semantics is similar (but not identical) to read.table(), namely if row.names is a column name or index, the corresponding column is used as row.names (provided the column has no duplicate values, of course); a NULL or 0 value mean "don't use any field to set the row.names of the output data.frame." * The getTables() method now returns a character vector, instead of a data.frame. * There have been 2 reports of NULL's in MySQL double fields being incorrectly mapped to non-NA's, random (very small) numbers; in both cases on Solaris (we couldn't reproduce it on Linux nor our local Sun servers). In one case the problem was traced back to multiple versions of the libmysqlclient.so library. We still need to get to the bottom of this:-( * Fixed a bug when converting from NULL in a float dbms field to a numeric (i.e., double) NA. * Fixed a bug that core dumped somewhat randomly when fetching a large result set that required extending the receiving vectors of the output list. The cause was not PROTECTing the code expanded by SET_LENGTH. [Somewhat counter to my (buggy) intuition, an element *inside* a protected list loses its protection when we use SET_LENGTH on it. See the function RS_DBI_allocOutput in RS-DBI.c for the gory details.] (This problems occurred with R 1.2.3 and previous versions.) * Fixed a bug in the data conversions of FIELD_TYPE_LONG into R/S integers that erroneously map them to numeric/double when their length was greater than sizeof(Sint). The current logic (only applies to BIGINTs) is that if R's integers, sizeof(Sint), have less then BIGINT's 8 bytes then we convert BIGINT to double to avoid overflow. This is clearly platform specific. Grrr! * Fixed a typo (PKG_CPPFLAG, sic) in the instructions generated when configure couldn't find the MySQL header files and libraries. * Fixed an unobservable bug in the LST_CHR_EL macro in S4R.h. Version 0.4-2 * (R version) We fixed a problem with load() --- we had correctly elevated this function to generic, but failed to define load.default as the load() in package:base; this problem only manifested when using load from inside other packages (thanks to Prof. Brian Ripley for catching this one.) * We now include the GNU files "getopt.h" and "getopt.c" under the "gnu" directory -- this is for the sake of non GNU systems (note that these files are also included in the MySQL source distributions). We also have a copy of "getopt.h" in the "src" directory (this simplifies installation for users of gcc on Solaris and possibly other non-GNU systems). We still need to code this into the R configure script -- see below. * Updated dbExec documentation, various typos, etc. Version 0.4-1 * A manual in the Adobe PDF file "RS-MySQL.pdf" * A lot of changes to the internal C code to have a common source for R and Splus 5.x and 6.x * A better configure.in (thanks to Torsten Hothorn). I still need to add code to check for the GNU getopt.c and getopt.h (as required by MySQL) on systems with no GNU tools (e.g., solaris/irix/hpux/aix). * Added a convenience RS-DBI dbConnect method dbConnect(mgr="character"), e.g., dbConnect("MySQL", ...) to invoke the dbManager("MySQL") prior to opening the actual connection. * added (almost) trivial convenience RS-DBI functions getTable(), assignTable(), existsTable(), and removeTable(). They all mimic the corresponding R/S get(), assign(), exists(), and remove(), and they all work with a connection object and an sql table name (NOT generic SQL queries); assignTable() assigns a data.frame object (or coerceable) to the database. (These functions provide the basis for "user-defined databases in S -- see below.) * Added support RS-DBI functions make.SQL.names() and isSQLKeyword() to create legal SQL identifiers and to test for SQL keywords. * Similarly, added a new RS-DBI generic function SQLDataType(dbObjectId, obj) that returns the DBMS data type that most closely can represent the R/S object "obj". Added the corresponding MySQL method for SQLDataType(MySQLObject, obj). * (Splus only) Added RS-DBI methods to be able to attach a relational DBMS as an S user-defined S database, e.g., con <- dbConnect("MySQL", group = "vitalAnalysis") attach(con, translate = T, max.rows = 10000) ls(pos=2) x <- CLIENTMAPTABLE See ?attach.dbConnection for details. Note: *DO NOT* use this facility on large tables --- see the "proxyDBMS" library for a more efficient/ambitious interface. (I'm not sure this facility belongs in the RS-DBI, but it sure is easiest to be bundled here.) * (Splus only) Added a MySQLObject virtual class that extends dbObjectId. dbObjectId is now the virtual class for generic remote (DBMS) database objects; each driver then extends it through its own virtual class, e.g., MySQLObject -> dbObjectId. MySQLObject is virtual and the base class for all MySQL objects (dbManager, dbConnection, etc.); this is cleaner, and besides, it simplifies some "mixin" helper classes, e.g., show() for remote objects, SQLDataType(), and so on.) Version 0.4.0 * Parses $HOME/.my.cnf file. Added an "rs-dbi" stanza, and the S code parses for other stanzas, as specified in the argument "group=" in the call to dbConnect. For details, see help(MySQL) and the MySQL manual. RMySQL/configure0000755000175100001440000037722511703617102013304 0ustar hornikusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="src/RS-MySQL.c" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP PKG_CPPFLAGS PKG_LIBS LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-mysql-dir=MYSQL_DIR specifies an existing MySQL base dir --with-mysql-inc=MYSQL_INC specifies an existing MySQL include dir --with-mysql-lib=MYSQL_LIB specifies an existing MySQL lib dir Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Some people have reported not having libz (which we clearly is needed # in the INSTALL file). Oh well. # echo "$as_me:$LINENO: checking for compress in -lz" >&5 echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6 if test "${ac_cv_lib_z_compress+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char compress (); int main () { compress (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_z_compress=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_compress=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5 echo "${ECHO_T}$ac_cv_lib_z_compress" >&6 if test $ac_cv_lib_z_compress = yes; then HAVE_COMPRESS="yes" else HAVE_COMPRESS="no" fi # Do we have access to GNU's getopt_long (problem on some systems, e.g., # FreeBDS, Mac OS/X, Windows/MinGW) # echo "$as_me:$LINENO: checking for getopt_long in -lc" >&5 echo $ECHO_N "checking for getopt_long in -lc... $ECHO_C" >&6 if test "${ac_cv_lib_c_getopt_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getopt_long (); int main () { getopt_long (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_c_getopt_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_getopt_long=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_c_getopt_long" >&5 echo "${ECHO_T}$ac_cv_lib_c_getopt_long" >&6 if test $ac_cv_lib_c_getopt_long = yes; then HAVE_GETOPT_LONG="yes" else HAVE_GETOPT_LONG="no" fi # can we find MySQL in the system directories? (users may still want/need # to use another version/installation) # echo "$as_me:$LINENO: checking for mysql_init in -lmysqlclient" >&5 echo $ECHO_N "checking for mysql_init in -lmysqlclient... $ECHO_C" >&6 if test "${ac_cv_lib_mysqlclient_mysql_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char mysql_init (); int main () { mysql_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_mysqlclient_mysql_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mysqlclient_mysql_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_init" >&6 if test $ac_cv_lib_mysqlclient_mysql_init = yes; then HAVE_MYSQL_LIB="yes" else HAVE_MYSQL_LIB="" fi echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in mysql.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF HAVE_MYSQL_INC="yes" else HAVE_MYSQL_INC="" fi done # # the user may still want a particular MySQL installation/version (possibly # overriding system directories). Note that we don't clobber the shell # variables MYSQL_DIR, MSYQL_INC, MYSQL_LIB, that may be inherited from the # global shell environement. # # Check whether --with-mysql-dir or --without-mysql-dir was given. if test "${with_mysql_dir+set}" = set; then withval="$with_mysql_dir" MYSQL_DIR="${with_mysql_dir}" fi; # Check whether --with-mysql-inc or --without-mysql-inc was given. if test "${with_mysql_inc+set}" = set; then withval="$with_mysql_inc" MYSQL_INC="${with_mysql_inc}" fi; # Check whether --with-mysql-lib or --without-mysql-lib was given. if test "${with_mysql_lib+set}" = set; then withval="$with_mysql_lib" MYSQL_LIB="${with_mysql_lib}" fi; # handle the uniformative cases of --with-mysql w.o. argument # and the case of -with-no-mysql test "${MYSQL_DIR}" = "yes" -o "${MYSQL_DIR}" = "no" && MYSQL_DIR="" test "${MYSQL_LIB}" = "yes" -o "${MYSQL_LIB}" = "no" && MYSQL_LIB="" test "${MYSQL_INC}" = "yes" -o "${MYSQL_INC}" = "no" && MYSQL_INC="" if test -n "${MYSQL_DIR}" ; then test ! -d "${MYSQL_DIR}" && { { echo "$as_me:$LINENO: error: dir ${MYSQL_DIR} does not exist" >&5 echo "$as_me: error: dir ${MYSQL_DIR} does not exist" >&2;} { (exit 1); exit 1; }; } test -z "${MYSQL_INC}" -a -d "${MYSQL_DIR}/include/mysql" && \ MYSQL_INC="${MYSQL_DIR}/include/mysql" test -z "${MYSQL_LIB}" -a -d "${MYSQL_DIR}/lib/mysql" && \ MYSQL_LIB="${MYSQL_DIR}/lib/mysql" fi # # We now determine whether we found the lib and header files (we still # need to check PKG_*, in case the user only defined one them) # if test -z "${PKG_LIBS}" ; then if test -n "${MYSQL_LIB}" ; then # use the one specified in --with-mysql-* PKG_LIBS="-L${MYSQL_LIB} -lmysqlclient" else # use the one in the system dirs (if there's one) test -n "${HAVE_MYSQL_LIB}" && PKG_LIBS="-lmysqlclient" fi fi if test -z "${PKG_CPPFLAGS}" ; then if test -n "${MYSQL_INC}" ; then # use the one specified in --with-mysql-inc=DIR PKG_CPPFLAGS="-I${MYSQL_INC}" FOUND_INC="yes" else if test -n "${HAVE_MYSQL_INC}" ; then # use the one in the system dirs PKG_CPPFLAGS="" FOUND_INC="yes" else PKG_CPPFLAGS="" FOUND_INC="no" fi fi fi if test "${HAVE_GETOPT_LONG}" = "no" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DHAVE_GETOPT_LONG=0 " fi # if above fails, do a more exhaustive search into potential mysql # subdirectories of the system directories. if test -z "${HAVE_MYSQL_LIB}" -a -z "${PKG_LIBS}" ; then for dir in /usr/local/lib64 /usr/lib64 \ /usr/local/lib /usr/lib /usr/local/mysql/lib /opt/lib /lib do # need to release mysqlcient from cache unset ac_cv_lib_mysqlclient_mysql_init candidate="${dir}/mysql" echo "$as_me:$LINENO: checking for mysql_init in -lmysqlclient" >&5 echo $ECHO_N "checking for mysql_init in -lmysqlclient... $ECHO_C" >&6 if test "${ac_cv_lib_mysqlclient_mysql_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient -L${candidate} $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char mysql_init (); int main () { mysql_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_mysqlclient_mysql_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_mysqlclient_mysql_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_init" >&6 if test $ac_cv_lib_mysqlclient_mysql_init = yes; then HAVE_MYSQL_LIB="${candidate}" else HAVE_MYSQL_LIB="" fi if test -n "${HAVE_MYSQL_LIB}" ; then echo " mysqlclient found in -L${HAVE_MYSQL_LIB}" PKG_LIBS="-L${HAVE_MYSQL_LIB} -lmysqlclient" break fi done fi # ditto for the header files if test -z "${HAVE_MYSQL_INC}" -a -z "${PKG_CPPFLAGS}" ; then for dir in /usr/local/include /usr/include /usr/local/mysql/include \ /opt/include /include do candidate="${dir}/mysql" as_ac_Header=`echo "ac_cv_header_${candidate}/mysql.h" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for ${candidate}/mysql.h" >&5 echo $ECHO_N "checking for ${candidate}/mysql.h... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking ${candidate}/mysql.h usability" >&5 echo $ECHO_N "checking ${candidate}/mysql.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <${candidate}/mysql.h> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking ${candidate}/mysql.h presence" >&5 echo $ECHO_N "checking ${candidate}/mysql.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <${candidate}/mysql.h> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: ${candidate}/mysql.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: ${candidate}/mysql.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for ${candidate}/mysql.h" >&5 echo $ECHO_N "checking for ${candidate}/mysql.h... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then HAVE_MYSQL_INC="${candidate}" else HAVE_MYSQL_INC="" fi if test -n "${HAVE_MYSQL_INC}" ; then PKG_CPPFLAGS="-I${HAVE_MYSQL_INC}" FOUND_INC="yes" break fi done fi # don't go any further if don't have libz if test "${HAVE_COMPRESS}" = "no" ; then echo "" echo "Configuration error:" echo ' Could not locate the library "libz" required by MySQL.' echo "" echo "INSTRUCTIONS:" echo "" echo ' The "libz" library is required by the MySQL client library' echo " in order to compress/uncompress connections between clients" echo " and the MySQL engine." echo "" echo ' Make sure you have "libz" installed properly and/or included' echo ' in your $LD_LIBRARY_PATH. Perhaps it is not in any of the' echo " standard directories (e.g., /usr/lib/, /usr/local/lib)?" echo "" echo "Aborting the installation of RMySQL." echo "" exit 1 fi # If we stil haven't set PKG_*, error if test "${FOUND_INC}" = "no" -o -z "${PKG_LIBS}" ; then echo "" echo "Configuration error:" echo " could not find the MySQL installation include and/or library" echo " directories. Manually specify the location of the MySQL" echo " libraries and the header files and re-run R CMD INSTALL." echo "" echo "INSTRUCTIONS:" echo "" echo "1. Define and export the 2 shell variables PKG_CPPFLAGS and" echo " PKG_LIBS to include the directory for header files (*.h)" echo " and libraries, for example (using Bourne shell syntax):" echo "" echo ' export PKG_CPPFLAGS="-I"' echo ' export PKG_LIBS="-L -lmysqlclient"' echo "" echo " Re-run the R INSTALL command:" echo "" echo " R CMD INSTALL RMySQL_.tar.gz" echo "" echo "2. Alternatively, you may pass the configure arguments" echo " --with-mysql-dir= (distribution directory)" echo " or" echo " --with-mysql-inc= (where MySQL header files reside)" echo " --with-mysql-lib= (where MySQL libraries reside)" echo " in the call to R INSTALL --configure-args='...' " echo "" echo " R CMD INSTALL --configure-args='--with-mysql-dir=DIR' RMySQL_.tar.gz" echo "" exit 1 fi ac_config_files="$ac_config_files src/Makevars" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "src/Makevars" ) CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@PKG_CPPFLAGS@,$PKG_CPPFLAGS,;t t s,@PKG_LIBS@,$PKG_LIBS,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi