├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── NAMESPACE ├── R ├── RcppExports.R ├── rpg.R ├── sql.R └── utils.R ├── README.Rmd ├── README.html ├── README.md ├── appveyor.yml ├── cleanup ├── configure ├── configure.win ├── cran-comments.md ├── man ├── async.Rd ├── connection-utils.Rd ├── connection.Rd ├── copy.Rd ├── cursor.Rd ├── format-for-send.Rd ├── misc.Rd ├── path.Rd ├── prepare.Rd ├── psql.Rd ├── query.Rd ├── rpg-package.Rd ├── sql.Rd ├── stack.Rd ├── stow.Rd ├── table-info.Rd ├── table-io.Rd ├── tracing.Rd └── transactions.Rd ├── rpg.Rproj ├── src ├── Makevars ├── Makevars.in ├── Makevars.win ├── RcppExports.cpp ├── rpg.cpp └── rpg.h ├── tools └── winlibs.R └── windows └── libpq-9.5.2 ├── include ├── ecpg_config.h ├── ecpg_informix.h ├── ecpgerrno.h ├── ecpglib.h ├── ecpgtype.h ├── libpq-events.h ├── libpq-fe.h ├── libpq │ └── libpq-fs.h ├── pg_config.h ├── pg_config_ext.h ├── pg_config_manual.h ├── pg_config_os.h ├── pgtypes_date.h ├── pgtypes_error.h ├── pgtypes_interval.h ├── pgtypes_numeric.h ├── pgtypes_timestamp.h ├── postgres_ext.h ├── postgresql │ └── internal │ │ ├── c.h │ │ ├── libpq-int.h │ │ ├── libpq │ │ └── pqcomm.h │ │ ├── port.h │ │ ├── postgres_fe.h │ │ └── pqexpbuffer.h ├── sql3types.h ├── sqlca.h ├── sqlda-compat.h ├── sqlda-native.h └── sqlda.h ├── lib ├── i386 │ ├── libcrypto.a │ ├── libpq.a │ └── libssl.a └── x64 │ ├── libcrypto.a │ ├── libpq.a │ └── libssl.a └── readme.md /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.* 4 | ^\.travis\.yml$ 5 | ^.*\.a$ 6 | ^windows$ 7 | ^appveyor\.yml$ 8 | ^src/Makevars$ 9 | 10 | ^cran-comments\.md$ 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | r: 3 | - oldrel 4 | - release 5 | - devel 6 | 7 | cache: packages 8 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rpg 2 | Type: Package 3 | Title: Easy Interface to Advanced PostgreSQL Features 4 | Version: 1.6 5 | Date: 2017-10-25 6 | Author: Timothy H. Keitt 7 | Maintainer: Timothy H. Keitt 8 | Description: Allows ad hoc queries and reading and 9 | writing data frames to and from a database. 10 | License: GPL (>=2) 11 | URL: http://github.com/thk686/rpg, http://www.keittlab.org/ 12 | Imports: 13 | Rcpp (>= 0.11.1), 14 | uuid (>= 0.1-1), 15 | RApiSerialize (>= 0.1.0), 16 | getPass (>= 0.1.0) 17 | Suggests: 18 | foreach (>= 1.4.2), 19 | doParallel (>= 1.0.0), 20 | hflights (>= 0.1) 21 | LinkingTo: Rcpp, RApiSerialize 22 | SystemRequirements: C++11 23 | Depends: 24 | R (>= 3.0.0) 25 | NeedsCompilation: yes 26 | RoxygenNote: 6.0.1 27 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(format_for_send,Date) 4 | S3method(format_for_send,data.frame) 5 | S3method(format_for_send,default) 6 | S3method(format_for_send,list) 7 | S3method(print,conn.info) 8 | S3method(print,pg.trace.dump) 9 | S3method(print,pq.error.message) 10 | S3method(print,pq.status) 11 | export(add_column) 12 | export(add_foreign_key) 13 | export(add_primary_key) 14 | export(append_path) 15 | export(async_query) 16 | export(async_status) 17 | export(begin) 18 | export(cancel) 19 | export(commit) 20 | export(connect) 21 | export(copy_from) 22 | export(copy_to) 23 | export(create_index) 24 | export(create_schema) 25 | export(createdb) 26 | export(cursor) 27 | export(delete_stowed) 28 | export(describe_table) 29 | export(disconnect) 30 | export(dropdb) 31 | export(dump_conn_trace) 32 | export(enable_extension) 33 | export(enable_postgis) 34 | export(encrypt_password) 35 | export(execute) 36 | export(fetch) 37 | export(finish_async) 38 | export(format_for_send) 39 | export(get_conn_defaults) 40 | export(get_conn_error) 41 | export(get_conn_info) 42 | export(get_encoding) 43 | export(get_path) 44 | export(get_tuple_info) 45 | export(is_busy) 46 | export(libpq_version) 47 | export(list_databases) 48 | export(list_schema) 49 | export(list_stowed) 50 | export(list_tables) 51 | export(make_service) 52 | export(path_contains) 53 | export(ping) 54 | export(pop_conn) 55 | export(prepare) 56 | export(prepend_path) 57 | export(psql) 58 | export(push_conn) 59 | export(query) 60 | export(query_error) 61 | export(read_table) 62 | export(register_return_formatter) 63 | export(reset_conn_defaults) 64 | export(result_dim) 65 | export(retrieve) 66 | export(retrieve_image) 67 | export(rollback) 68 | export(rotate_stack) 69 | export(savepoint) 70 | export(set_conn_defaults) 71 | export(set_default_password) 72 | export(set_encoding) 73 | export(set_error_verbosity) 74 | export(set_path) 75 | export(show_conn_stack) 76 | export(stow) 77 | export(stow_image) 78 | export(swap_conn) 79 | export(toggle_echo) 80 | export(trace_conn) 81 | export(trace_filename) 82 | export(untrace_conn) 83 | export(write_table) 84 | import(RApiSerialize) 85 | import(Rcpp) 86 | useDynLib(rpg, .registration = TRUE) 87 | -------------------------------------------------------------------------------- /R/RcppExports.R: -------------------------------------------------------------------------------- 1 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | connect_ <- function(keywords, values) { 5 | .Call(`_rpg_connect_`, keywords, values) 6 | } 7 | 8 | #' Database connection utilities 9 | #' 10 | #' Conection reporting and defaults 11 | #' 12 | #' @param opts a libpq connection string 13 | #' 14 | #' @details \code{ping} will ignore any keywords not directly 15 | #' related to the database host (e.g., username, dbname) as it 16 | #' does not connect; it only detect the server port is responding. 17 | #' 18 | #' @return \code{ping} returns one of the following: 19 | #' \tabular{ll}{ 20 | #' \code{PQPING_OK} \tab Server reachable \cr 21 | #' \code{PQPING_REJECT} \tab Server reachable but not accepting 22 | #' connections \cr 23 | #' \code{PQPING_NO_RESPONSE} \tab Server unreachable \cr 24 | #' \code{PQPING_NO_ATTEMPT} \tab Connection string is nonsense \cr} 25 | #' 26 | #' @author Timothy H. Keitt 27 | #' 28 | #' @examples 29 | #' \dontrun{ 30 | #' ping("connect_timeout = 3, host = www.keittlab.org") 31 | #' connect() 32 | #' get_conn_defaults() 33 | #' set_conn_defaults(dbname = "test") 34 | #' get_conn_defaults() 35 | #' reset_conn_defaults() 36 | #' get_conn_defaults() 37 | #' get_conn_defaults(all = TRUE) 38 | #' get_conn_info() 39 | #' get_conn_error() 40 | #' disconnect()} 41 | #' 42 | #' @export ping 43 | #' @rdname connection-utils 44 | ping <- function(opts = "") { 45 | .Call(`_rpg_ping`, opts) 46 | } 47 | 48 | disconnect_ <- function() { 49 | invisible(.Call(`_rpg_disconnect_`)) 50 | } 51 | 52 | clean_up_all <- function() { 53 | invisible(.Call(`_rpg_clean_up_all`)) 54 | } 55 | 56 | #' @return get_conn_error: an error string 57 | #' @export get_conn_error 58 | #' @rdname connection-utils 59 | get_conn_error <- function() { 60 | .Call(`_rpg_get_conn_error`) 61 | } 62 | 63 | get_conn_info_ <- function() { 64 | .Call(`_rpg_get_conn_info_`) 65 | } 66 | 67 | #' @return \code{result_dim} returns the number of tuples and fields 68 | #' @rdname query 69 | #' @export 70 | result_dim <- function() { 71 | .Call(`_rpg_result_dim`) 72 | } 73 | 74 | #' @return \code{get_tuple_info} returns an integer array with tuple information. 75 | #' @rdname query 76 | #' @export 77 | get_tuple_info <- function() { 78 | .Call(`_rpg_get_tuple_info`) 79 | } 80 | 81 | #' PostgreSQL query 82 | #' 83 | #' Issue a query to the current database connection 84 | #' 85 | #' @param sql a query string 86 | #' @param pars a character vector of substitution values 87 | #' 88 | #' @return \code{query} returns: 89 | #' \tabular{ll}{ 90 | #' PGRES_EMPTY_QUERY \tab The string sent to the server was empty \cr 91 | #' PGRES_COMMAND_OK \tab Successful completion of a command returning no data \cr 92 | #' PGRES_TUPLES_OK \tab Successful completion of a command returning data (such as a SELECT or SHOW) \cr 93 | #' PGRES_COPY_OUT \tab Copy Out (from server) data transfer started \cr 94 | #' PGRES_COPY_IN \tab Copy In (to server) data transfer started \cr 95 | #' PGRES_BAD_RESPONSE \tab The server's response was not understood. \cr 96 | #' PGRES_NONFATAL_ERROR \tab A nonfatal error (a notice or warning) occurred \cr 97 | #' PGRES_FATAL_ERROR \tab A fatal error occurred \cr 98 | #' PGRES_COPY_BOTH \tab Copy In/Out (to and from server) data transfer started. This is currently used only for streaming replication \cr} 99 | #' 100 | #' @author Timothy H. Keitt 101 | #' 102 | #' @seealso \code{\link{psql}} 103 | #' 104 | #' @examples 105 | #' \dontrun{ 106 | #' createdb("rpgtesting") 107 | #' connect("rpgtesting") 108 | #' begin() 109 | #' execute("DROP SCHEMA IF EXISTS rpgtesting CASCADE") 110 | #' execute("CREATE SCHEMA rpgtesting") 111 | #' execute("SET search_path TO rpgtesting") 112 | #' execute("DROP TABLE IF EXISTS test") 113 | #' execute("CREATE TABLE test (id integer, field text)") 114 | #' query("INSERT INTO test VALUES ($1, $2)", c(1, "test")) 115 | #' fetch("SELECT * FROM test") 116 | #' result_dim() 117 | #' fetch("SELECT * FROM testing") 118 | #' query_error() 119 | #' rollback() 120 | #' disconnect() 121 | #' dropdb("rpgtesting")} 122 | #' 123 | #' @rdname query 124 | #' @export query 125 | query <- function(sql = "", pars = NULL) { 126 | .Call(`_rpg_query`, sql, pars) 127 | } 128 | 129 | #' @return \code{query_error} returns an error string 130 | #' @export query_error 131 | #' @rdname query 132 | query_error <- function() { 133 | .Call(`_rpg_query_error`) 134 | } 135 | 136 | fetch_matrix <- function() { 137 | .Call(`_rpg_fetch_matrix`) 138 | } 139 | 140 | fetch_dataframe <- function() { 141 | .Call(`_rpg_fetch_dataframe`) 142 | } 143 | 144 | #' PostgeSQL connection tracing 145 | #' 146 | #' Functions to manage connection tracing 147 | #' 148 | #' @param filename where to send the tracing 149 | #' @param append if true, append to existing file 150 | #' @param remove if true, unlink the tracing file 151 | #' 152 | #' @details 153 | #' PostgeSQL tracing lets you observe all information 154 | #' passing between \code{rpg} and the database server. 155 | #' 156 | #' \code{trace_conn} begins tracing and \code{untrace_conn} 157 | #' stops tracing. 158 | #' 159 | #' @author Timothy H. Keitt 160 | #' 161 | #' @examples 162 | #' \dontrun{ 163 | #' createdb("rpgtesting") 164 | #' connect("rpgtesting") 165 | #' trace_conn() 166 | #' list_tables() 167 | #' dump_conn_trace(n = 40) 168 | #' untrace_conn(remove = TRUE) 169 | #' disconnect() 170 | #' dropdb("rpgtesting")} 171 | #' @rdname tracing 172 | #' @export 173 | trace_conn <- function(filename = "", append = FALSE) { 174 | invisible(.Call(`_rpg_trace_conn`, filename, append)) 175 | } 176 | 177 | #' @rdname tracing 178 | #' @export 179 | untrace_conn <- function(remove = FALSE) { 180 | invisible(.Call(`_rpg_untrace_conn`, remove)) 181 | } 182 | 183 | #' @return \code{trace_filename}: the name of the file containing 184 | #' trace information. 185 | #' 186 | #' @rdname tracing 187 | #' @export 188 | trace_filename <- function() { 189 | .Call(`_rpg_trace_filename`) 190 | } 191 | 192 | #' @param all if false return only defaults with settings 193 | #' @details \code{get_conn_defaults} returns a data frame containing 194 | #' all of the possible connection string keywords, the names of environment 195 | #' variables used to override the defaults, the compiled in default value 196 | #' and the current value of the keyword. 197 | #' @return \code{get_conn_defaults}: a data frame with defaults listed 198 | #' @rdname connection-utils 199 | #' @export 200 | get_conn_defaults <- function(all = FALSE) { 201 | .Call(`_rpg_get_conn_defaults`, all) 202 | } 203 | 204 | #' Miscelaneous functions 205 | #' 206 | #' Various utility functions 207 | #' 208 | #' @author Timothy H. Keitt 209 | #' 210 | #' @examples 211 | #' \dontrun{ 212 | #' # try connecting to default database 213 | #' createdb("rpgtesting") 214 | #' connect("rpgtesting") 215 | #' begin() 216 | #' 217 | #' libpq_version() 218 | #' encrypt_password("test", "tester") 219 | #' get_encoding() 220 | #' set_encoding("UTF8") 221 | #' set_error_verbosity("terse") 222 | #' set_error_verbosity("verbose") 223 | #' set_error_verbosity("default") 224 | #' enable_postgis() 225 | #' 226 | #' # cleanup 227 | #' rollback() 228 | #' disconnect() 229 | #' dropdb("rpgtesting")} 230 | #' 231 | #' @rdname misc 232 | #' @export 233 | libpq_version <- function() { 234 | .Call(`_rpg_libpq_version`) 235 | } 236 | 237 | #' @param passwd the password 238 | #' @param user the user name 239 | #' @rdname misc 240 | #' @export 241 | encrypt_password <- function(passwd, user) { 242 | .Call(`_rpg_encrypt_password`, passwd, user) 243 | } 244 | 245 | #' @rdname misc 246 | #' @export 247 | get_encoding <- function() { 248 | .Call(`_rpg_get_encoding`) 249 | } 250 | 251 | #' @param encoding the character encoding 252 | #' @rdname misc 253 | #' @export 254 | set_encoding <- function(encoding) { 255 | .Call(`_rpg_set_encoding`, encoding) 256 | } 257 | 258 | #' @param verbosity one of "terse", "default", "verbose" 259 | #' @rdname misc 260 | #' @export 261 | set_error_verbosity <- function(verbosity) { 262 | invisible(.Call(`_rpg_set_error_verbosity`, verbosity)) 263 | } 264 | 265 | check_transaction <- function() { 266 | .Call(`_rpg_check_transaction`) 267 | } 268 | 269 | prepare_ <- function(sql, name = "") { 270 | .Call(`_rpg_prepare_`, sql, name) 271 | } 272 | 273 | execute_prepared_ <- function(pars, name = "") { 274 | .Call(`_rpg_execute_prepared_`, pars, name) 275 | } 276 | 277 | num_prepared_params <- function(name = "") { 278 | .Call(`_rpg_num_prepared_params`, name) 279 | } 280 | 281 | #' Multiple PostgreSQL connections 282 | #' 283 | #' Manage multiple connections on a stack 284 | #' 285 | #' @details 286 | #' These functions allow you to store multiple connections on a stack. They are 287 | #' only used for their side-effects. \code{\link{rpg}} stores an active connection 288 | #' pointer internally. This pointer can be moved onto the stack and manipulated. 289 | #' Once on the stack, the pointer is no longer active. You must use 290 | #' \code{swap_conn} or \code{pop_conn} to reactive a pushed connection, or call 291 | #' \code{\link{connect}} to create a new active connection. 292 | #' 293 | #' \code{push_conn} pushes the current connection onto the connection stack 294 | #' leaving the active connection null. 295 | #' 296 | #' @examples 297 | #' \dontrun{ 298 | #' # make some databases 299 | #' dbs = paste0("rpgdb", 1:3) 300 | #' lapply(paste("createdb", dbs), system) 301 | #' 302 | #' # connect 303 | #' connect(dbname = dbs[1]); push_conn() 304 | #' connect(dbname = dbs[2]); push_conn() 305 | #' connect(dbname = dbs[3]); push_conn() 306 | #' 307 | #' show_conn_stack() 308 | #' rotate_stack() 309 | #' show_conn_stack() 310 | #' rotate_stack(2) 311 | #' show_conn_stack() 312 | #' pop_conn() 313 | #' show_conn_stack() 314 | #' get_conn_info("dbname") 315 | #' swap_conn() 316 | #' show_conn_stack() 317 | #' get_conn_info("dbname") 318 | #' pop_conn() 319 | #' show_conn_stack() 320 | #' pop_conn() 321 | #' show_conn_stack() 322 | #' disconnect() 323 | #' connect() 324 | #' lapply(paste("dropdb", dbs), system)} 325 | #' 326 | #' @rdname stack 327 | #' @export 328 | push_conn <- function() { 329 | invisible(.Call(`_rpg_push_conn`)) 330 | } 331 | 332 | #' @details 333 | #' \code{pop_conn} pops a connection off the stack and makes it active. Whatever 334 | #' connection was active when \code{pop_conn} is called will be disconnected and 335 | #' cleared. Use \code{swap_conn} to preserve the active connection. 336 | #' 337 | #' @rdname stack 338 | #' @export 339 | pop_conn <- function() { 340 | invisible(.Call(`_rpg_pop_conn`)) 341 | } 342 | 343 | #' @details 344 | #' \code{swap_conn} swaps the active connection with the connection on the top 345 | #' of the stack. If the stack is empty, the connection is swapped with a null 346 | #' connection. 347 | #' 348 | #' @rdname stack 349 | #' @export 350 | swap_conn <- function() { 351 | invisible(.Call(`_rpg_swap_conn`)) 352 | } 353 | 354 | #' @param n number of shifts 355 | #' @details 356 | #' \code{rotate_stack} moves the bottom of the stack to the top. 357 | #' 358 | #' @rdname stack 359 | #' @export 360 | rotate_stack <- function(n = 1L) { 361 | invisible(.Call(`_rpg_rotate_stack`, n)) 362 | } 363 | 364 | #' @details 365 | #' \code{show_conn_stack} returns a data frame with information about the 366 | #' connections on the stack. 367 | #' 368 | #' @rdname stack 369 | #' @export 370 | show_conn_stack <- function() { 371 | .Call(`_rpg_show_conn_stack`) 372 | } 373 | 374 | #' Asynchronous query processing 375 | #' 376 | #' Manage an asynchronous query 377 | #' 378 | #' @param sql a query string 379 | #' @param pars a vector of parameters 380 | #' 381 | #' @details 382 | #' These functions expose the asynchronous query interface from 383 | #' \code{libpq}. The function \code{async_query} issues a query. Its 384 | #' call is identical to \code{\link{query}} except that it will return 385 | #' immediately. When the issued command is ready, the function 386 | #' \code{async_status} will return a query status object exactly 387 | #' as \code{\link{query}}. Otherwise it will return \code{"BUSY"} to 388 | #' indicate the server has not finished or \code{"DONE"} to indicate 389 | #' there is nothing more to fetch. 390 | #' 391 | #' If \code{async_status} does not return \code{"DONE"}, then 392 | #' you should call \code{finish_async} to free pending results. Note 393 | #' that a call to \code{finish_async} may block until the server is finished 394 | #' processing the command. It calls \code{cancel} internally but there is 395 | #' no guarantee the command will abort. 396 | #' 397 | #' @return 398 | #' \code{async_query}: true if query was successfully sent (an invalid query 399 | #' will still return true) 400 | #' 401 | #' \code{async_status}: a results status object, possibly indicating an 402 | #' invalid query 403 | #' 404 | #' \code{is_busy}: a boolean 405 | #' 406 | #' @note In practice, you will be much better off using \code{\link{cursor}} 407 | #' as that will usually return very quickly even for large queries, and has 408 | #' the advantage of retrieving the results in chunks. You can call \code{cancel} 409 | #' while a cursor is active. The cursor will return \code{PGRES_FATAL_ERROR} if 410 | #' the \code{cancel} is effective. Alternately, issuing any query that sets the 411 | #' result status will have the same effect as \code{finish_async}. 412 | #' 413 | #' @author Timothy H. Keitt 414 | #' 415 | #' @examples 416 | #' \dontrun{ 417 | #' # create a database 418 | #' createdb("rpgtesting") 419 | #' connect("rpgtesting") 420 | #' begin() 421 | #' 422 | #' # write data frame contents 423 | #' data(mtcars) 424 | #' write_table(mtcars) 425 | #' 426 | #' # async processing on smallish result 427 | #' # this wont be interesting if your machine is very fast 428 | #' async_query("SELECT a.* FROM mtcars a, mtcars b") 429 | #' repeat 430 | #' { 431 | #' status = async_status() 432 | #' if ( status != "BUSY" ) break 433 | #' cat("busy...\n") 434 | #' Sys.sleep(1) 435 | #' } 436 | #' print(status) 437 | #' head(fetch()) 438 | #' finish_async() 439 | #' Sys.sleep(1) 440 | #' 441 | #' # async processing on larger result 442 | #' async_query("SELECT a.* FROM mtcars a, mtcars b, mtcars c") 443 | #' count = 0 444 | #' repeat 445 | #' { 446 | #' status = async_status() 447 | #' if ( status == "BUSY" ) 448 | #' { 449 | #' if ( count > 2 ) 450 | #' { 451 | #' cat("calling cancel...\n") 452 | #' cancel() 453 | #' } 454 | #' } 455 | #' else break 456 | #' cat("busy... \n") 457 | #' Sys.sleep(1) 458 | #' count = count + 1 459 | #' } 460 | #' print(status) 461 | #' finish_async() 462 | #' 463 | #' # you can run multiple queries with async_query 464 | #' rollback(); begin() 465 | #' write_table(mtcars) 466 | #' sql1 = "SELECT mpg FROM mtcars LIMIT 3" 467 | #' sql2 = "SELECT cyl FROM mtcars LIMIT 4" 468 | #' async_query(paste(sql1, sql2, sep = "; ")) 469 | #' while ( async_status() == "BUSY" ) NULL 470 | #' fetch() 471 | #' while ( is_busy() ) NULL 472 | #' async_status() 473 | #' fetch() 474 | #' finish_async() 475 | #' 476 | #' # issue an async query and come back later 477 | #' async_query(sql1) 478 | #' push_conn() 479 | #' connect("rpgtesting") 480 | #' 481 | #' # fails because of transaction isolation 482 | #' fetch(sql2) 483 | #' pop_conn() 484 | #' async_status() 485 | #' 486 | #' # results from sql1 487 | #' fetch() 488 | #' 489 | #' # this is automatic if you issue new queries 490 | #' finish_async() 491 | #' 492 | #' # cleanup 493 | #' rollback() 494 | #' disconnect() 495 | #' dropdb("rpgtesting")} 496 | #' 497 | #' @export 498 | #' @rdname async 499 | async_query <- function(sql = "", pars = NULL) { 500 | .Call(`_rpg_async_query`, sql, pars) 501 | } 502 | 503 | #' @details Any pending results will be lost if you call \code{\link{query}}, 504 | #' \code{\link{execute}} or \code{\link{fetch}} with a \code{sql} string prior 505 | #' to \code{async_query} returning \code{DONE}. If you need to issue queries 506 | #' while waiting on an async call, then use \code{\link{push_conn}} to save 507 | #' the query state, \code{\link{connect}} to make a new connetion, and then 508 | #' \code{\link{pop_conn}} followed by \code{async_status}. 509 | #' @export 510 | #' @rdname async 511 | async_status <- function() { 512 | .Call(`_rpg_async_status`) 513 | } 514 | 515 | #' @details \code{is_busy} is a slightly faster shortcut to check whether the 516 | #' server has completed the query. You must still call \code{async_status} to 517 | #' fetch the results. 518 | #' @export 519 | #' @rdname async 520 | is_busy <- function() { 521 | .Call(`_rpg_is_busy`) 522 | } 523 | 524 | #' @export 525 | #' @rdname async 526 | cancel <- function() { 527 | invisible(.Call(`_rpg_cancel`)) 528 | } 529 | 530 | #' @export 531 | #' @rdname async 532 | finish_async <- function() { 533 | invisible(.Call(`_rpg_finish_async`)) 534 | } 535 | 536 | exec_param_serialize <- function(sql, obj) { 537 | .Call(`_rpg_exec_param_serialize`, sql, obj) 538 | } 539 | 540 | fetch_stowed <- function(sql, par) { 541 | .Call(`_rpg_fetch_stowed`, sql, par) 542 | } 543 | 544 | #' @param pgoid the PostgreSQL type Oid 545 | #' @param f a function 546 | #' @details 547 | #' The function f must accept a vector of character values and return 548 | #' a vector of values formated appropriately. 549 | #' @rdname format-for-send 550 | #' @export 551 | register_return_formatter <- function(pgoid, f) { 552 | invisible(.Call(`_rpg_register_return_formatter`, pgoid, f)) 553 | } 554 | 555 | #' @rdname misc 556 | #' @export 557 | toggle_echo <- function() { 558 | invisible(.Call(`_rpg_toggle_echo`)) 559 | } 560 | 561 | -------------------------------------------------------------------------------- /R/sql.R: -------------------------------------------------------------------------------- 1 | #' Create an index 2 | #' 3 | #' Create and index on an existing table column 4 | #' 5 | #' @param tablename the name of the table 6 | #' @param columnname the name of the column 7 | #' @param schemaname specifically in this schema 8 | #' @param indexname optional index name to use 9 | #' @param unique if true, create a unique index 10 | #' @param using the index method 11 | #' @param collate set collation 12 | #' @param descending if true, sort descending 13 | #' @param tablespace create in this tablespace 14 | #' @param where restrict to rows matching predicate 15 | #' 16 | #' @details Build an index on a column. 17 | #' 18 | #' @author Timothy H. Keitt 19 | #' 20 | #' @export 21 | #' @aliases sql 22 | #' @rdname sql 23 | create_index = function(tablename, 24 | columnname, 25 | schemaname = NULL, 26 | indexname = NULL, 27 | unique = FALSE, 28 | using = NULL, 29 | collate = NULL, 30 | descending = FALSE, 31 | tablespace = NULL, 32 | where = NULL){ 33 | sp = savepoint(); on.exit(rollback(sp)) 34 | tableschema = format_tablename(tablename, schemaname) 35 | prefix = if (unique) "CREATE UNIQUE INDEX" else "CREATE INDEX" 36 | if (!is.null(indexname)) prefix = paste(prefix, indexname) 37 | if (!is.null(using)) tableschema = paste(tableschema, "USING", using) 38 | sql = paste(prefix, "ON", tableschema, "(", dquote_esc(columnname), ")") 39 | if (!is.null(collate)) sql = paste(sql, "COLLATE", collate) 40 | if (descending) sql = paste(sql, "DESC") 41 | if (!is.null(tablespace)) sql = paste(sql, "TABLESPACE", tablespace) 42 | if (!is.null(where)) sql = paste(sql, "WHERE", where) 43 | execute(sql); on.exit(commit(sp))} 44 | 45 | #' @export 46 | #' @rdname sql 47 | add_primary_key = function(tablename, 48 | columnname, 49 | schemaname = NULL){ 50 | sp = savepoint(); on.exit(rollback(sp)) 51 | tableschema = format_tablename(tablename, schemaname) 52 | execute("ALTER TABLE", tableschema, "ADD PRIMARY KEY (", columnname, ")") 53 | on.exit(commit(sp))} 54 | 55 | #' @param foreign_table the foreign table name 56 | #' @param foreign_column a key column (defaults to primary key) 57 | #' @param foreign_schema the schema of the foreign table 58 | #' @export 59 | #' @rdname sql 60 | add_foreign_key = function(tablename, 61 | columnname, 62 | foreign_table, 63 | foreign_column = NULL, 64 | schemaname = NULL, 65 | foreign_schema = schemaname){ 66 | sp = savepoint(); on.exit(rollback(sp)) 67 | tableschema = format_tablename(tablename, schemaname) 68 | foreign_tableschema = format_tablename(foreign_table, foreign_schema) 69 | execute("ALTER TABLE", tableschema, 70 | "ADD FOREIGN KEY (", columnname, ")", 71 | "REFERENCES", foreign_tableschema, 72 | ifelse(is.null(foreign_column), "", 73 | paste("(", foreign_column, ")"))) 74 | on.exit(commit(sp))} 75 | 76 | #' @export 77 | #' @rdname sql 78 | create_schema = function(schemaname){ 79 | execute("CREATE SCHEMA", schemaname)} 80 | 81 | #' PostgreSQL path variable 82 | #' 83 | #' Manipulate the PostgreSQL path variable 84 | #' 85 | #' @param ... path names 86 | #' @param default if true, manipulate database default 87 | #' @param no_dup do not add if path exists 88 | #' 89 | #' @export 90 | #' @rdname path 91 | set_path = function(..., default = FALSE) 92 | { 93 | sp = savepoint() 94 | on.exit(rollback(sp)) 95 | if (default) 96 | execute("ALTER DATABASE", get_conn_info("dbname"), 97 | "SET search_path TO", paste(..., sep = ", ")) else 98 | execute("SET search_path TO", paste(..., sep = ", ")) 99 | on.exit(commit(sp)) 100 | } 101 | 102 | #' @export 103 | #' @rdname path 104 | get_path = function(default = FALSE) 105 | if (default) 106 | { 107 | path = get_path() 108 | on.exit(set_path(path)) 109 | set_path("default") 110 | return(get_path()) 111 | } else 112 | fetch("show search_path")[[1]] 113 | 114 | #' @export 115 | #' @rdname path 116 | append_path = function(..., default = FALSE, no_dup = TRUE) 117 | if (no_dup && any(path_contains(..., default = default))) 118 | warning("Path not updated") else 119 | set_path(get_path(default = default), ..., default = default) 120 | 121 | #' @export 122 | #' @rdname path 123 | prepend_path = function(..., default = FALSE, no_dup = TRUE) 124 | if (no_dup && any(path_contains(..., default = default))) 125 | warning("Path not updated") else 126 | set_path(..., get_path(default = default), default = default) 127 | 128 | #' @export 129 | #' @rdname path 130 | path_contains = function(..., default = FALSE) 131 | sapply(list(...), grepl, x = strsplit(get_path(default = default), ", ", fixed = TRUE)) 132 | 133 | #' @param columntype the column SQL type 134 | #' @rdname sql 135 | #' @export 136 | add_column = function(columnname, columntype, tablename, schemaname = NULL) 137 | { 138 | sp = savepoint() 139 | on.exit(rollback(sp)) 140 | tableschema = format_tablename(tablename, schemaname) 141 | status = execute("ALTER TABLE", tableschema, "ADD COLUMN", columnname, columntype) 142 | on.exit(commit(sp)) 143 | return(status) 144 | } 145 | 146 | #' @param name name of the database 147 | #' @rdname sql 148 | #' @export 149 | createdb = function(name) 150 | { 151 | execute("CREATE DATABASE", name) 152 | } 153 | 154 | #' @param if_exists don't fail on missing database 155 | #' @rdname sql 156 | #' @export 157 | dropdb = function(name, if_exists = TRUE) 158 | { 159 | execute("DROP DATABASE", if (if_exists) "IF EXISTS", name) 160 | } 161 | 162 | 163 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | .onLoad = function(libname, pkgname) { return(invisible()) } 2 | 3 | .onUnload = function(libpath){ 4 | clean_up_all(); set_prompt() 5 | return(invisible())} 6 | 7 | set_prompt = function(){ 8 | if(get_conn_info("status.ok")) 9 | options(prompt = paste0("db:", get_conn_info("dbname"), "> ")) 10 | else 11 | options(prompt = "> ")} 12 | 13 | #' Convert R objects to strings 14 | #' 15 | #' Prepare R objects for sending to postgresql 16 | #' 17 | #' @param obj any object 18 | #' 19 | #' @details R objects that will be written to postgresql must be converted to 20 | #' characters as all data is transferred to the server as text. The S3 method 21 | #' \code{foramt_for_send} accomplishes this. It accepts any object and returns 22 | #' a character representation. 23 | #' 24 | #' You can define new conversions by supplying your own S3 override of 25 | #' \code{format_for_send}. 26 | #' 27 | #' @rdname format-for-send 28 | #' @export 29 | format_for_send = function(obj) 30 | { 31 | UseMethod("format_for_send", obj) 32 | } 33 | 34 | #' @export 35 | format_for_send.default = function(obj) as.character(obj) 36 | 37 | #' @export 38 | format_for_send.list = function(obj) 39 | { 40 | unlist(lapply(obj, format_for_send)) 41 | } 42 | 43 | #' @export 44 | format_for_send.data.frame = function(obj) 45 | { 46 | unlist(lapply(obj, format_for_send)) 47 | } 48 | 49 | #' @export 50 | format_for_send.Date = function(obj) 51 | { 52 | as.character(as.POSIXlt.Date(obj)) 53 | } 54 | 55 | pg_type = function(x) 56 | { 57 | switch(class(x)[[1]], 58 | numeric = switch(typeof(x), 59 | double = "double precision", 60 | integer = "integer", 61 | "text"), 62 | integer = "integer", 63 | double = "double precision", 64 | logical = "boolean", 65 | Date = "date", 66 | "text") 67 | } 68 | 69 | #' @export 70 | print.conn.info = function(x, ...) 71 | { 72 | print(as.matrix(unclass(x)), ...) 73 | } 74 | 75 | #' @export 76 | print.pq.error.message = function(x, ...) 77 | { 78 | cat(x) 79 | invisible(x) 80 | } 81 | 82 | print.message = function(x, terminate = "\n") 83 | { 84 | if (!is.null(x) && nchar(x) > 0) 85 | cat(x, terminate) 86 | invisible(x) 87 | } 88 | 89 | is_non_empty_string = function(x) 90 | { 91 | if (is.null(x)) return(FALSE) 92 | if (!any(nzchar(x))) return(FALSE) 93 | return(TRUE) 94 | } 95 | 96 | #' @export 97 | print.pq.status = function(x, ...) 98 | { 99 | if (getOption("verbose")) print.message(x) 100 | error.message = attr(x, "error.message") 101 | if (is_non_empty_string(error.message)) 102 | print.message(error.message) 103 | else 104 | { 105 | command.status = attr(x, "command.status") 106 | if (is_non_empty_string(command.status)) 107 | print.message(command.status) 108 | else if (x %in% c("PGRES_FATAL_ERROR", "BUSY", "DONE")) 109 | print.message(x) 110 | } 111 | invisible(x) 112 | } 113 | 114 | as.csv = function(...) 115 | { 116 | paste0(..., collapse = ", ") 117 | } 118 | 119 | dquote_esc = function(...) 120 | { 121 | gsub("\"+", "\"", paste0(paste0("\"", ...), "\"")) 122 | } 123 | 124 | format_tablename = function(tablename, schemaname = NULL) 125 | { 126 | if (is.null(schemaname)) 127 | dquote_esc(tablename) 128 | else 129 | paste(dquote_esc(schemaname), dquote_esc(tablename), sep = ".") 130 | } 131 | 132 | handle_row_names = function(a, b) 133 | { 134 | if (!is.null(b)) 135 | { 136 | a = data.frame(row.names(a), a, stringsAsFactors = FALSE) 137 | names(a)[1] = b 138 | } 139 | return(a) 140 | } 141 | 142 | primary_key_name = function(tablename) 143 | { 144 | unlist(fetch("SELECT pg_attribute.attname as pkey 145 | FROM pg_index, pg_class, pg_attribute 146 | WHERE pg_class.oid = $1::regclass 147 | AND indrelid = pg_class.oid 148 | AND pg_attribute.attrelid = pg_class.oid 149 | AND pg_attribute.attnum = any(pg_index.indkey) 150 | AND indisprimary", tablename)) 151 | } 152 | 153 | unique_name = function() 154 | { 155 | dquote_esc(uuid::UUIDgenerate()) 156 | } 157 | 158 | unique_statement_id = function() 159 | { 160 | res = uuid::UUIDgenerate() 161 | paste0("stmt", gsub("-", "", res)) 162 | } 163 | 164 | table_exists = function(table, schema = NULL) 165 | { 166 | sql = "select count(*) > 0 from pg_catalog.pg_tables" 167 | if (is.null(schema)) 168 | sql = paste(sql, "where tablename = $1") 169 | else 170 | sql = paste(sql, "where tablename = $1 and schemaname = $2") 171 | fetch(sql, strip_quotes(c(table, schema)))[[1]] 172 | } 173 | 174 | strip_quotes = function(x) 175 | { 176 | gsub("\"", "", x) 177 | } 178 | 179 | proc_psql_opts = function(psql_opts = "") 180 | { 181 | if (nchar(psql_opts) == 0 && get_conn_info("status.ok")) 182 | { 183 | host = get_conn_info("host") 184 | dbnm = get_conn_info("dbname") 185 | port = get_conn_info("port") 186 | user = get_conn_info("user") 187 | if (!is.null(host)) psql_opts = paste(psql_opts, "-h", host) 188 | if (!is.null(dbnm)) psql_opts = paste(psql_opts, "-d", dbnm) 189 | if (!is.null(port)) psql_opts = paste(psql_opts, "-p", port) 190 | if (!is.null(user)) psql_opts = paste(psql_opts, "-U", user) 191 | } 192 | psql_opts = paste(psql_opts, "-n -q -w -1") 193 | return(psql_opts) 194 | } 195 | 196 | proc_psql_passwd = function(psql_command) 197 | { 198 | if (get_conn_info("status.ok") && 199 | get_conn_info("password.supplied")) 200 | psql_command = paste0("PGPASSWORD=", 201 | get_conn_info("password.used"), 202 | " ", psql_command) 203 | return(psql_command) 204 | } 205 | 206 | run_examples = function() 207 | { 208 | eval(utils::example(ping, run.dontrun = T), globalenv()) 209 | eval(utils::example(connect, run.dontrun = T), globalenv()) 210 | eval(utils::example(query, run.dontrun = T), globalenv()) 211 | eval(utils::example(trace_conn, run.dontrun = T), globalenv()) 212 | eval(utils::example(libpq_version, run.dontrun = T), globalenv()) 213 | eval(utils::example(prepare, run.dontrun = T), globalenv()) 214 | eval(utils::example(push_conn, run.dontrun = T), globalenv()) 215 | eval(utils::example(async_query, run.dontrun = T), globalenv()) 216 | eval(utils::example(list_tables, run.dontrun = T), globalenv()) 217 | eval(utils::example(write_table, run.dontrun = T), globalenv()) 218 | eval(utils::example(cursor, run.dontrun = T), globalenv()) 219 | eval(utils::example(copy_to, run.dontrun = T), globalenv()) 220 | eval(utils::example(savepoint, run.dontrun = T), globalenv()) 221 | eval(utils::example(stow, run.dontrun = T), globalenv()) 222 | invisible() 223 | } 224 | 225 | check_schema = function(schemaname) 226 | { 227 | sql = paste("select count(*) = 0 from", 228 | "information_schema.schemata", 229 | "where schema_name = $1") 230 | res = fetch(sql, schemaname) 231 | if (inherits(res, "pg.status")) stop(res) 232 | if (res[[1]]) execute("create schema", dquote_esc(schemaname)) 233 | } 234 | 235 | check_stow = function(tablename, schemaname) 236 | { 237 | check_schema(schemaname) 238 | sql = "SELECT count(*) = 0 239 | FROM information_schema.tables 240 | WHERE table_name = $1" 241 | res = fetch(sql, tablename) 242 | if (inherits(res, "pg.status")) stop(res) 243 | if (res[[1]]) 244 | execute("CREATE TABLE", 245 | format_tablename(tablename, schemaname), 246 | "(objname TEXT PRIMARY KEY, object BYTEA,", 247 | "stamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP(0))") 248 | } 249 | 250 | get_pw = function() 251 | getPass::getPass("Enter password:") 252 | 253 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "rpg" 3 | author: "Timothy H. Keitt" 4 | date: "02/08/2017" 5 | output: 6 | html_document: 7 | keep_md: yes 8 | --- 9 | 10 | [![CRAN Version](http://www.r-pkg.org/badges/version/rpg)](http://www.r-pkg.org/badges/version/rpg) [![CRAN Downloads](http://cranlogs.r-pkg.org/badges/rpg)](http://cran.rstudio.com/web/packages/rpg/index.html) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/thk686/rpg?branch=master&svg=true)](https://ci.appveyor.com/project/thk686/rpg) [![Travis-CI Build Status](https://travis-ci.org/thk686/rpg.svg?branch=master)](https://travis-ci.org/thk686/rpg) [![Depsy](http://depsy.org/api/package/cran/rpg/badge.svg)](http://depsy.org/package/r/rpg) 11 | 12 | This package wraps PostgreSQL's libpq, a library for interacting with a PostreSQL database. Unlike other database access packages for R, ```rpg``` is designed to be specific to PostgreSQL and, as such, exposes a more of the functionality of libpq. A great deal of thought went into making ```rpg``` simple to use. The major difference between ```rpg``` and most other database packages is that ```rpg``` does not use an object-oriented model. There are no connection objects, result objects and so on. This simplifies the interface and makes using ```rpg``` a lot like using psql, PostgreSQL's command line interface. I basically wrote ```rpg``` as a nice comfy environment for my own work. If you are building infrastructure, you probably want to investigate ```DBI``` and [RPostgres](https://github.com/rstats-db/RPostgres). There is also the excellent [RPostgreSQL](https://cran.r-project.org/web/packages/RPostgreSQL/index.html) package on CRAN. 13 | 14 | ### Installation 15 | 16 | ``` 17 | install.packages(rpg) # Released 18 | devtools::install_github("thk686/rpg") # Development 19 | ``` 20 | 21 | ### Queries 22 | 23 | ```rpg``` supports parameterized queries and prepared statements. 24 | 25 | ```{r} 26 | library(rpg) 27 | createdb("exampledb"); connect("exampledb") 28 | data(mtcars); write_table(mtcars) 29 | fetch("select * from mtcars where mpg > $1", 30) 30 | prepared = prepare("select * from mtcars where mpg > $1") 31 | prepared(25); fetch(); prepared(30); fetch() 32 | ``` 33 | 34 | ### Connection stack 35 | 36 | Even though the database connection is implicit, you are not restricted to a single connection. Connections can be managed on a stack. 37 | 38 | ```{r} 39 | push_conn() 40 | createdb("exampledb2"); connect("exampledb2") 41 | data(iris); write_table(iris); list_tables() 42 | swap_conn(); list_tables() 43 | show_conn_stack() 44 | swap_conn(); describe_table("iris") 45 | pop_conn(); get_conn_info("dbname") 46 | dropdb("exampledb2") 47 | ``` 48 | 49 | ### Database cursors and foreach 50 | 51 | The ```rpg``` package integrates nicely with the iterators package. This allows you to use ```foreach``` to iterate over query results. This is perhaps the most unique feature of ```rpg```. 52 | 53 | ```{r} 54 | library(foreach) 55 | c1 = cursor("SELECT * FROM mtcars", by = 8) 56 | x = foreach(i = c1, .combine = rbind) %do% { i$mpg } 57 | print(x, digits = 2) 58 | ``` 59 | 60 | This usage is compatible with ```%dopar%```; you can access these cursors from multiple threads of execution and even across a heterogeneous cluster of machines. See the documentation for ```cursor``` for an example. 61 | 62 | Note: after some additional experimentation, I have concluded that parallel processing of cursors in PostgreSQL does not in fact work. You can iterate over a cursor on multiple backends. However it appears that only one of these backends will do any work, probably to ensure the access is serialized. My guess is that requests are forwarded to the portal where the cursor was opened. 63 | 64 | ### Asynchronous queries 65 | 66 | You can submit asynchronous queries with ```rpg```. When combined with the connection stack, this allows you to launch queries, push the connection, make a new connection while the first query is completing. By swapping the first connection back to the active state, you can then check for completion or try to cancel the transaction. 67 | 68 | ```{r} 69 | async_query("SELECT a.* FROM mtcars a, mtcars b, mtcars c") # >30,000 rows 70 | count = 0 71 | repeat { 72 | status = async_status() 73 | if (status == "BUSY") { 74 | if (count > 2) { 75 | cat("calling cancel...\n") 76 | cancel() }} 77 | else break 78 | cat("busy... \n") 79 | Sys.sleep(1) 80 | count = count + 1 } 81 | print(status) 82 | finish_async() 83 | ``` 84 | 85 | ### Transactions and save points 86 | 87 | A PostgreSQL-specific feature are save points for nested transactions. ```rpg``` provides a convenient wrapper. 88 | 89 | ```{r} 90 | sp1 = savepoint(); write_table(iris) 91 | sp2 = savepoint(); data(Loblolly); write_table(Loblolly); list_tables() 92 | rollback(sp2); list_tables() 93 | rollback(sp1); list_tables() 94 | ``` 95 | 96 | ### Object serialization and storage 97 | 98 | The ```stow``` and ```stow.image``` functions write entire R objects into a database. You can stow your entire working environment and reload it anywhere else you can reconnect to the database. (A facility listing and commenting images is in the works.) 99 | 100 | ```{r} 101 | stow("mtcars") 102 | rm(list = objects()) 103 | ls() 104 | list_stowed() 105 | retrieve("mtcars") 106 | ls() 107 | 108 | disconnect() 109 | dropdb("exampledb") 110 | ``` 111 | 112 | ### Additional features 113 | 114 | 1. Intelligent handling of passwords: ```rpg``` will query for the password only if it is needed. You can set a default password. 115 | 1. Easy creation of connection aliases: call ```make_service``` and your connection settings will be saved as a named service. You only have to type complex connection options once. If you used a password, that will be saved as well. 116 | 1. Lots of options for getting and setting connection options and defaults. 117 | 1. Easy tracing of data flowing between client and server. 118 | 1. High bandwidth options for reading/writing bulk data from/to the database. 119 | 120 | ### News 121 | 122 | 2/7/17 -- Gave up trying to build libpq on the fly and instead borrowed the excellent work done by the [RPostgres](https://github.com/rstats-db/RPostgres) team. RPostgres is looking very promising for DBI work. 123 | 124 | 4/15/16 -- I ripped out and replaced the build setup. I was using the autoconf bits and libpq files distributed with RPostgreSQL (a very good package you should check out). However it had a few peculiarities, like never using the included libpq on Linux. Also, I could not check the libpq version number. So now the package will check your postgres install using the pg_config command and if its not found or the version is not new enough, then libpq is downloaded and built. 125 | 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rpg 2 | Timothy H. Keitt 3 | 02/08/2017 4 | 5 | [![CRAN Version](http://www.r-pkg.org/badges/version/rpg)](http://www.r-pkg.org/badges/version/rpg) [![CRAN Downloads](http://cranlogs.r-pkg.org/badges/rpg)](http://cran.rstudio.com/web/packages/rpg/index.html) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/thk686/rpg?branch=master&svg=true)](https://ci.appveyor.com/project/thk686/rpg) [![Travis-CI Build Status](https://travis-ci.org/thk686/rpg.svg?branch=master)](https://travis-ci.org/thk686/rpg) [![Depsy](http://depsy.org/api/package/cran/rpg/badge.svg)](http://depsy.org/package/r/rpg) 6 | 7 | This package wraps PostgreSQL's libpq, a library for interacting with a PostreSQL database. Unlike other database access packages for R, ```rpg``` is designed to be specific to PostgreSQL and, as such, exposes a more of the functionality of libpq. A great deal of thought went into making ```rpg``` simple to use. The major difference between ```rpg``` and most other database packages is that ```rpg``` does not use an object-oriented model. There are no connection objects, result objects and so on. This simplifies the interface and makes using ```rpg``` a lot like using psql, PostgreSQL's command line interface. I basically wrote ```rpg``` as a nice comfy environment for my own work. If you are building infrastructure, you probably want to investigate ```DBI``` and [RPostgres](https://github.com/rstats-db/RPostgres). There is also the excellent [RPostgreSQL](https://cran.r-project.org/web/packages/RPostgreSQL/index.html) package on CRAN. 8 | 9 | ### Installation 10 | 11 | ``` 12 | install.packages(rpg) # Released 13 | devtools::install_github("thk686/rpg") # Development 14 | ``` 15 | 16 | ### Queries 17 | 18 | ```rpg``` supports parameterized queries and prepared statements. 19 | 20 | 21 | ```r 22 | library(rpg) 23 | createdb("exampledb"); connect("exampledb") 24 | ``` 25 | 26 | ``` 27 | ## No connection... attempting reset... nope... trying default... that worked. 28 | ``` 29 | 30 | ``` 31 | ## CREATE DATABASE 32 | ``` 33 | 34 | ```r 35 | data(mtcars); write_table(mtcars) 36 | ``` 37 | 38 | ``` 39 | ## Initiating new transaction block... done. 40 | ``` 41 | 42 | ``` 43 | ## INSERT 0 1 44 | ``` 45 | 46 | ```r 47 | fetch("select * from mtcars where mpg > $1", 30) 48 | ``` 49 | 50 | ``` 51 | ## mpg cyl disp hp drat wt qsec vs am gear carb 52 | ## 1 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 53 | ## 2 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 54 | ## 3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 55 | ## 4 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 56 | ``` 57 | 58 | ```r 59 | prepared = prepare("select * from mtcars where mpg > $1") 60 | prepared(25); fetch(); prepared(30); fetch() 61 | ``` 62 | 63 | ``` 64 | ## SELECT 6 65 | ``` 66 | 67 | ``` 68 | ## mpg cyl disp hp drat wt qsec vs am gear carb 69 | ## 1 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 70 | ## 2 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 71 | ## 3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 72 | ## 4 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 73 | ## 5 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 74 | ## 6 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 75 | ``` 76 | 77 | ``` 78 | ## SELECT 4 79 | ``` 80 | 81 | ``` 82 | ## mpg cyl disp hp drat wt qsec vs am gear carb 83 | ## 1 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 84 | ## 2 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 85 | ## 3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 86 | ## 4 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 87 | ``` 88 | 89 | ### Connection stack 90 | 91 | Even though the database connection is implicit, you are not restricted to a single connection. Connections can be managed on a stack. 92 | 93 | 94 | ```r 95 | push_conn() 96 | createdb("exampledb2"); connect("exampledb2") 97 | ``` 98 | 99 | ``` 100 | ## No connection... attempting reset... nope... trying default... that worked. 101 | ``` 102 | 103 | ``` 104 | ## CREATE DATABASE 105 | ``` 106 | 107 | ```r 108 | data(iris); write_table(iris); list_tables() 109 | ``` 110 | 111 | ``` 112 | ## Initiating new transaction block... done. 113 | ``` 114 | 115 | ``` 116 | ## INSERT 0 1 117 | ``` 118 | 119 | ``` 120 | ## [1] "iris" 121 | ``` 122 | 123 | ```r 124 | swap_conn(); list_tables() 125 | ``` 126 | 127 | ``` 128 | ## [1] "mtcars" 129 | ``` 130 | 131 | ```r 132 | show_conn_stack() 133 | ``` 134 | 135 | ``` 136 | ## host dbname status.ok 137 | ## 1 /tmp exampledb2 TRUE 138 | ``` 139 | 140 | ```r 141 | swap_conn(); describe_table("iris") 142 | ``` 143 | 144 | ``` 145 | ## schema table column position type default 146 | ## 1 public iris Sepal.Length 1 double precision 147 | ## 2 public iris Sepal.Width 2 double precision 148 | ## 3 public iris Petal.Length 3 double precision 149 | ## 4 public iris Petal.Width 4 double precision 150 | ## 5 public iris Species 5 text 151 | ``` 152 | 153 | ```r 154 | pop_conn(); get_conn_info("dbname") 155 | ``` 156 | 157 | ``` 158 | ## [1] "exampledb" 159 | ``` 160 | 161 | ```r 162 | dropdb("exampledb2") 163 | ``` 164 | 165 | ``` 166 | ## DROP DATABASE 167 | ``` 168 | 169 | ### Database cursors and foreach 170 | 171 | The ```rpg``` package integrates nicely with the iterators package. This allows you to use ```foreach``` to iterate over query results. This is perhaps the most unique feature of ```rpg```. 172 | 173 | 174 | ```r 175 | library(foreach) 176 | c1 = cursor("SELECT * FROM mtcars", by = 8) 177 | ``` 178 | 179 | ``` 180 | ## Initiating new transaction block... done. 181 | ``` 182 | 183 | ```r 184 | x = foreach(i = c1, .combine = rbind) %do% { i$mpg } 185 | print(x, digits = 2) 186 | ``` 187 | 188 | ``` 189 | ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 190 | ## result.1 21 21 23 21 19 18 14 24 191 | ## result.2 23 19 18 16 17 15 10 10 192 | ## result.3 15 32 30 34 22 16 15 13 193 | ## result.4 19 27 26 30 16 20 15 21 194 | ``` 195 | 196 | This usage is compatible with ```%dopar%```; you can access these cursors from multiple threads of execution and even across a heterogeneous cluster of machines. See the documentation for ```cursor``` for an example. 197 | 198 | Note: after some additional experimentation, I have concluded that parallel processing of cursors in PostgreSQL does not in fact work. You can iterate over a cursor on multiple backends. However it appears that only one of these backends will do any work, probably to ensure the access is serialized. My guess is that requests are forwarded to the portal where the cursor was opened. 199 | 200 | ### Asynchronous queries 201 | 202 | You can submit asynchronous queries with ```rpg```. When combined with the connection stack, this allows you to launch queries, push the connection, make a new connection while the first query is completing. By swapping the first connection back to the active state, you can then check for completion or try to cancel the transaction. 203 | 204 | 205 | ```r 206 | async_query("SELECT a.* FROM mtcars a, mtcars b, mtcars c") # >30,000 rows 207 | ``` 208 | 209 | ``` 210 | ## [1] TRUE 211 | ``` 212 | 213 | ```r 214 | count = 0 215 | repeat { 216 | status = async_status() 217 | if (status == "BUSY") { 218 | if (count > 2) { 219 | cat("calling cancel...\n") 220 | cancel() }} 221 | else break 222 | cat("busy... \n") 223 | Sys.sleep(1) 224 | count = count + 1 } 225 | ``` 226 | 227 | ``` 228 | ## busy... 229 | ## busy... 230 | ## busy... 231 | ## calling cancel... 232 | ## busy... 233 | ## calling cancel... 234 | ## busy... 235 | ## calling cancel... 236 | ## busy... 237 | ``` 238 | 239 | ```r 240 | print(status) 241 | ``` 242 | 243 | ``` 244 | ## ERROR: canceling statement due to user request 245 | ## 246 | ``` 247 | 248 | ```r 249 | finish_async() 250 | ``` 251 | 252 | ### Transactions and save points 253 | 254 | A PostgreSQL-specific feature are save points for nested transactions. ```rpg``` provides a convenient wrapper. 255 | 256 | 257 | ```r 258 | sp1 = savepoint(); write_table(iris) 259 | ``` 260 | 261 | ``` 262 | ## Error in current transaction: rolling back... done. 263 | ## Initiating new transaction block... done. 264 | ``` 265 | 266 | ``` 267 | ## INSERT 0 1 268 | ``` 269 | 270 | ```r 271 | sp2 = savepoint(); data(Loblolly); write_table(Loblolly); list_tables() 272 | ``` 273 | 274 | ``` 275 | ## INSERT 0 1 276 | ``` 277 | 278 | ``` 279 | ## [1] "Loblolly" "iris" "mtcars" 280 | ``` 281 | 282 | ```r 283 | rollback(sp2); list_tables() 284 | ``` 285 | 286 | ``` 287 | ## ROLLBACK 288 | ``` 289 | 290 | ``` 291 | ## [1] "iris" "mtcars" 292 | ``` 293 | 294 | ```r 295 | rollback(sp1); list_tables() 296 | ``` 297 | 298 | ``` 299 | ## ROLLBACK 300 | ``` 301 | 302 | ``` 303 | ## [1] "mtcars" 304 | ``` 305 | 306 | ### Object serialization and storage 307 | 308 | The ```stow``` and ```stow.image``` functions write entire R objects into a database. You can stow your entire working environment and reload it anywhere else you can reconnect to the database. (A facility listing and commenting images is in the works.) 309 | 310 | 311 | ```r 312 | stow("mtcars") 313 | ``` 314 | 315 | ``` 316 | ## Initiating new transaction block... done. 317 | ``` 318 | 319 | ```r 320 | rm(list = objects()) 321 | ls() 322 | ``` 323 | 324 | ``` 325 | ## character(0) 326 | ``` 327 | 328 | ```r 329 | list_stowed() 330 | ``` 331 | 332 | ``` 333 | ## objname stamp 334 | ## 1 mtcars 2017-10-27 12:16:01-05 335 | ``` 336 | 337 | ```r 338 | retrieve("mtcars") 339 | ls() 340 | ``` 341 | 342 | ``` 343 | ## [1] "mtcars" 344 | ``` 345 | 346 | ```r 347 | disconnect() 348 | dropdb("exampledb") 349 | ``` 350 | 351 | ``` 352 | ## No connection... attempting reset... nope... trying default... that worked. 353 | ``` 354 | 355 | ``` 356 | ## DROP DATABASE 357 | ``` 358 | 359 | ### Additional features 360 | 361 | 1. Intelligent handling of passwords: ```rpg``` will query for the password only if it is needed. You can set a default password. 362 | 1. Easy creation of connection aliases: call ```make_service``` and your connection settings will be saved as a named service. You only have to type complex connection options once. If you used a password, that will be saved as well. 363 | 1. Lots of options for getting and setting connection options and defaults. 364 | 1. Easy tracing of data flowing between client and server. 365 | 1. High bandwidth options for reading/writing bulk data from/to the database. 366 | 367 | ### News 368 | 369 | 2/7/17 -- Gave up trying to build libpq on the fly and instead borrowed the excellent work done by the [RPostgres](https://github.com/rstats-db/RPostgres) team. RPostgres is looking very promising for DBI work. 370 | 371 | 4/15/16 -- I ripped out and replaced the build setup. I was using the autoconf bits and libpq files distributed with RPostgreSQL (a very good package you should check out). However it had a few peculiarities, like never using the included libpq on Linux. Also, I could not check the libpq version number. So now the package will check your postgres install using the pg_config command and if its not found or the version is not new enough, then libpq is downloaded and built. 372 | 373 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | # Adapt as necessary starting from here 14 | 15 | build_script: 16 | - travis-tool.sh install_deps 17 | 18 | test_script: 19 | - travis-tool.sh run_tests 20 | 21 | on_failure: 22 | - 7z a failure.zip *.Rcheck\* 23 | - appveyor PushArtifact failure.zip 24 | 25 | artifacts: 26 | - path: '*.Rcheck\**\*.log' 27 | name: Logs 28 | 29 | - path: '*.Rcheck\**\*.out' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.fail' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.Rout' 36 | name: Logs 37 | 38 | - path: '\*_*.tar.gz' 39 | name: Bits 40 | 41 | - path: '\*_*.zip' 42 | name: Bits 43 | -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rm -f src/Makevars 3 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Anticonf (tm) script by Jeroen Ooms & Murat Tasan (2017) 3 | # This script will prefer cflags (specifically includefile dirs) and lib dirs 4 | # in the following order of precedence: 5 | # (1) INCLUDE_DIR or LIB_DIR entered explicitly on the command line, e.g. 6 | # R CMD INSTALL --configure-vars='INCLUDE_DIR=/.../include LIB_DIR=/.../lib' 7 | # (2) Values found via 'pkg-config' for the libpq package. 8 | # (3) Values found via 'pg_config' given a PostgreSQL installation. 9 | 10 | # Library settings 11 | PKG_CONFIG_NAME="libpq" 12 | PKG_DEB_NAME="libpq-dev" 13 | PKG_RPM_NAME="postgresql-devel" 14 | PKG_AMZ_RPM_NAMES="postgreql8-devel, psstgresql92-devel, postgresql93-devel, or postgresql94-devel" 15 | PKG_CSW_NAME="postgresql_dev" 16 | PKG_BREW_NAME="postgresql" 17 | PKG_TEST_HEADER="" 18 | PKG_LIBS="-lpq" 19 | PKG_LIBS_STATIC="-lpq -lssl -lcrypto -lldap" 20 | 21 | # pkg-config values (if available) 22 | if [ $(command -v pkg-config) ]; then 23 | PKGCONFIG_CFLAGS=$(pkg-config --cflags --silence-errors ${PKG_CONFIG_NAME}) 24 | PKGCONFIG_LIBS=$(pkg-config --libs --silence-errors ${PKG_CONFIG_NAME}) 25 | fi 26 | 27 | # pg_config vlaues (if available) 28 | if [ $(command -v pg_config) ]; then 29 | PG_INC_DIR=$(pg_config --includedir) 30 | PG_LIB_DIR=$(pg_config --libdir) 31 | fi 32 | 33 | # Note that cflags may be empty in case of success 34 | if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then 35 | echo "Found INCLUDE_DIR and/or LIB_DIR!" 36 | PKG_CFLAGS="-I$INCLUDE_DIR $PKG_CFLAGS" 37 | PKG_LIBS="-L$LIB_DIR $PKG_LIBS" 38 | elif [ "$PKGCONFIG_CFLAGS" ] || [ "$PKGCONFIG_LIBS" ]; then 39 | echo "Using pkg-config cflags and libs!" 40 | PKG_CFLAGS=${PKGCONFIG_CFLAGS} 41 | PKG_LIBS=${PKGCONFIG_LIBS} 42 | elif [ "$PG_INC_DIR" ] || [ "$PG_LIB_DIR" ]; then 43 | echo "Using pg_config includedir and libdir!" 44 | PKG_CFLAGS="-I${PG_INC_DIR}" 45 | PKG_LIBS="-L${PG_LIB_DIR} ${PKG_LIBS}" 46 | elif [[ "$OSTYPE" == "darwin"* ]]; then 47 | if [ $(command -v brew) ]; then 48 | BREWDIR=$(brew --prefix) 49 | else 50 | curl -sfL "https://jeroen.github.io/autobrew/$PKG_BREW_NAME" > autobrew 51 | source autobrew 52 | fi 53 | PKG_CFLAGS="-I$BREWDIR/opt/postgresql/include" 54 | PKG_LIBS="-L$BREWDIR/opt/{openssl,postgresql}/lib $PKG_LIBS" 55 | fi 56 | 57 | # For debugging 58 | echo "Using PKG_CFLAGS=$PKG_CFLAGS" 59 | echo "Using PKG_LIBS=$PKG_LIBS" 60 | 61 | # Find compiler 62 | CC=$(${R_HOME}/bin/R CMD config CC) 63 | CFLAGS=$(${R_HOME}/bin/R CMD config CFLAGS) 64 | CPPFLAGS=$(${R_HOME}/bin/R CMD config CPPFLAGS) 65 | 66 | # Test configuration 67 | echo "#include $PKG_TEST_HEADER" | ${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E -xc - >/dev/null 2>&1 || R_CONFIG_ERROR=1; 68 | 69 | # Customize the error 70 | if [ $R_CONFIG_ERROR ]; then 71 | echo "------------------------- ANTICONF ERROR ---------------------------" 72 | echo "Configuration failed because $PKG_CONFIG_NAME was not found. Try installing:" 73 | echo " * deb: $PKG_DEB_NAME (Debian, Ubuntu, etc)" 74 | echo " * rpm: $PKG_RPM_NAME (Fedora, EPEL)" 75 | echo " * rpm: $PKG_AMZ_RPM_NAMES (Amazon Linux)" 76 | echo " * csw: $PKG_CSW_NAME (Solaris)" 77 | echo " * brew: $PKG_BREW_NAME (OSX)" 78 | echo "If $PKG_CONFIG_NAME is already installed, check that either:" 79 | echo "(i) 'pkg-config' is in your PATH AND PKG_CONFIG_PATH contains" 80 | echo " a $PKG_CONFIG_NAME.pc file; or" 81 | echo "(ii) 'pg_config' is in your PATH." 82 | echo "If neither can detect $PGK_CONFIG_NAME, you can set INCLUDE_DIR" 83 | echo "and LIB_DIR manually via:" 84 | echo "R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'" 85 | echo "--------------------------------------------------------------------" 86 | exit 1; 87 | fi 88 | 89 | # Write to Makevars 90 | sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars 91 | 92 | # Success 93 | exit 0 -------------------------------------------------------------------------------- /configure.win: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/configure.win -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local OS X install, R 3.4.1 3 | * ubuntu 12.04 (on travis-ci), R 3.4.1 4 | * win-builder (devel and release) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 1 note 9 | 10 | * This is a new release. 11 | 12 | ## Reverse dependencies 13 | 14 | This is a new release, so there are no reverse dependencies. 15 | 16 | --- 17 | 18 | * Some small fixes and a version bump 19 | -------------------------------------------------------------------------------- /man/async.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{async_query} 4 | \alias{async_query} 5 | \alias{async_status} 6 | \alias{is_busy} 7 | \alias{cancel} 8 | \alias{finish_async} 9 | \title{Asynchronous query processing} 10 | \usage{ 11 | async_query(sql = "", pars = NULL) 12 | 13 | async_status() 14 | 15 | is_busy() 16 | 17 | cancel() 18 | 19 | finish_async() 20 | } 21 | \arguments{ 22 | \item{sql}{a query string} 23 | 24 | \item{pars}{a vector of parameters} 25 | } 26 | \value{ 27 | \code{async_query}: true if query was successfully sent (an invalid query 28 | will still return true) 29 | 30 | \code{async_status}: a results status object, possibly indicating an 31 | invalid query 32 | 33 | \code{is_busy}: a boolean 34 | } 35 | \description{ 36 | Manage an asynchronous query 37 | } 38 | \details{ 39 | These functions expose the asynchronous query interface from 40 | \code{libpq}. The function \code{async_query} issues a query. Its 41 | call is identical to \code{\link{query}} except that it will return 42 | immediately. When the issued command is ready, the function 43 | \code{async_status} will return a query status object exactly 44 | as \code{\link{query}}. Otherwise it will return \code{"BUSY"} to 45 | indicate the server has not finished or \code{"DONE"} to indicate 46 | there is nothing more to fetch. 47 | 48 | If \code{async_status} does not return \code{"DONE"}, then 49 | you should call \code{finish_async} to free pending results. Note 50 | that a call to \code{finish_async} may block until the server is finished 51 | processing the command. It calls \code{cancel} internally but there is 52 | no guarantee the command will abort. 53 | 54 | Any pending results will be lost if you call \code{\link{query}}, 55 | \code{\link{execute}} or \code{\link{fetch}} with a \code{sql} string prior 56 | to \code{async_query} returning \code{DONE}. If you need to issue queries 57 | while waiting on an async call, then use \code{\link{push_conn}} to save 58 | the query state, \code{\link{connect}} to make a new connetion, and then 59 | \code{\link{pop_conn}} followed by \code{async_status}. 60 | 61 | \code{is_busy} is a slightly faster shortcut to check whether the 62 | server has completed the query. You must still call \code{async_status} to 63 | fetch the results. 64 | } 65 | \note{ 66 | In practice, you will be much better off using \code{\link{cursor}} 67 | as that will usually return very quickly even for large queries, and has 68 | the advantage of retrieving the results in chunks. You can call \code{cancel} 69 | while a cursor is active. The cursor will return \code{PGRES_FATAL_ERROR} if 70 | the \code{cancel} is effective. Alternately, issuing any query that sets the 71 | result status will have the same effect as \code{finish_async}. 72 | } 73 | \examples{ 74 | \dontrun{ 75 | # create a database 76 | createdb("rpgtesting") 77 | connect("rpgtesting") 78 | begin() 79 | 80 | # write data frame contents 81 | data(mtcars) 82 | write_table(mtcars) 83 | 84 | # async processing on smallish result 85 | # this wont be interesting if your machine is very fast 86 | async_query("SELECT a.* FROM mtcars a, mtcars b") 87 | repeat 88 | { 89 | status = async_status() 90 | if ( status != "BUSY" ) break 91 | cat("busy...\\n") 92 | Sys.sleep(1) 93 | } 94 | print(status) 95 | head(fetch()) 96 | finish_async() 97 | Sys.sleep(1) 98 | 99 | # async processing on larger result 100 | async_query("SELECT a.* FROM mtcars a, mtcars b, mtcars c") 101 | count = 0 102 | repeat 103 | { 104 | status = async_status() 105 | if ( status == "BUSY" ) 106 | { 107 | if ( count > 2 ) 108 | { 109 | cat("calling cancel...\\n") 110 | cancel() 111 | } 112 | } 113 | else break 114 | cat("busy... \\n") 115 | Sys.sleep(1) 116 | count = count + 1 117 | } 118 | print(status) 119 | finish_async() 120 | 121 | # you can run multiple queries with async_query 122 | rollback(); begin() 123 | write_table(mtcars) 124 | sql1 = "SELECT mpg FROM mtcars LIMIT 3" 125 | sql2 = "SELECT cyl FROM mtcars LIMIT 4" 126 | async_query(paste(sql1, sql2, sep = "; ")) 127 | while ( async_status() == "BUSY" ) NULL 128 | fetch() 129 | while ( is_busy() ) NULL 130 | async_status() 131 | fetch() 132 | finish_async() 133 | 134 | # issue an async query and come back later 135 | async_query(sql1) 136 | push_conn() 137 | connect("rpgtesting") 138 | 139 | # fails because of transaction isolation 140 | fetch(sql2) 141 | pop_conn() 142 | async_status() 143 | 144 | # results from sql1 145 | fetch() 146 | 147 | # this is automatic if you issue new queries 148 | finish_async() 149 | 150 | # cleanup 151 | rollback() 152 | disconnect() 153 | dropdb("rpgtesting")} 154 | 155 | } 156 | \author{ 157 | Timothy H. Keitt 158 | } 159 | -------------------------------------------------------------------------------- /man/connection-utils.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R, R/rpg.R 3 | \name{ping} 4 | \alias{ping} 5 | \alias{get_conn_error} 6 | \alias{get_conn_defaults} 7 | \alias{get_conn_info} 8 | \alias{set_conn_defaults} 9 | \alias{set_default_password} 10 | \alias{reset_conn_defaults} 11 | \title{Database connection utilities} 12 | \usage{ 13 | ping(opts = "") 14 | 15 | get_conn_error() 16 | 17 | get_conn_defaults(all = FALSE) 18 | 19 | get_conn_info(what = NULL, hide_password = TRUE) 20 | 21 | set_conn_defaults(...) 22 | 23 | set_default_password(password = NULL) 24 | 25 | reset_conn_defaults() 26 | } 27 | \arguments{ 28 | \item{opts}{a libpq connection string} 29 | 30 | \item{all}{if false return only defaults with settings} 31 | 32 | \item{what}{the fields to return or all if NULL} 33 | 34 | \item{hide_password}{if true, do not reveal password used} 35 | 36 | \item{...}{a named list of arguments giving new defaults} 37 | 38 | \item{password}{the password} 39 | } 40 | \value{ 41 | \code{ping} returns one of the following: 42 | \tabular{ll}{ 43 | \code{PQPING_OK} \tab Server reachable \cr 44 | \code{PQPING_REJECT} \tab Server reachable but not accepting 45 | connections \cr 46 | \code{PQPING_NO_RESPONSE} \tab Server unreachable \cr 47 | \code{PQPING_NO_ATTEMPT} \tab Connection string is nonsense \cr} 48 | 49 | get_conn_error: an error string 50 | 51 | \code{get_conn_defaults}: a data frame with defaults listed 52 | 53 | get_conn_info: a list of values 54 | } 55 | \description{ 56 | Conection reporting and defaults 57 | } 58 | \details{ 59 | \code{ping} will ignore any keywords not directly 60 | related to the database host (e.g., username, dbname) as it 61 | does not connect; it only detect the server port is responding. 62 | 63 | \code{get_conn_defaults} returns a data frame containing 64 | all of the possible connection string keywords, the names of environment 65 | variables used to override the defaults, the compiled in default value 66 | and the current value of the keyword. 67 | 68 | \code{get_conn_info} returns a list containing 69 | information about the current connection. For 70 | readability, it will print as though it is a matrix. If 71 | you want to see it as a list, try \code{unclass(get_conn_info())}. 72 | 73 | If \code{length(what) == 1} then \code{get_conn_info} returns 74 | a scalar 75 | 76 | \code{set_conn_defaults} sets the connection defaults by calling 77 | \code{\link{Sys.setenv}} and setting the environment variable associated 78 | with the connection keywords returned by \code{get_conn_defaults(all = TRUE)}. 79 | These settings will only last as long as the current shell session and will 80 | reset after a new login. 81 | 82 | \code{set_default_password} will query for a password (if not supplied) 83 | and set the \code{PGPASSWORD} environment variable accordingly. This can be used 84 | with \code{\link{psql}} and \code{\link{copy_to}}. 85 | 86 | \code{reset_conn_defaults} unsets all environment variables returned 87 | by \code{get_conn_defaults(all = TRUE)}. 88 | } 89 | \examples{ 90 | \dontrun{ 91 | ping("connect_timeout = 3, host = www.keittlab.org") 92 | connect() 93 | get_conn_defaults() 94 | set_conn_defaults(dbname = "test") 95 | get_conn_defaults() 96 | reset_conn_defaults() 97 | get_conn_defaults() 98 | get_conn_defaults(all = TRUE) 99 | get_conn_info() 100 | get_conn_error() 101 | disconnect()} 102 | 103 | } 104 | \author{ 105 | Timothy H. Keitt 106 | } 107 | -------------------------------------------------------------------------------- /man/connection.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{connect} 4 | \alias{connect} 5 | \alias{disconnect} 6 | \alias{make_service} 7 | \title{PostgreSQL connection} 8 | \usage{ 9 | connect(dbname, ...) 10 | 11 | disconnect() 12 | 13 | make_service(name) 14 | } 15 | \arguments{ 16 | \item{dbname}{name of the database or a valid \code{libpq} connection string} 17 | 18 | \item{...}{named optional connection parameters} 19 | 20 | \item{name}{the service name} 21 | } 22 | \value{ 23 | \code{connect} returns one of: 24 | \tabular{ll}{ 25 | \code{CONNECTION_OK} \tab Succesful connection \cr 26 | \code{CONNECTION_BAD} \tab Connection failed \cr} 27 | } 28 | \description{ 29 | Manage database connection 30 | } 31 | \details{ 32 | If no connection parameters are supplied, the 33 | connection will fallback to default parameters. Usually 34 | this establishes a connection on the localhost to a database, 35 | if it exists, with the same name as the user. 36 | 37 | Valid keywords and their defaults can be obtained by calling 38 | \code{get_conn_defaults(all = TRUE)}. A valid \code{libpq} 39 | connection string is composed of \code{keyword = value} pairs 40 | separated by whitespace. You can either pass the entire string 41 | or use named arguments. The names of the arguments will be used 42 | as keywords and their values as values. 43 | 44 | If a password was required but not provided, \code{connect} will 45 | will open a dialog and prompt for a password. The connection is 46 | then re-tried and the status returned. 47 | 48 | \code{disconnect} will free any query results as well 49 | as clean up the connection data. It is called in the pakcage 50 | \code{\link{.Last.lib}} function when exiting \code{R}. 51 | 52 | The \code{make_service} function will write the current connection 53 | settings to a special set of files recognized by PostgreSQL's libpq. 54 | After calling this function, you will be able to reconnect using the 55 | service name as in \code{connect(service=name)}. If the connection 56 | requires a password, that will be saved as well. This is not likely 57 | to work on Windows since the file locations are different between 58 | Unix-like and Windows. File a bug with the libpq folks if that 59 | upsets you. 60 | } 61 | \note{ 62 | Do not open a connection and then fork the R 63 | process. The behavior will be unpredictable. It is perfectly 64 | acceptable however to call \code{connect} within each 65 | forked instance. 66 | } 67 | \examples{ 68 | \dontrun{ 69 | fetch("SHOW search_path") # default connection 70 | connect("test") 71 | connect(dbname = "test") 72 | connect(dbname = "test", host = "localhost") 73 | connect("dbname = test host = localhost") 74 | disconnect()} 75 | 76 | } 77 | \author{ 78 | Timothy H. Keitt 79 | } 80 | -------------------------------------------------------------------------------- /man/copy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{copy_from} 4 | \alias{copy_from} 5 | \alias{copy_to} 6 | \title{Bulk read and write} 7 | \usage{ 8 | copy_from(what, psql_opts = "") 9 | 10 | copy_to(x, tablename, schemaname = NULL, append = FALSE, psql_opts = "") 11 | } 12 | \arguments{ 13 | \item{what}{a table name or sql query string} 14 | 15 | \item{psql_opts}{passed directly to the psql command line} 16 | 17 | \item{x}{a data frame} 18 | 19 | \item{tablename}{name of table to create} 20 | 21 | \item{schemaname}{create table in this schema} 22 | 23 | \item{append}{if false, drop and receate table} 24 | } 25 | \description{ 26 | Read from and write to a database using COPY 27 | } 28 | \details{ 29 | These functions use the SQL COPY command and therefore are much 30 | faster than \code{\link{write_table}} and possibly 31 | \code{\link{read_table}}. These functions also call PostgreSQL's 32 | psql command from the command line and will fail if it is not 33 | found on the search path. 34 | 35 | Because these functions shell out to psql you do not need an 36 | active connection. By specifying \code{psql_opts} you can connect 37 | to any database without affecting the active connection. If you 38 | do not specify \code{psql_opts} an attempt will be made to use 39 | the active connection information. If that fails, 40 | psql will use default connection settings. 41 | } 42 | \note{ 43 | These functions call \code{\link{read.csv}} and 44 | \code{\link{write.csv}} and so will suffer the same bandwidth 45 | limitations as those functions. I argue that is good enough. 46 | There is little point in reading and writing datasets too large 47 | for those functions in R. Better to bulk load using psql on 48 | the command line and then use \code{\link{cursor}} to read the 49 | data in small bits. 50 | } 51 | \examples{ 52 | \dontrun{ 53 | # example requires hflights 54 | if (! require(hflights, quietly = TRUE)) 55 | stop("This example requires the \\'hflights\\' package") 56 | 57 | # big dataset 58 | data(hflights) 59 | dim(hflights) 60 | 61 | system(paste("createdb rpgtesting")) 62 | 63 | opts = paste("-d rpgtesting") 64 | system.time(copy_to(hflights, psql_opts = opts)) 65 | system.time(invisible(copy_from("hflights", psql_opts = opts))) 66 | 67 | connect("rpgtesting") 68 | begin() 69 | 70 | ## Sloooowwwwwww 71 | ## system.time(write_table(hflights)) 72 | system.time(invisible(read_table("hflights"))) 73 | 74 | rollback() 75 | disconnect() 76 | dropdb("rpgtesting")} 77 | 78 | } 79 | \seealso{ 80 | \code{\link{set_default_password}} 81 | } 82 | \author{ 83 | Timothy H. Keitt 84 | } 85 | -------------------------------------------------------------------------------- /man/cursor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{cursor} 4 | \alias{cursor} 5 | \title{Iterator support} 6 | \usage{ 7 | cursor(sql, by = 1, pars = NULL) 8 | } 9 | \arguments{ 10 | \item{sql}{any valid query returning rows} 11 | 12 | \item{by}{how many rows to return each iteration} 13 | 14 | \item{pars}{optional query parameters} 15 | } 16 | \description{ 17 | Construct a row iterator 18 | } 19 | \details{ 20 | This function generates an interator object that can be used with 21 | the \code{foreach-package}. 22 | 23 | It is possible to use the 24 | \code{\%dopar\%} operator as shown in the example below. You must 25 | establish a connection to the database on each node and in your current 26 | session because the call to \code{cursor} requires it. Note that the 27 | cursor's lifetime is the current transaction block, so if anything happens 28 | to the transaction or you call \code{END} or \code{ROLLBACK}, then the 29 | cursor will no longer function. Apparently a named SQL cursor is visible 30 | to any database session, as evidenced by the example below, 31 | even though it is declared within a transaction. This is not stated 32 | explicitely in the PostgreSQL documentation. 33 | } 34 | \note{ 35 | There are some reports of issues using multicore (forking) with 36 | RStudio. 37 | } 38 | \examples{ 39 | \dontrun{ 40 | # example requires foreach 41 | if (! require(foreach, quietly = TRUE)) 42 | stop("This example requires the \\'foreach\\' package") 43 | 44 | # connect using defaults 45 | createdb("rpgtesting") 46 | connect("rpgtesting") 47 | begin() 48 | 49 | # write data frame contents 50 | data(mtcars) 51 | write_table(mtcars, row_names = "id", pkey = "id", overwrite = TRUE) 52 | 53 | # expand rows to columns 8 rows at a time 54 | x = foreach(i = cursor("SELECT * FROM mtcars", by = 8), 55 | .combine = rbind) \%do\% { i$mpg } 56 | print(x, digits = 2) 57 | 58 | # parallel example 59 | if (require(doParallel, quietly = TRUE)) 60 | { 61 | # make the cluster 62 | cl = makeCluster(2) 63 | 64 | # must connect to database on each node 65 | clusterEvalQ(cl, library(rpg)) 66 | clusterEvalQ(cl, connect("rpgtesting")) 67 | clusterEvalQ(cl, begin()) 68 | 69 | # setup the dopar call 70 | registerDoParallel(cl) 71 | 72 | # take column averages 4 rows at a time 73 | curs1 = cursor("SELECT * FROM mtcars", by = 4) 74 | x = foreach(i = curs1, .combine = rbind, .inorder = FALSE) \%dopar\% 75 | { 76 | rr = paste0(range(abbreviate(i$id)), collapse = "-") 77 | pid = get_conn_info("server.pid") 78 | j = names(i) != "id" 79 | mn = signif(apply(i[, j], 2, mean), 2) 80 | c(rows = rr, backend = pid, mn) 81 | } 82 | x = as.data.frame(x) 83 | row.names(x) = x$rows 84 | x$rows = NULL 85 | print(noquote(x)) 86 | 87 | clusterEvalQ(cl, rollback()) 88 | stopCluster(cl) 89 | } 90 | 91 | #cleanup 92 | disconnect() 93 | dropdb("rpgtesting")} 94 | 95 | } 96 | \seealso{ 97 | \code{foreach}, \code{\link{rollback}}, \code{\link{query}} 98 | } 99 | \author{ 100 | Timothy H. Keitt 101 | } 102 | -------------------------------------------------------------------------------- /man/format-for-send.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R, R/utils.R 3 | \name{register_return_formatter} 4 | \alias{register_return_formatter} 5 | \alias{format_for_send} 6 | \title{Convert R objects to strings} 7 | \usage{ 8 | register_return_formatter(pgoid, f) 9 | 10 | format_for_send(obj) 11 | } 12 | \arguments{ 13 | \item{pgoid}{the PostgreSQL type Oid} 14 | 15 | \item{f}{a function} 16 | 17 | \item{obj}{any object} 18 | } 19 | \description{ 20 | Prepare R objects for sending to postgresql 21 | } 22 | \details{ 23 | The function f must accept a vector of character values and return 24 | a vector of values formated appropriately. 25 | 26 | R objects that will be written to postgresql must be converted to 27 | characters as all data is transferred to the server as text. The S3 method 28 | \code{foramt_for_send} accomplishes this. It accepts any object and returns 29 | a character representation. 30 | 31 | You can define new conversions by supplying your own S3 override of 32 | \code{format_for_send}. 33 | } 34 | -------------------------------------------------------------------------------- /man/misc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R, R/rpg.R 3 | \name{libpq_version} 4 | \alias{libpq_version} 5 | \alias{encrypt_password} 6 | \alias{get_encoding} 7 | \alias{set_encoding} 8 | \alias{set_error_verbosity} 9 | \alias{toggle_echo} 10 | \alias{enable_postgis} 11 | \alias{enable_extension} 12 | \title{Miscelaneous functions} 13 | \usage{ 14 | libpq_version() 15 | 16 | encrypt_password(passwd, user) 17 | 18 | get_encoding() 19 | 20 | set_encoding(encoding) 21 | 22 | set_error_verbosity(verbosity) 23 | 24 | toggle_echo() 25 | 26 | enable_postgis(schemaname = "postgis") 27 | 28 | enable_extension(extension, schemaname = extension) 29 | } 30 | \arguments{ 31 | \item{passwd}{the password} 32 | 33 | \item{user}{the user name} 34 | 35 | \item{encoding}{the character encoding} 36 | 37 | \item{verbosity}{one of "terse", "default", "verbose"} 38 | 39 | \item{schemaname}{install in this schema} 40 | 41 | \item{extension}{the extension name} 42 | } 43 | \description{ 44 | Various utility functions 45 | } 46 | \details{ 47 | \code{enable_postgis} will attempt to install the postgis 48 | extension in the named schema using \code{enable_extension}. 49 | 50 | \code{enable_extension} will attempt to install the 51 | extension in the named schema. The default search path is altered to 52 | include the new schema. 53 | } 54 | \examples{ 55 | \dontrun{ 56 | # try connecting to default database 57 | createdb("rpgtesting") 58 | connect("rpgtesting") 59 | begin() 60 | 61 | libpq_version() 62 | encrypt_password("test", "tester") 63 | get_encoding() 64 | set_encoding("UTF8") 65 | set_error_verbosity("terse") 66 | set_error_verbosity("verbose") 67 | set_error_verbosity("default") 68 | enable_postgis() 69 | 70 | # cleanup 71 | rollback() 72 | disconnect() 73 | dropdb("rpgtesting")} 74 | 75 | } 76 | \author{ 77 | Timothy H. Keitt 78 | } 79 | -------------------------------------------------------------------------------- /man/path.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sql.R 3 | \name{set_path} 4 | \alias{set_path} 5 | \alias{get_path} 6 | \alias{append_path} 7 | \alias{prepend_path} 8 | \alias{path_contains} 9 | \title{PostgreSQL path variable} 10 | \usage{ 11 | set_path(..., default = FALSE) 12 | 13 | get_path(default = FALSE) 14 | 15 | append_path(..., default = FALSE, no_dup = TRUE) 16 | 17 | prepend_path(..., default = FALSE, no_dup = TRUE) 18 | 19 | path_contains(..., default = FALSE) 20 | } 21 | \arguments{ 22 | \item{...}{path names} 23 | 24 | \item{default}{if true, manipulate database default} 25 | 26 | \item{no_dup}{do not add if path exists} 27 | } 28 | \description{ 29 | Manipulate the PostgreSQL path variable 30 | } 31 | -------------------------------------------------------------------------------- /man/prepare.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{prepare} 4 | \alias{prepare} 5 | \title{Prepared queries} 6 | \usage{ 7 | prepare(sql) 8 | } 9 | \arguments{ 10 | \item{sql}{a valid query string} 11 | } 12 | \value{ 13 | A function. 14 | 15 | The function can take one argument. The values will be used 16 | to fill in parameters of the prepared statement. If no argument 17 | is passed, the statement will be executed without any parameters. 18 | } 19 | \description{ 20 | Prepare and execute queries 21 | } 22 | \details{ 23 | \code{prepare} prepares a statement for later execution. 24 | It returns a function that when called executes the prepared 25 | statement. Values passed to the returned function will substituted 26 | for parameters in the prepared statement. If the number of parameters 27 | supplied is a 28 | multiple of the number of open parameters in query prepared 29 | using \code{prepare}, then the prepared query will be executed 30 | repeatedly for each successive set of parameters. This repeated 31 | execution loop is evaluted in C++ and so is quite fast. The 32 | supplied parameter values will be coerced to a matrix of the 33 | appropriate dimensions. Values passed to the function will be 34 | recycled to match the number of query parameters. 35 | The passed parameters will be coerced to character strings. 36 | } 37 | \note{ 38 | One can use pure SQL to achieve the same result. 39 | 40 | It is generally a good idea to wrap \code{prepare} 41 | in a transaction. If not in a transaction, you cannot rollback any updates 42 | and it will be much slower as PostgreSQL initiates a transaction-per-query 43 | by default. 44 | } 45 | \examples{ 46 | \dontrun{ 47 | # try connecting to default database 48 | createdb("rpgtesting") 49 | connect("rpgtesting") 50 | begin() 51 | 52 | # write data frame contents 53 | data(mtcars) 54 | write_table(mtcars) 55 | 56 | # delete the rows 57 | query("truncate mtcars") 58 | read_table(mtcars) 59 | 60 | # use prepare-execute to write rows 61 | pars = paste0("$", 1:11, collapse = ", ") 62 | sql = paste0("INSERT INTO mtcars VALUES (", pars, ")", collapse = " ") 63 | f = prepare(sql) 64 | f(mtcars) 65 | read_table(mtcars, limit = 5) 66 | 67 | # cleanup 68 | rollback() 69 | disconnect() 70 | dropdb("rpgtesting")} 71 | 72 | } 73 | \author{ 74 | Timothy H. Keitt 75 | } 76 | -------------------------------------------------------------------------------- /man/psql.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{psql} 4 | \alias{psql} 5 | \title{PostgreSQL shell} 6 | \usage{ 7 | psql(psql_opts = "") 8 | } 9 | \arguments{ 10 | \item{psql_opts}{a character string passed to the psql command} 11 | } 12 | \description{ 13 | Run PostgreSQL's psql shell interactively 14 | } 15 | \details{ 16 | The \code{psql} function repeatedly queries for input and pipes it to 17 | PostgreSQL's psql command. It will terminate on \code{\\q} or empty 18 | input. 19 | 20 | If \code{psql_opts} is an empty string, then an attempt will be made to 21 | supply suitable options based on the current connection. If there is no 22 | active connection, psql will fallback to complied in defaults. If 23 | \code{psql_opts} is not an empty string, then it will be passed as-is to 24 | psql. 25 | 26 | You can type psql's escape commands as usual. Try \code{\?}. You 27 | cannot use \code{\\e} or \code{\\ef} to evoke an editor. Doing strange 28 | things with \code{\!} will likely hang the R session. 29 | 30 | There is no way to direclty enter a database password. If one is required, 31 | you can use a \href{http://www.postgresql.org/docs/9.1/static/libpq-pgpass.html}{password file} 32 | or \code{\link{set_conn_defaults}}. 33 | 34 | Unfortunately it is probably impossible to enable GNU readline support 35 | so for example up-arrow will recall your R commands, not the psql 36 | commands entered. You can always call psql from a terminal. 37 | } 38 | \seealso{ 39 | \code{\link{set_default_password}} 40 | } 41 | \author{ 42 | Timothy H. Keitt 43 | } 44 | -------------------------------------------------------------------------------- /man/query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R, R/rpg.R 3 | \name{result_dim} 4 | \alias{result_dim} 5 | \alias{get_tuple_info} 6 | \alias{query} 7 | \alias{query_error} 8 | \alias{fetch} 9 | \alias{execute} 10 | \title{PostgreSQL query} 11 | \usage{ 12 | result_dim() 13 | 14 | get_tuple_info() 15 | 16 | query(sql = "", pars = NULL) 17 | 18 | query_error() 19 | 20 | fetch(sql = "", pars = NULL) 21 | 22 | execute(...) 23 | } 24 | \arguments{ 25 | \item{sql}{a query string} 26 | 27 | \item{pars}{a character vector of substitution values} 28 | 29 | \item{...}{list of commands to be \code{\link{paste}d} together} 30 | } 31 | \value{ 32 | \code{result_dim} returns the number of tuples and fields 33 | 34 | \code{get_tuple_info} returns an integer array with tuple information. 35 | 36 | \code{query} returns: 37 | \tabular{ll}{ 38 | PGRES_EMPTY_QUERY \tab The string sent to the server was empty \cr 39 | PGRES_COMMAND_OK \tab Successful completion of a command returning no data \cr 40 | PGRES_TUPLES_OK \tab Successful completion of a command returning data (such as a SELECT or SHOW) \cr 41 | PGRES_COPY_OUT \tab Copy Out (from server) data transfer started \cr 42 | PGRES_COPY_IN \tab Copy In (to server) data transfer started \cr 43 | PGRES_BAD_RESPONSE \tab The server's response was not understood. \cr 44 | PGRES_NONFATAL_ERROR \tab A nonfatal error (a notice or warning) occurred \cr 45 | PGRES_FATAL_ERROR \tab A fatal error occurred \cr 46 | PGRES_COPY_BOTH \tab Copy In/Out (to and from server) data transfer started. This is currently used only for streaming replication \cr} 47 | 48 | \code{query_error} returns an error string 49 | 50 | \code{fetch} returns a data frame or a query status object on failure. 51 | 52 | \code{execute} the result status string 53 | } 54 | \description{ 55 | Issue a query to the current database connection 56 | } 57 | \details{ 58 | \code{fetch} returns the result of a query as a data frame. If 59 | \code{sql} is \code{NULL} or empty, then an attempt will be made to retrieve 60 | any pending resutls from previous queries. Note that query results are not 61 | cleared until the next query is issued so \code{fetch} will continue to 62 | return results until a new query is issued. 63 | 64 | \code{execute} is a wrapper around \code{query}. It will raise 65 | an exception if the command does not complete. Exceptions can be caught with 66 | \code{\link{tryCatch}}. You cannot use a parameterized 67 | query with \code{execute}. Unlike \code{query} it will \code{\link{paste}} its 68 | arguments into a single string. 69 | } 70 | \examples{ 71 | \dontrun{ 72 | createdb("rpgtesting") 73 | connect("rpgtesting") 74 | begin() 75 | execute("DROP SCHEMA IF EXISTS rpgtesting CASCADE") 76 | execute("CREATE SCHEMA rpgtesting") 77 | execute("SET search_path TO rpgtesting") 78 | execute("DROP TABLE IF EXISTS test") 79 | execute("CREATE TABLE test (id integer, field text)") 80 | query("INSERT INTO test VALUES ($1, $2)", c(1, "test")) 81 | fetch("SELECT * FROM test") 82 | result_dim() 83 | fetch("SELECT * FROM testing") 84 | query_error() 85 | rollback() 86 | disconnect() 87 | dropdb("rpgtesting")} 88 | 89 | } 90 | \seealso{ 91 | \code{\link{psql}} 92 | } 93 | \author{ 94 | Timothy H. Keitt 95 | } 96 | -------------------------------------------------------------------------------- /man/rpg-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \docType{package} 4 | \name{rpg-package} 5 | \alias{rpg-package} 6 | \alias{rpg} 7 | \title{Easy Access to Advanced PostgreSQL Features} 8 | \description{ 9 | Provides functions for connecting to, reading from and writing to a PostgreSQL 10 | database. Facilities for tracing the communication between R and PostgreSQL are 11 | provided, as are function to retieve detailed session metadata. 12 | } 13 | \details{ 14 | \tabular{ll}{ 15 | Package: \tab rpg\cr 16 | Type: \tab Package\cr 17 | Version: \tab 1.5\cr 18 | Date: \tab 2017-2-8\cr 19 | License: \tab GPL \cr 20 | } 21 | The main functions are \code{connect}, which establishes a connection, 22 | \code{query}, which issues queries and \code{fetch}, which retieves results. 23 | Intelligent defaults are used throughout. Functions that require a connection 24 | will automatically attempt to establish a valid connection based on a previous 25 | connection or from defaults. The defaults can be overriden in a variety of 26 | ways. 27 | } 28 | \references{ 29 | \url{http://github.com/thk686/rpg}, \url{http://www.postgresql.org/} 30 | } 31 | \author{ 32 | Timothy H. Keitt \cr \url{http://www.keittlab.org/} \cr \cr 33 | Maintainer: Timothy H. Keitt \email{tkeitt@gmail.com} \cr 34 | } 35 | \keyword{package} 36 | -------------------------------------------------------------------------------- /man/sql.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sql.R 3 | \name{create_index} 4 | \alias{create_index} 5 | \alias{sql} 6 | \alias{add_primary_key} 7 | \alias{add_foreign_key} 8 | \alias{create_schema} 9 | \alias{add_column} 10 | \alias{createdb} 11 | \alias{dropdb} 12 | \title{Create an index} 13 | \usage{ 14 | create_index(tablename, columnname, schemaname = NULL, indexname = NULL, 15 | unique = FALSE, using = NULL, collate = NULL, descending = FALSE, 16 | tablespace = NULL, where = NULL) 17 | 18 | add_primary_key(tablename, columnname, schemaname = NULL) 19 | 20 | add_foreign_key(tablename, columnname, foreign_table, foreign_column = NULL, 21 | schemaname = NULL, foreign_schema = schemaname) 22 | 23 | create_schema(schemaname) 24 | 25 | add_column(columnname, columntype, tablename, schemaname = NULL) 26 | 27 | createdb(name) 28 | 29 | dropdb(name, if_exists = TRUE) 30 | } 31 | \arguments{ 32 | \item{tablename}{the name of the table} 33 | 34 | \item{columnname}{the name of the column} 35 | 36 | \item{schemaname}{specifically in this schema} 37 | 38 | \item{indexname}{optional index name to use} 39 | 40 | \item{unique}{if true, create a unique index} 41 | 42 | \item{using}{the index method} 43 | 44 | \item{collate}{set collation} 45 | 46 | \item{descending}{if true, sort descending} 47 | 48 | \item{tablespace}{create in this tablespace} 49 | 50 | \item{where}{restrict to rows matching predicate} 51 | 52 | \item{foreign_table}{the foreign table name} 53 | 54 | \item{foreign_column}{a key column (defaults to primary key)} 55 | 56 | \item{foreign_schema}{the schema of the foreign table} 57 | 58 | \item{columntype}{the column SQL type} 59 | 60 | \item{name}{name of the database} 61 | 62 | \item{if_exists}{don't fail on missing database} 63 | } 64 | \description{ 65 | Create and index on an existing table column 66 | } 67 | \details{ 68 | Build an index on a column. 69 | } 70 | \author{ 71 | Timothy H. Keitt 72 | } 73 | -------------------------------------------------------------------------------- /man/stack.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{push_conn} 4 | \alias{push_conn} 5 | \alias{pop_conn} 6 | \alias{swap_conn} 7 | \alias{rotate_stack} 8 | \alias{show_conn_stack} 9 | \title{Multiple PostgreSQL connections} 10 | \usage{ 11 | push_conn() 12 | 13 | pop_conn() 14 | 15 | swap_conn() 16 | 17 | rotate_stack(n = 1L) 18 | 19 | show_conn_stack() 20 | } 21 | \arguments{ 22 | \item{n}{number of shifts} 23 | } 24 | \description{ 25 | Manage multiple connections on a stack 26 | } 27 | \details{ 28 | These functions allow you to store multiple connections on a stack. They are 29 | only used for their side-effects. \code{\link{rpg}} stores an active connection 30 | pointer internally. This pointer can be moved onto the stack and manipulated. 31 | Once on the stack, the pointer is no longer active. You must use 32 | \code{swap_conn} or \code{pop_conn} to reactive a pushed connection, or call 33 | \code{\link{connect}} to create a new active connection. 34 | 35 | \code{push_conn} pushes the current connection onto the connection stack 36 | leaving the active connection null. 37 | 38 | \code{pop_conn} pops a connection off the stack and makes it active. Whatever 39 | connection was active when \code{pop_conn} is called will be disconnected and 40 | cleared. Use \code{swap_conn} to preserve the active connection. 41 | 42 | \code{swap_conn} swaps the active connection with the connection on the top 43 | of the stack. If the stack is empty, the connection is swapped with a null 44 | connection. 45 | 46 | \code{rotate_stack} moves the bottom of the stack to the top. 47 | 48 | \code{show_conn_stack} returns a data frame with information about the 49 | connections on the stack. 50 | } 51 | \examples{ 52 | \dontrun{ 53 | # make some databases 54 | dbs = paste0("rpgdb", 1:3) 55 | lapply(paste("createdb", dbs), system) 56 | 57 | # connect 58 | connect(dbname = dbs[1]); push_conn() 59 | connect(dbname = dbs[2]); push_conn() 60 | connect(dbname = dbs[3]); push_conn() 61 | 62 | show_conn_stack() 63 | rotate_stack() 64 | show_conn_stack() 65 | rotate_stack(2) 66 | show_conn_stack() 67 | pop_conn() 68 | show_conn_stack() 69 | get_conn_info("dbname") 70 | swap_conn() 71 | show_conn_stack() 72 | get_conn_info("dbname") 73 | pop_conn() 74 | show_conn_stack() 75 | pop_conn() 76 | show_conn_stack() 77 | disconnect() 78 | connect() 79 | lapply(paste("dropdb", dbs), system)} 80 | 81 | } 82 | -------------------------------------------------------------------------------- /man/stow.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{stow} 4 | \alias{stow} 5 | \alias{list_stowed} 6 | \alias{retrieve} 7 | \alias{delete_stowed} 8 | \alias{stow_image} 9 | \alias{retrieve_image} 10 | \title{Object storage} 11 | \usage{ 12 | stow(..., tablename = "rpgstow", schemaname = "rpgstow") 13 | 14 | list_stowed(tablename = "rpgstow", schemaname = "rpgstow") 15 | 16 | retrieve(objnames, tablename = "rpgstow", schemaname = "rpgstow") 17 | 18 | delete_stowed(objnames, tablename = "rpgstow", schemaname = "rpgstow") 19 | 20 | stow_image(imagename = "rpgimage", schemaname = "rpgstow") 21 | 22 | retrieve_image(imagename = "rpgimage", schemaname = "rpgstow") 23 | } 24 | \arguments{ 25 | \item{...}{a list of objects or object names} 26 | 27 | \item{tablename}{the table for storing objects} 28 | 29 | \item{schemaname}{the schema to use} 30 | 31 | \item{objnames}{a character vector with object names or regular expressions} 32 | 33 | \item{imagename}{a table name for stowing the session image} 34 | } 35 | \description{ 36 | Serialize and write R objects 37 | } 38 | \details{ 39 | These functions allow one to write out any R object to a PostgreSQL 40 | database and later retrieve them into any R session. The pair \code{stow} and 41 | \code{retrieve} are modeled roughly as \code{\link{save}} and \code{\link{load}}. 42 | 43 | The contents of \code{...} are handled specially. If a named argument is passed, 44 | then the object will be stowed and retrieved with that name. A raw string will 45 | not be stowed if it matches the name of any R object; the matching R object will 46 | be stowed instead. A vector of strings will however be stowed as is. Object names 47 | will be coerced to valid identifiers using \code{\link{make.names}}. Names must 48 | be unique and not collide with any existing object name in the same table. 49 | 50 | \code{retrieve} assigns the stowed values to the 51 | stowed names in the global environment. It will overwrite any variable that 52 | has the same name as a stowed object. 53 | 54 | The functions \code{retrieve} and \code{delete_stowed} use regular 55 | expression matching as implemented by the 56 | \href{http://www.postgresql.org/docs/9.1/static/functions-matching.html}{PostgreSQL \code{~} operator}. 57 | 58 | \code{stow_image} and \code{retrieve_image} will stow all objects in 59 | the current session and retrieve them later. Note that \code{stow_image} will 60 | overwrite all existing objects stowed within \code{imagename}. 61 | } 62 | \examples{ 63 | \dontrun{ 64 | createdb("rpgtesting") 65 | connect("rpgtesting") 66 | begin() 67 | 68 | stow("test") 69 | list_stowed() 70 | stow("test") 71 | list_stowed() 72 | stow(x = "test") 73 | list_stowed() 74 | x = 1 75 | stow(x) 76 | list_stowed() 77 | stow(y = x) 78 | list_stowed() 79 | rm(x) 80 | retrieve(".*") 81 | print(test) 82 | print(x) 83 | print(y) 84 | delete_stowed(".*") 85 | data(mtcars) 86 | stow(mtcars) 87 | list_stowed() 88 | rm(mtcars) 89 | retrieve("mtcars") 90 | head(mtcars) 91 | 92 | rollback() 93 | disconnect() 94 | dropdb("rpgtesting")} 95 | 96 | } 97 | \seealso{ 98 | \code{\link{RApiSerialize}} 99 | } 100 | \author{ 101 | Timothy H. Keitt 102 | } 103 | -------------------------------------------------------------------------------- /man/table-info.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{list_tables} 4 | \alias{list_tables} 5 | \alias{describe_table} 6 | \alias{list_schema} 7 | \alias{list_databases} 8 | \title{PostgreSQL database information} 9 | \usage{ 10 | list_tables(only.names = TRUE) 11 | 12 | describe_table(tablename, schemaname = NULL) 13 | 14 | list_schema(only.names = TRUE) 15 | 16 | list_databases(only.names = TRUE) 17 | } 18 | \arguments{ 19 | \item{only.names}{if true, just list the table names} 20 | 21 | \item{tablename}{the name of a PostgreSQL table} 22 | 23 | \item{schemaname}{if not null, look only in this schema} 24 | } 25 | \value{ 26 | \code{list_tables}: a vector of table names or a data frame 27 | 28 | \code{describe_table}: a data frame with column information 29 | } 30 | \description{ 31 | Get information about tables in a database 32 | } 33 | \examples{ 34 | \dontrun{ 35 | createdb("rpgtesting") 36 | connect("rpgtesting") 37 | begin() 38 | 39 | # write data frame contents 40 | data(mtcars) 41 | write_table(mtcars) 42 | 43 | # get some information 44 | list_tables() 45 | describe_table("mtcars") 46 | list_schema() 47 | list_databases() 48 | 49 | #cleanup 50 | rollback() 51 | disconnect() 52 | dropdb("rpgtesting")} 53 | 54 | } 55 | \seealso{ 56 | \code{\link{psql}} 57 | } 58 | \author{ 59 | Timothy H. Keitt 60 | } 61 | -------------------------------------------------------------------------------- /man/table-io.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{write_table} 4 | \alias{write_table} 5 | \alias{read_table} 6 | \title{PostgreSQL data frame IO} 7 | \usage{ 8 | write_table(x, tablename, pkey = NULL, row_names = NULL, 9 | schemaname = NULL, types = NULL, append = FALSE, overwrite = FALSE) 10 | 11 | read_table(tablename, what = "*", limit = NULL, row_names = NULL, 12 | schemaname = NULL, pkey_to_row_names = FALSE) 13 | } 14 | \arguments{ 15 | \item{x}{a data frame or something convertible to a data frame} 16 | 17 | \item{tablename}{the name of the table to read from or write to} 18 | 19 | \item{pkey}{a column name to use as primary key} 20 | 21 | \item{row_names}{a column name to write row names} 22 | 23 | \item{schemaname}{the schema name} 24 | 25 | \item{types}{a list of valid PostgreSQL type names} 26 | 27 | \item{append}{if true, append rows to existing table} 28 | 29 | \item{overwrite}{if true, destroy existing table with the same name} 30 | 31 | \item{what}{a vector of column names} 32 | 33 | \item{limit}{only return this many rows} 34 | 35 | \item{pkey_to_row_names}{if true and row_names not given, use primary key column} 36 | } 37 | \value{ 38 | \code{write_table} the final query status 39 | 40 | \code{read_table} a data frame 41 | } 42 | \description{ 43 | Reads and writes table to and from database 44 | } 45 | \details{ 46 | A table is created using the current connection. If \code{pkey} does not 47 | match any column name, then a new column is created with the name given by 48 | \code{pkey}. Its type will be \code{serial} and it will be set as the primary 49 | key. If \code{pkey} does match an existing column name, then that column will 50 | be used as the primary key. Note that \code{\link{make.unique}} will be 51 | called on the column names before this matching is done. If \code{row_names} 52 | is a character string, the data frame row names will be stored in a column 53 | with the column name given by \code{row_names}. The \code{row_names} column 54 | can also be the primary key if \code{pkey} is the same as \code{row_names}. 55 | 56 | If \code{row_names} is specified when calling \code{read_table}, then the 57 | resulting data frame will have row names installed from the column named 58 | in \code{row_names}. Note that the column named in \code{row_names} must 59 | match a column specified by \code{what}. The matching column will be removed 60 | from the data frame. 61 | 62 | If \code{types} is not supplied, they will be computed from the classes and 63 | types of the columns of input. 64 | } 65 | \note{ 66 | The entire process is wrapped within a transcation. On failure 67 | at any point, the transaction will be rolled back and the database 68 | unaffected. 69 | 70 | Also, \code{write_table} uses SQL \code{INSERT} statements and as such 71 | will be slow for large tables. You are much better off bulk loading data 72 | using the \code{COPY} command outside of \code{R}. 73 | } 74 | \examples{ 75 | \dontrun{ 76 | # connect using defaults 77 | createdb("rpgtesting") 78 | connect("rpgtesting") 79 | begin() 80 | 81 | # write data frame contents 82 | data(mtcars) 83 | write_table(mtcars) 84 | 85 | # make "cyl" primary key (will fail unique constraint) 86 | write_table(mtcars, pkey = "cyl", overwrite = TRUE) 87 | 88 | # also write row names to "id" 89 | write_table(mtcars, row_names = "id", overwrite = TRUE) 90 | 91 | # row names as primary key 92 | write_table(mtcars, row_names = "id", pkey = "id", overwrite = TRUE) 93 | 94 | # default R row names and only first 3 columns 95 | read_table("mtcars", what = "mpg, cyl, disp", limit = 3) 96 | 97 | # row names from column "id" 98 | read_table("mtcars", row_names = "id", limit = 3) 99 | 100 | # get row names from primary key 101 | read_table("mtcars", pkey_to_row_names = TRUE, limit = 3) 102 | 103 | #cleanup 104 | rollback() 105 | disconnect() 106 | dropdb("rpgtesting")} 107 | 108 | } 109 | \seealso{ 110 | \code{\link{copy_from}} 111 | } 112 | \author{ 113 | Timothy H. Keitt 114 | } 115 | -------------------------------------------------------------------------------- /man/tracing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R, R/rpg.R 3 | \name{trace_conn} 4 | \alias{trace_conn} 5 | \alias{untrace_conn} 6 | \alias{trace_filename} 7 | \alias{dump_conn_trace} 8 | \title{PostgeSQL connection tracing} 9 | \usage{ 10 | trace_conn(filename = "", append = FALSE) 11 | 12 | untrace_conn(remove = FALSE) 13 | 14 | trace_filename() 15 | 16 | dump_conn_trace(warn = FALSE, ...) 17 | } 18 | \arguments{ 19 | \item{filename}{where to send the tracing} 20 | 21 | \item{append}{if true, append to existing file} 22 | 23 | \item{remove}{if true, unlink the tracing file} 24 | 25 | \item{warn}{if true, \code{\link{readLines}} will issue warnings} 26 | 27 | \item{...}{passed to \code{\link{readLines}}} 28 | } 29 | \value{ 30 | \code{trace_filename}: the name of the file containing 31 | trace information. 32 | } 33 | \description{ 34 | Functions to manage connection tracing 35 | } 36 | \details{ 37 | PostgeSQL tracing lets you observe all information 38 | passing between \code{rpg} and the database server. 39 | 40 | \code{trace_conn} begins tracing and \code{untrace_conn} 41 | stops tracing. 42 | 43 | \code{dump_conn_trace} invokes \code{\link{readLines}} on 44 | the trace file. 45 | } 46 | \examples{ 47 | \dontrun{ 48 | createdb("rpgtesting") 49 | connect("rpgtesting") 50 | trace_conn() 51 | list_tables() 52 | dump_conn_trace(n = 40) 53 | untrace_conn(remove = TRUE) 54 | disconnect() 55 | dropdb("rpgtesting")} 56 | } 57 | \author{ 58 | Timothy H. Keitt 59 | } 60 | -------------------------------------------------------------------------------- /man/transactions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rpg.R 3 | \name{begin} 4 | \alias{begin} 5 | \alias{commit} 6 | \alias{rollback} 7 | \alias{savepoint} 8 | \title{Transaction support} 9 | \usage{ 10 | begin() 11 | 12 | commit(savepoint = NULL) 13 | 14 | rollback(savepoint = NULL) 15 | 16 | savepoint() 17 | } 18 | \arguments{ 19 | \item{savepoint}{an object produced by \code{savepoint}} 20 | } 21 | \value{ 22 | \code{savepoint}: a savepoint object 23 | } 24 | \description{ 25 | Start, commit or rollback transactions or savepoints 26 | } 27 | \details{ 28 | These functions allow manipulation of database transaction states. If no 29 | \code{savepoint} object is supplied, then an attempt is made to commit or 30 | rollback the current transaction. 31 | 32 | The \code{savepoint} function will initiate a transaction if one is not 33 | currently active. In that case, no actual PostgreSQL savepoint will be used. 34 | Rolling back the savepoint will rollback the initiated transaction. If a 35 | tranaction is active, then a named savepoint will be generated. You can 36 | \code{rollback} to the database state when \code{savepoint} 37 | was called or \code{commit} all changes. 38 | } 39 | \examples{ 40 | \dontrun{ 41 | createdb("rpgtesting") 42 | connect("rpgtesting") 43 | begin() 44 | sp1 = savepoint() 45 | 46 | # nest savepoints 47 | sp2 = savepoint() 48 | data(mtcars) 49 | write_table(mtcars, "testtab", overwrite = TRUE) 50 | list_tables() 51 | rollback(sp2) 52 | 53 | list_tables() 54 | # nest savepoints 55 | sp3 = savepoint() 56 | sp4 = savepoint() 57 | write_table(mtcars, "testtab", overwrite = TRUE) 58 | commit(sp4) 59 | list_tables() 60 | rollback(sp3) 61 | list_tables() 62 | 63 | rollback(sp1) 64 | rollback() 65 | disconnect() 66 | dropdb("rpgtesting")} 67 | 68 | } 69 | \author{ 70 | Timothy H. Keitt 71 | } 72 | -------------------------------------------------------------------------------- /rpg.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageCheckArgs: --as-cran 19 | PackageRoxygenize: rd,collate,namespace 20 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | PKG_CPPFLAGS=-I/Applications/Postgres.app/Contents/Versions/10/include 2 | PKG_LIBS=-L/Applications/Postgres.app/Contents/Versions/10/lib -lpq 3 | CXX_STD = CXX11 4 | -------------------------------------------------------------------------------- /src/Makevars.in: -------------------------------------------------------------------------------- 1 | PKG_CPPFLAGS=@cflags@ 2 | PKG_LIBS=@libs@ 3 | CXX_STD = CXX11 4 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | PKG_CPPFLAGS= -I../windows/libpq-9.5.2/include 2 | PKG_LIBS= -L../windows/libpq-9.5.2/lib${R_ARCH} -lpq -lssl -lcrypto -lwsock32 -lsecur32 -lws2_32 -lgdi32 -lcrypt32 -lwldap32 3 | 4 | all: clean winlibs 5 | 6 | winlibs: 7 | "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "../tools/winlibs.R" 8 | 9 | clean: 10 | rm -f $(OBJECTS) $(SHLIB) 11 | -------------------------------------------------------------------------------- /src/RcppExports.cpp: -------------------------------------------------------------------------------- 1 | // Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | #include 5 | 6 | using namespace Rcpp; 7 | 8 | // connect_ 9 | CharacterVector connect_(CharacterVector keywords, CharacterVector values); 10 | RcppExport SEXP _rpg_connect_(SEXP keywordsSEXP, SEXP valuesSEXP) { 11 | BEGIN_RCPP 12 | Rcpp::RObject rcpp_result_gen; 13 | Rcpp::RNGScope rcpp_rngScope_gen; 14 | Rcpp::traits::input_parameter< CharacterVector >::type keywords(keywordsSEXP); 15 | Rcpp::traits::input_parameter< CharacterVector >::type values(valuesSEXP); 16 | rcpp_result_gen = Rcpp::wrap(connect_(keywords, values)); 17 | return rcpp_result_gen; 18 | END_RCPP 19 | } 20 | // ping 21 | CharacterVector ping(const char* opts); 22 | RcppExport SEXP _rpg_ping(SEXP optsSEXP) { 23 | BEGIN_RCPP 24 | Rcpp::RObject rcpp_result_gen; 25 | Rcpp::RNGScope rcpp_rngScope_gen; 26 | Rcpp::traits::input_parameter< const char* >::type opts(optsSEXP); 27 | rcpp_result_gen = Rcpp::wrap(ping(opts)); 28 | return rcpp_result_gen; 29 | END_RCPP 30 | } 31 | // disconnect_ 32 | void disconnect_(); 33 | RcppExport SEXP _rpg_disconnect_() { 34 | BEGIN_RCPP 35 | Rcpp::RNGScope rcpp_rngScope_gen; 36 | disconnect_(); 37 | return R_NilValue; 38 | END_RCPP 39 | } 40 | // clean_up_all 41 | void clean_up_all(); 42 | RcppExport SEXP _rpg_clean_up_all() { 43 | BEGIN_RCPP 44 | Rcpp::RNGScope rcpp_rngScope_gen; 45 | clean_up_all(); 46 | return R_NilValue; 47 | END_RCPP 48 | } 49 | // get_conn_error 50 | CharacterVector get_conn_error(); 51 | RcppExport SEXP _rpg_get_conn_error() { 52 | BEGIN_RCPP 53 | Rcpp::RObject rcpp_result_gen; 54 | Rcpp::RNGScope rcpp_rngScope_gen; 55 | rcpp_result_gen = Rcpp::wrap(get_conn_error()); 56 | return rcpp_result_gen; 57 | END_RCPP 58 | } 59 | // get_conn_info_ 60 | SEXP get_conn_info_(); 61 | RcppExport SEXP _rpg_get_conn_info_() { 62 | BEGIN_RCPP 63 | Rcpp::RObject rcpp_result_gen; 64 | Rcpp::RNGScope rcpp_rngScope_gen; 65 | rcpp_result_gen = Rcpp::wrap(get_conn_info_()); 66 | return rcpp_result_gen; 67 | END_RCPP 68 | } 69 | // result_dim 70 | IntegerVector result_dim(); 71 | RcppExport SEXP _rpg_result_dim() { 72 | BEGIN_RCPP 73 | Rcpp::RObject rcpp_result_gen; 74 | Rcpp::RNGScope rcpp_rngScope_gen; 75 | rcpp_result_gen = Rcpp::wrap(result_dim()); 76 | return rcpp_result_gen; 77 | END_RCPP 78 | } 79 | // get_tuple_info 80 | IntegerMatrix get_tuple_info(); 81 | RcppExport SEXP _rpg_get_tuple_info() { 82 | BEGIN_RCPP 83 | Rcpp::RObject rcpp_result_gen; 84 | Rcpp::RNGScope rcpp_rngScope_gen; 85 | rcpp_result_gen = Rcpp::wrap(get_tuple_info()); 86 | return rcpp_result_gen; 87 | END_RCPP 88 | } 89 | // query 90 | CharacterVector query(const char* sql, SEXP pars); 91 | RcppExport SEXP _rpg_query(SEXP sqlSEXP, SEXP parsSEXP) { 92 | BEGIN_RCPP 93 | Rcpp::RObject rcpp_result_gen; 94 | Rcpp::RNGScope rcpp_rngScope_gen; 95 | Rcpp::traits::input_parameter< const char* >::type sql(sqlSEXP); 96 | Rcpp::traits::input_parameter< SEXP >::type pars(parsSEXP); 97 | rcpp_result_gen = Rcpp::wrap(query(sql, pars)); 98 | return rcpp_result_gen; 99 | END_RCPP 100 | } 101 | // query_error 102 | CharacterVector query_error(); 103 | RcppExport SEXP _rpg_query_error() { 104 | BEGIN_RCPP 105 | Rcpp::RObject rcpp_result_gen; 106 | Rcpp::RNGScope rcpp_rngScope_gen; 107 | rcpp_result_gen = Rcpp::wrap(query_error()); 108 | return rcpp_result_gen; 109 | END_RCPP 110 | } 111 | // fetch_matrix 112 | CharacterMatrix fetch_matrix(); 113 | RcppExport SEXP _rpg_fetch_matrix() { 114 | BEGIN_RCPP 115 | Rcpp::RObject rcpp_result_gen; 116 | Rcpp::RNGScope rcpp_rngScope_gen; 117 | rcpp_result_gen = Rcpp::wrap(fetch_matrix()); 118 | return rcpp_result_gen; 119 | END_RCPP 120 | } 121 | // fetch_dataframe 122 | List fetch_dataframe(); 123 | RcppExport SEXP _rpg_fetch_dataframe() { 124 | BEGIN_RCPP 125 | Rcpp::RObject rcpp_result_gen; 126 | Rcpp::RNGScope rcpp_rngScope_gen; 127 | rcpp_result_gen = Rcpp::wrap(fetch_dataframe()); 128 | return rcpp_result_gen; 129 | END_RCPP 130 | } 131 | // trace_conn 132 | void trace_conn(const char* filename, bool append); 133 | RcppExport SEXP _rpg_trace_conn(SEXP filenameSEXP, SEXP appendSEXP) { 134 | BEGIN_RCPP 135 | Rcpp::RNGScope rcpp_rngScope_gen; 136 | Rcpp::traits::input_parameter< const char* >::type filename(filenameSEXP); 137 | Rcpp::traits::input_parameter< bool >::type append(appendSEXP); 138 | trace_conn(filename, append); 139 | return R_NilValue; 140 | END_RCPP 141 | } 142 | // untrace_conn 143 | void untrace_conn(bool remove); 144 | RcppExport SEXP _rpg_untrace_conn(SEXP removeSEXP) { 145 | BEGIN_RCPP 146 | Rcpp::RNGScope rcpp_rngScope_gen; 147 | Rcpp::traits::input_parameter< bool >::type remove(removeSEXP); 148 | untrace_conn(remove); 149 | return R_NilValue; 150 | END_RCPP 151 | } 152 | // trace_filename 153 | const char* trace_filename(); 154 | RcppExport SEXP _rpg_trace_filename() { 155 | BEGIN_RCPP 156 | Rcpp::RObject rcpp_result_gen; 157 | Rcpp::RNGScope rcpp_rngScope_gen; 158 | rcpp_result_gen = Rcpp::wrap(trace_filename()); 159 | return rcpp_result_gen; 160 | END_RCPP 161 | } 162 | // get_conn_defaults 163 | List get_conn_defaults(const bool all); 164 | RcppExport SEXP _rpg_get_conn_defaults(SEXP allSEXP) { 165 | BEGIN_RCPP 166 | Rcpp::RObject rcpp_result_gen; 167 | Rcpp::RNGScope rcpp_rngScope_gen; 168 | Rcpp::traits::input_parameter< const bool >::type all(allSEXP); 169 | rcpp_result_gen = Rcpp::wrap(get_conn_defaults(all)); 170 | return rcpp_result_gen; 171 | END_RCPP 172 | } 173 | // libpq_version 174 | int libpq_version(); 175 | RcppExport SEXP _rpg_libpq_version() { 176 | BEGIN_RCPP 177 | Rcpp::RObject rcpp_result_gen; 178 | Rcpp::RNGScope rcpp_rngScope_gen; 179 | rcpp_result_gen = Rcpp::wrap(libpq_version()); 180 | return rcpp_result_gen; 181 | END_RCPP 182 | } 183 | // encrypt_password 184 | const char* encrypt_password(const char* passwd, const char* user); 185 | RcppExport SEXP _rpg_encrypt_password(SEXP passwdSEXP, SEXP userSEXP) { 186 | BEGIN_RCPP 187 | Rcpp::RObject rcpp_result_gen; 188 | Rcpp::RNGScope rcpp_rngScope_gen; 189 | Rcpp::traits::input_parameter< const char* >::type passwd(passwdSEXP); 190 | Rcpp::traits::input_parameter< const char* >::type user(userSEXP); 191 | rcpp_result_gen = Rcpp::wrap(encrypt_password(passwd, user)); 192 | return rcpp_result_gen; 193 | END_RCPP 194 | } 195 | // get_encoding 196 | const char* get_encoding(); 197 | RcppExport SEXP _rpg_get_encoding() { 198 | BEGIN_RCPP 199 | Rcpp::RObject rcpp_result_gen; 200 | Rcpp::RNGScope rcpp_rngScope_gen; 201 | rcpp_result_gen = Rcpp::wrap(get_encoding()); 202 | return rcpp_result_gen; 203 | END_RCPP 204 | } 205 | // set_encoding 206 | bool set_encoding(const char* encoding); 207 | RcppExport SEXP _rpg_set_encoding(SEXP encodingSEXP) { 208 | BEGIN_RCPP 209 | Rcpp::RObject rcpp_result_gen; 210 | Rcpp::RNGScope rcpp_rngScope_gen; 211 | Rcpp::traits::input_parameter< const char* >::type encoding(encodingSEXP); 212 | rcpp_result_gen = Rcpp::wrap(set_encoding(encoding)); 213 | return rcpp_result_gen; 214 | END_RCPP 215 | } 216 | // set_error_verbosity 217 | void set_error_verbosity(std::string verbosity); 218 | RcppExport SEXP _rpg_set_error_verbosity(SEXP verbositySEXP) { 219 | BEGIN_RCPP 220 | Rcpp::RNGScope rcpp_rngScope_gen; 221 | Rcpp::traits::input_parameter< std::string >::type verbosity(verbositySEXP); 222 | set_error_verbosity(verbosity); 223 | return R_NilValue; 224 | END_RCPP 225 | } 226 | // check_transaction 227 | bool check_transaction(); 228 | RcppExport SEXP _rpg_check_transaction() { 229 | BEGIN_RCPP 230 | Rcpp::RObject rcpp_result_gen; 231 | Rcpp::RNGScope rcpp_rngScope_gen; 232 | rcpp_result_gen = Rcpp::wrap(check_transaction()); 233 | return rcpp_result_gen; 234 | END_RCPP 235 | } 236 | // prepare_ 237 | CharacterVector prepare_(const char* sql, const char* name); 238 | RcppExport SEXP _rpg_prepare_(SEXP sqlSEXP, SEXP nameSEXP) { 239 | BEGIN_RCPP 240 | Rcpp::RObject rcpp_result_gen; 241 | Rcpp::RNGScope rcpp_rngScope_gen; 242 | Rcpp::traits::input_parameter< const char* >::type sql(sqlSEXP); 243 | Rcpp::traits::input_parameter< const char* >::type name(nameSEXP); 244 | rcpp_result_gen = Rcpp::wrap(prepare_(sql, name)); 245 | return rcpp_result_gen; 246 | END_RCPP 247 | } 248 | // execute_prepared_ 249 | SEXP execute_prepared_(CharacterMatrix pars, const char* name); 250 | RcppExport SEXP _rpg_execute_prepared_(SEXP parsSEXP, SEXP nameSEXP) { 251 | BEGIN_RCPP 252 | Rcpp::RObject rcpp_result_gen; 253 | Rcpp::RNGScope rcpp_rngScope_gen; 254 | Rcpp::traits::input_parameter< CharacterMatrix >::type pars(parsSEXP); 255 | Rcpp::traits::input_parameter< const char* >::type name(nameSEXP); 256 | rcpp_result_gen = Rcpp::wrap(execute_prepared_(pars, name)); 257 | return rcpp_result_gen; 258 | END_RCPP 259 | } 260 | // num_prepared_params 261 | int num_prepared_params(const char* name); 262 | RcppExport SEXP _rpg_num_prepared_params(SEXP nameSEXP) { 263 | BEGIN_RCPP 264 | Rcpp::RObject rcpp_result_gen; 265 | Rcpp::RNGScope rcpp_rngScope_gen; 266 | Rcpp::traits::input_parameter< const char* >::type name(nameSEXP); 267 | rcpp_result_gen = Rcpp::wrap(num_prepared_params(name)); 268 | return rcpp_result_gen; 269 | END_RCPP 270 | } 271 | // push_conn 272 | void push_conn(); 273 | RcppExport SEXP _rpg_push_conn() { 274 | BEGIN_RCPP 275 | Rcpp::RNGScope rcpp_rngScope_gen; 276 | push_conn(); 277 | return R_NilValue; 278 | END_RCPP 279 | } 280 | // pop_conn 281 | void pop_conn(); 282 | RcppExport SEXP _rpg_pop_conn() { 283 | BEGIN_RCPP 284 | Rcpp::RNGScope rcpp_rngScope_gen; 285 | pop_conn(); 286 | return R_NilValue; 287 | END_RCPP 288 | } 289 | // swap_conn 290 | void swap_conn(); 291 | RcppExport SEXP _rpg_swap_conn() { 292 | BEGIN_RCPP 293 | Rcpp::RNGScope rcpp_rngScope_gen; 294 | swap_conn(); 295 | return R_NilValue; 296 | END_RCPP 297 | } 298 | // rotate_stack 299 | void rotate_stack(const int n); 300 | RcppExport SEXP _rpg_rotate_stack(SEXP nSEXP) { 301 | BEGIN_RCPP 302 | Rcpp::RNGScope rcpp_rngScope_gen; 303 | Rcpp::traits::input_parameter< const int >::type n(nSEXP); 304 | rotate_stack(n); 305 | return R_NilValue; 306 | END_RCPP 307 | } 308 | // show_conn_stack 309 | List show_conn_stack(); 310 | RcppExport SEXP _rpg_show_conn_stack() { 311 | BEGIN_RCPP 312 | Rcpp::RObject rcpp_result_gen; 313 | Rcpp::RNGScope rcpp_rngScope_gen; 314 | rcpp_result_gen = Rcpp::wrap(show_conn_stack()); 315 | return rcpp_result_gen; 316 | END_RCPP 317 | } 318 | // async_query 319 | bool async_query(const char* sql, SEXP pars); 320 | RcppExport SEXP _rpg_async_query(SEXP sqlSEXP, SEXP parsSEXP) { 321 | BEGIN_RCPP 322 | Rcpp::RObject rcpp_result_gen; 323 | Rcpp::RNGScope rcpp_rngScope_gen; 324 | Rcpp::traits::input_parameter< const char* >::type sql(sqlSEXP); 325 | Rcpp::traits::input_parameter< SEXP >::type pars(parsSEXP); 326 | rcpp_result_gen = Rcpp::wrap(async_query(sql, pars)); 327 | return rcpp_result_gen; 328 | END_RCPP 329 | } 330 | // async_status 331 | CharacterVector async_status(); 332 | RcppExport SEXP _rpg_async_status() { 333 | BEGIN_RCPP 334 | Rcpp::RObject rcpp_result_gen; 335 | Rcpp::RNGScope rcpp_rngScope_gen; 336 | rcpp_result_gen = Rcpp::wrap(async_status()); 337 | return rcpp_result_gen; 338 | END_RCPP 339 | } 340 | // is_busy 341 | bool is_busy(); 342 | RcppExport SEXP _rpg_is_busy() { 343 | BEGIN_RCPP 344 | Rcpp::RObject rcpp_result_gen; 345 | Rcpp::RNGScope rcpp_rngScope_gen; 346 | rcpp_result_gen = Rcpp::wrap(is_busy()); 347 | return rcpp_result_gen; 348 | END_RCPP 349 | } 350 | // cancel 351 | void cancel(); 352 | RcppExport SEXP _rpg_cancel() { 353 | BEGIN_RCPP 354 | Rcpp::RNGScope rcpp_rngScope_gen; 355 | cancel(); 356 | return R_NilValue; 357 | END_RCPP 358 | } 359 | // finish_async 360 | void finish_async(); 361 | RcppExport SEXP _rpg_finish_async() { 362 | BEGIN_RCPP 363 | Rcpp::RNGScope rcpp_rngScope_gen; 364 | finish_async(); 365 | return R_NilValue; 366 | END_RCPP 367 | } 368 | // exec_param_serialize 369 | CharacterVector exec_param_serialize(const char* sql, SEXP obj); 370 | RcppExport SEXP _rpg_exec_param_serialize(SEXP sqlSEXP, SEXP objSEXP) { 371 | BEGIN_RCPP 372 | Rcpp::RObject rcpp_result_gen; 373 | Rcpp::RNGScope rcpp_rngScope_gen; 374 | Rcpp::traits::input_parameter< const char* >::type sql(sqlSEXP); 375 | Rcpp::traits::input_parameter< SEXP >::type obj(objSEXP); 376 | rcpp_result_gen = Rcpp::wrap(exec_param_serialize(sql, obj)); 377 | return rcpp_result_gen; 378 | END_RCPP 379 | } 380 | // fetch_stowed 381 | List fetch_stowed(const char* sql, const char* par); 382 | RcppExport SEXP _rpg_fetch_stowed(SEXP sqlSEXP, SEXP parSEXP) { 383 | BEGIN_RCPP 384 | Rcpp::RObject rcpp_result_gen; 385 | Rcpp::RNGScope rcpp_rngScope_gen; 386 | Rcpp::traits::input_parameter< const char* >::type sql(sqlSEXP); 387 | Rcpp::traits::input_parameter< const char* >::type par(parSEXP); 388 | rcpp_result_gen = Rcpp::wrap(fetch_stowed(sql, par)); 389 | return rcpp_result_gen; 390 | END_RCPP 391 | } 392 | // register_return_formatter 393 | void register_return_formatter(int pgoid, Function f); 394 | RcppExport SEXP _rpg_register_return_formatter(SEXP pgoidSEXP, SEXP fSEXP) { 395 | BEGIN_RCPP 396 | Rcpp::RNGScope rcpp_rngScope_gen; 397 | Rcpp::traits::input_parameter< int >::type pgoid(pgoidSEXP); 398 | Rcpp::traits::input_parameter< Function >::type f(fSEXP); 399 | register_return_formatter(pgoid, f); 400 | return R_NilValue; 401 | END_RCPP 402 | } 403 | // toggle_echo 404 | void toggle_echo(); 405 | RcppExport SEXP _rpg_toggle_echo() { 406 | BEGIN_RCPP 407 | Rcpp::RNGScope rcpp_rngScope_gen; 408 | toggle_echo(); 409 | return R_NilValue; 410 | END_RCPP 411 | } 412 | 413 | static const R_CallMethodDef CallEntries[] = { 414 | {"_rpg_connect_", (DL_FUNC) &_rpg_connect_, 2}, 415 | {"_rpg_ping", (DL_FUNC) &_rpg_ping, 1}, 416 | {"_rpg_disconnect_", (DL_FUNC) &_rpg_disconnect_, 0}, 417 | {"_rpg_clean_up_all", (DL_FUNC) &_rpg_clean_up_all, 0}, 418 | {"_rpg_get_conn_error", (DL_FUNC) &_rpg_get_conn_error, 0}, 419 | {"_rpg_get_conn_info_", (DL_FUNC) &_rpg_get_conn_info_, 0}, 420 | {"_rpg_result_dim", (DL_FUNC) &_rpg_result_dim, 0}, 421 | {"_rpg_get_tuple_info", (DL_FUNC) &_rpg_get_tuple_info, 0}, 422 | {"_rpg_query", (DL_FUNC) &_rpg_query, 2}, 423 | {"_rpg_query_error", (DL_FUNC) &_rpg_query_error, 0}, 424 | {"_rpg_fetch_matrix", (DL_FUNC) &_rpg_fetch_matrix, 0}, 425 | {"_rpg_fetch_dataframe", (DL_FUNC) &_rpg_fetch_dataframe, 0}, 426 | {"_rpg_trace_conn", (DL_FUNC) &_rpg_trace_conn, 2}, 427 | {"_rpg_untrace_conn", (DL_FUNC) &_rpg_untrace_conn, 1}, 428 | {"_rpg_trace_filename", (DL_FUNC) &_rpg_trace_filename, 0}, 429 | {"_rpg_get_conn_defaults", (DL_FUNC) &_rpg_get_conn_defaults, 1}, 430 | {"_rpg_libpq_version", (DL_FUNC) &_rpg_libpq_version, 0}, 431 | {"_rpg_encrypt_password", (DL_FUNC) &_rpg_encrypt_password, 2}, 432 | {"_rpg_get_encoding", (DL_FUNC) &_rpg_get_encoding, 0}, 433 | {"_rpg_set_encoding", (DL_FUNC) &_rpg_set_encoding, 1}, 434 | {"_rpg_set_error_verbosity", (DL_FUNC) &_rpg_set_error_verbosity, 1}, 435 | {"_rpg_check_transaction", (DL_FUNC) &_rpg_check_transaction, 0}, 436 | {"_rpg_prepare_", (DL_FUNC) &_rpg_prepare_, 2}, 437 | {"_rpg_execute_prepared_", (DL_FUNC) &_rpg_execute_prepared_, 2}, 438 | {"_rpg_num_prepared_params", (DL_FUNC) &_rpg_num_prepared_params, 1}, 439 | {"_rpg_push_conn", (DL_FUNC) &_rpg_push_conn, 0}, 440 | {"_rpg_pop_conn", (DL_FUNC) &_rpg_pop_conn, 0}, 441 | {"_rpg_swap_conn", (DL_FUNC) &_rpg_swap_conn, 0}, 442 | {"_rpg_rotate_stack", (DL_FUNC) &_rpg_rotate_stack, 1}, 443 | {"_rpg_show_conn_stack", (DL_FUNC) &_rpg_show_conn_stack, 0}, 444 | {"_rpg_async_query", (DL_FUNC) &_rpg_async_query, 2}, 445 | {"_rpg_async_status", (DL_FUNC) &_rpg_async_status, 0}, 446 | {"_rpg_is_busy", (DL_FUNC) &_rpg_is_busy, 0}, 447 | {"_rpg_cancel", (DL_FUNC) &_rpg_cancel, 0}, 448 | {"_rpg_finish_async", (DL_FUNC) &_rpg_finish_async, 0}, 449 | {"_rpg_exec_param_serialize", (DL_FUNC) &_rpg_exec_param_serialize, 2}, 450 | {"_rpg_fetch_stowed", (DL_FUNC) &_rpg_fetch_stowed, 2}, 451 | {"_rpg_register_return_formatter", (DL_FUNC) &_rpg_register_return_formatter, 2}, 452 | {"_rpg_toggle_echo", (DL_FUNC) &_rpg_toggle_echo, 0}, 453 | {NULL, NULL, 0} 454 | }; 455 | 456 | RcppExport void R_init_rpg(DllInfo *dll) { 457 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); 458 | R_useDynamicSymbols(dll, FALSE); 459 | } 460 | -------------------------------------------------------------------------------- /src/rpg.h: -------------------------------------------------------------------------------- 1 | #ifndef __RPG_H__ 2 | #define __RPG_H__ 3 | 4 | #include "libpq-fe.h" 5 | 6 | #include 7 | using namespace Rcpp; 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | static PGconn* conn = NULL; 16 | static PGresult* res = NULL; 17 | static const char* tracefname = NULL; 18 | static std::FILE* tracef = NULL; 19 | 20 | static bool echo = false; 21 | 22 | static std::vector conn_stack; 23 | 24 | typedef std::map format_map_t; 25 | static format_map_t format_map; 26 | 27 | static void cancel_() 28 | { 29 | char buff[256]; 30 | memset(buff, '\0', 256); 31 | PGcancel *obj = PQgetCancel(conn); 32 | PQcancel(obj, buff, 256); 33 | PQfreeCancel(obj); 34 | } 35 | 36 | static void clear_res() 37 | { 38 | // Avoid blocking on PQgetResult 39 | cancel_(); 40 | do 41 | { 42 | PQclear(res); 43 | res = PQgetResult(conn); 44 | } while ( res ); 45 | } 46 | 47 | static void set_res(PGresult* x) 48 | { 49 | clear_res(); 50 | res = x; 51 | } 52 | 53 | static void clear_tracef() 54 | { 55 | PQuntrace(conn); 56 | if ( tracef ) fclose(tracef); 57 | tracef = NULL; 58 | } 59 | 60 | static void clear_conn() 61 | { 62 | clear_res(); 63 | clear_tracef(); 64 | PQfinish(conn); 65 | conn = NULL; 66 | } 67 | 68 | static void set_conn(PGconn* x) 69 | { 70 | clear_conn(); 71 | conn = x; 72 | } 73 | 74 | static void clear_stack() 75 | { 76 | if ( conn_stack.empty() ) return; 77 | if ( conn ) 78 | { 79 | conn_stack.insert(conn_stack.begin(), conn); 80 | conn = NULL; 81 | } 82 | while ( ! conn_stack.empty() ) 83 | { 84 | set_conn(conn_stack.back()); 85 | conn_stack.pop_back(); 86 | } 87 | } 88 | 89 | static void clear_all() 90 | { 91 | clear_stack(); 92 | clear_conn(); 93 | } 94 | 95 | static std::vector 96 | charvec_to_vec_cstr(CharacterVector x, const bool null_terminate = false) 97 | { 98 | std::vector out(x.size()); 99 | for ( int i = 0; i != x.size(); ++i ) 100 | out[i] = ( x[i] == NA_STRING ) ? NULL : as(x[i]); 101 | if ( null_terminate ) out.push_back(NULL); 102 | return out; 103 | } 104 | 105 | static void 106 | rpg_notice_processor(void *arg, const char *message) 107 | { 108 | Rf_warning(message); 109 | } 110 | 111 | static void finish_connection_setup() 112 | { 113 | if ( PQstatus(conn) == CONNECTION_OK ) 114 | { 115 | if ( PQprotocolVersion(conn) < 3 ) 116 | stop("PostgreSQL messaging protocol version < 3 not supported"); 117 | PQsetNoticeProcessor(conn, rpg_notice_processor, NULL); 118 | PQexec(conn, "set client_min_messages to warning"); 119 | } 120 | 121 | } 122 | 123 | static void setup_connection(CharacterVector keywords, CharacterVector values) 124 | { 125 | std::vector kw = charvec_to_vec_cstr(keywords, true), 126 | vals = charvec_to_vec_cstr(values, true); 127 | set_conn(PQconnectdbParams(&kw[0], &vals[0], 1)); 128 | finish_connection_setup(); 129 | } 130 | 131 | static void reset_connection() 132 | { 133 | PQreset(conn); 134 | finish_connection_setup(); 135 | } 136 | 137 | static void check_conn() 138 | { 139 | if ( PQstatus(conn) == CONNECTION_BAD ) 140 | { 141 | Rcout << "No connection... attempting reset... "; 142 | reset_connection(); 143 | if ( PQstatus(conn) == CONNECTION_BAD ) 144 | { 145 | Rcout << "nope... trying default... "; 146 | setup_connection(CharacterVector(), CharacterVector()); 147 | } 148 | if ( PQstatus(conn) == CONNECTION_BAD ) 149 | Rcout << "connection failed (try ping)." << std::endl; 150 | else 151 | Rcout << "that worked." << std::endl; 152 | } 153 | } 154 | 155 | static SEXP wrap_string(const char* s) 156 | { 157 | return s ? wrap(std::string(s)) : R_NilValue; 158 | } 159 | 160 | static SEXP connection_status_string() 161 | { 162 | switch ( PQstatus(conn) ) 163 | { 164 | case CONNECTION_OK: return wrap("CONNECTION_OK"); 165 | default: return wrap("CONNECTION_BAD"); 166 | } 167 | } 168 | 169 | static SEXP ping_status_string(const char* opts) 170 | { 171 | switch ( PQping(opts) ) 172 | { 173 | case PQPING_OK: return wrap("PQPING_OK"); 174 | case PQPING_REJECT: return wrap("PQPING_REJECT"); 175 | case PQPING_NO_RESPONSE: return wrap("PQPING_NO_RESPONSE"); 176 | default: return wrap("PQPING_NO_ATTEMPT"); 177 | } 178 | } 179 | 180 | static CharacterVector connection_error_string() 181 | { 182 | return PQerrorMessage(conn); 183 | } 184 | 185 | static SEXP trasaction_status_string() 186 | { 187 | switch ( PQtransactionStatus(conn) ) 188 | { 189 | case PQTRANS_IDLE: return wrap("PQTRANS_IDLE"); 190 | case PQTRANS_ACTIVE: return wrap("PQTRANS_ACTIVE"); 191 | case PQTRANS_INTRANS: return wrap("PQTRANS_INTRANS"); 192 | case PQTRANS_INERROR: return wrap("PQTRANS_INERROR"); 193 | default: return wrap("PQTRANS_UNKNOWN"); 194 | } 195 | } 196 | 197 | static SEXP fetch_par(const char* par) 198 | { 199 | const char* status = PQparameterStatus(conn, par); 200 | return status ? wrap(CharacterVector(status)) : R_NilValue; 201 | } 202 | 203 | static int send_exec_params(const char* sql, CharacterVector pars) 204 | { 205 | std::vector vals = charvec_to_vec_cstr(pars); 206 | return PQsendQueryParams(conn, sql, vals.size(), NULL, &vals[0], NULL, NULL, 0); 207 | } 208 | 209 | static void exec_params(const char* sql, CharacterVector pars) 210 | { 211 | std::vector vals = charvec_to_vec_cstr(pars); 212 | set_res(PQexecParams(conn, sql, vals.size(), NULL, &vals[0], NULL, NULL, 0)); 213 | } 214 | 215 | /* 216 | static void exec_prepared(CharacterVector pars, const char* name = "") 217 | { 218 | std::vector vals = charvec_to_vec_cstr(pars); 219 | set_res(PQexecPrepared(conn, name, vals.size(), &vals[0], NULL, NULL, 0)); 220 | } 221 | */ 222 | 223 | static void exec_prepared_rows(CharacterMatrix pars, const char* name = "") 224 | { 225 | for ( int i = 0; i != pars.nrow(); ++i ) 226 | { 227 | CharacterVector row = pars.row(i); 228 | std::vector vals = charvec_to_vec_cstr(row); 229 | set_res(PQexecPrepared(conn, name, vals.size(), &vals[0], NULL, NULL, 0)); 230 | if ( PQresultStatus(res) == PGRES_FATAL_ERROR ) return; 231 | } 232 | } 233 | 234 | static SEXP fetch_string(const int row = 0, const int col = 0) 235 | { 236 | if ( PQgetisnull(res, row, col) ) return NA_STRING; 237 | std::string val = PQgetvalue(res, row, col); 238 | return Rf_mkChar(val.c_str()); 239 | } 240 | 241 | static SEXP fetch_binary_text(const int row = 0, const int col = 0) 242 | { 243 | if ( PQgetisnull(res, row, col) ) return NA_STRING; 244 | char* val = PQgetvalue(res, row, col) + 1; 245 | int i = PQgetlength(res, row, col); 246 | val[i - 2] = '\0'; 247 | return Rf_mkChar(val); 248 | } 249 | 250 | static int fetch_int(const int row = 0, const int col = 0) 251 | { 252 | if ( PQgetisnull(res, row, col) ) return NA_INTEGER; 253 | std::string val = PQgetvalue(res, row, col); 254 | return atoi(val.c_str()); 255 | } 256 | 257 | static double fetch_double(const int row = 0, const int col = 0) 258 | { 259 | if ( PQgetisnull(res, row, col) ) return NA_REAL; 260 | std::string val = PQgetvalue(res, row, col); 261 | return atof(val.c_str()); 262 | } 263 | 264 | static int fetch_bool(const int row = 0, const int col = 0) 265 | { 266 | if ( PQgetisnull(res, row, col) ) return NA_LOGICAL; 267 | std::string val = PQgetvalue(res, row, col); 268 | return val.compare("t") ? 0 : 1; // weird 269 | } 270 | 271 | static Date fetch_date(const int row = 0, const int col = 0) 272 | { 273 | if ( PQgetisnull(res, row, col) ) return NA_INTEGER; 274 | std::string val = PQgetvalue(res, row, col); 275 | return Date(val); 276 | } 277 | 278 | static SEXP fetch_column(const int col = 0) 279 | { 280 | int nrow = PQntuples(res); 281 | Oid ftype = PQftype(res, col); 282 | format_map_t::iterator i = format_map.find(ftype); 283 | if (i != format_map.end()) 284 | { 285 | CharacterVector out(nrow); 286 | for ( int row = 0; row != nrow; ++row ) 287 | out[row] = fetch_string(row, col); 288 | Function f = as(i->second); 289 | return f(out); 290 | } 291 | switch (ftype) 292 | { 293 | case 16: 294 | { 295 | LogicalVector out(nrow); 296 | for ( int row = 0; row != nrow; ++row ) 297 | out[row] = fetch_bool(row, col); 298 | return wrap(out); 299 | } 300 | case 20: 301 | case 21: 302 | case 23: 303 | { 304 | IntegerVector out(nrow); 305 | for ( int row = 0; row != nrow; ++row ) 306 | out[row] = fetch_int(row, col); 307 | return wrap(out); 308 | } 309 | case 700: 310 | case 701: 311 | { 312 | NumericVector out(nrow); 313 | for ( int row = 0; row != nrow; ++row ) 314 | out[row] = fetch_double(row, col); 315 | return wrap(out); 316 | } 317 | case 1082: 318 | { 319 | DateVector out(nrow); 320 | for ( int row = 0; row != nrow; ++row ) 321 | out[row] = fetch_date(row, col); 322 | return wrap(out); 323 | } 324 | default: 325 | { 326 | CharacterVector out(nrow); 327 | for ( int row = 0; row != nrow; ++row ) 328 | out[row] = fetch_string(row, col); 329 | return wrap(out); 330 | } 331 | } 332 | return R_NilValue; 333 | } 334 | 335 | static const char* tempfile() 336 | { 337 | Function tf("tempfile"); 338 | return as(tf()); 339 | } 340 | 341 | static void unlink_file(const char* filename) 342 | { 343 | Function ul("unlink"); 344 | ul(filename); 345 | } 346 | 347 | static CharacterVector make_status(const char* status, 348 | const bool with_err = false, 349 | const bool with_cmd = false) 350 | { 351 | CharacterVector out(status); 352 | if ( with_err ) out.attr("error.message") = wrap_string(PQresultErrorMessage(res)); 353 | if ( with_cmd ) out.attr("command.status") = wrap_string(PQcmdStatus(res)); 354 | out.attr("class") = "pq.status"; 355 | return out; 356 | } 357 | 358 | static CharacterVector result_status(const bool with_err = true, 359 | const bool with_cmd = true) 360 | { 361 | return make_status(PQresStatus(PQresultStatus(res)), with_err, with_cmd); 362 | } 363 | 364 | #endif // __RPG_H__ 365 | -------------------------------------------------------------------------------- /tools/winlibs.R: -------------------------------------------------------------------------------- 1 | # Build against static libpq 2 | if(!file.exists("../windows/libpq-9.5.2/include/libpq-fe.h")){ 3 | if(getRversion() < "3.3.0") setInternet2() 4 | download.file("https://github.com/rwinlib/libpq/archive/v9.5.2.zip", "lib.zip", quiet = TRUE) 5 | dir.create("../windows", showWarnings = FALSE) 6 | unzip("lib.zip", exdir = "../windows") 7 | unlink("lib.zip") 8 | } 9 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/ecpg_config.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/ecpg_config.h. Generated from ecpg_config.h.in by configure. */ 2 | /* Define to 1 if the system has the type `int64'. */ 3 | /* #undef HAVE_INT64 */ 4 | 5 | /* Define to 1 if `long int' works and is 64 bits. */ 6 | /* #undef HAVE_LONG_INT_64 */ 7 | 8 | /* Define to 1 if the system has the type `__extension__ long long int'. */ 9 | #define HAVE_LONG_LONG_INT 1 10 | 11 | /* Define to 1 if `__extension__ long long int' works and is 64 bits. */ 12 | #define HAVE_LONG_LONG_INT_64 1 13 | 14 | /* Define to 1 if you want 64-bit integer timestamp and interval support. 15 | (--enable-integer-datetimes) */ 16 | #define USE_INTEGER_DATETIMES 1 17 | 18 | /* Define to 1 to build client libraries as thread-safe code. 19 | * (--enable-thread-safety) */ 20 | #define ENABLE_THREAD_SAFETY 1 21 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/ecpg_informix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains stuff needed to be as compatible to Informix as possible. 3 | * src/interfaces/ecpg/include/ecpg_informix.h 4 | */ 5 | #ifndef _ECPG_INFORMIX_H 6 | #define _ECPG_INFORMIX_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define SQLNOTFOUND 100 15 | 16 | #define ECPG_INFORMIX_NUM_OVERFLOW -1200 17 | #define ECPG_INFORMIX_NUM_UNDERFLOW -1201 18 | #define ECPG_INFORMIX_DIVIDE_ZERO -1202 19 | #define ECPG_INFORMIX_BAD_YEAR -1204 20 | #define ECPG_INFORMIX_BAD_MONTH -1205 21 | #define ECPG_INFORMIX_BAD_DAY -1206 22 | #define ECPG_INFORMIX_ENOSHORTDATE -1209 23 | #define ECPG_INFORMIX_DATE_CONVERT -1210 24 | #define ECPG_INFORMIX_OUT_OF_MEMORY -1211 25 | #define ECPG_INFORMIX_ENOTDMY -1212 26 | #define ECPG_INFORMIX_BAD_NUMERIC -1213 27 | #define ECPG_INFORMIX_BAD_EXPONENT -1216 28 | #define ECPG_INFORMIX_BAD_DATE -1218 29 | #define ECPG_INFORMIX_EXTRA_CHARS -1264 30 | 31 | #ifdef __cplusplus 32 | extern "C" 33 | { 34 | #endif 35 | 36 | extern int rdatestr(date, char *); 37 | extern void rtoday(date *); 38 | extern int rjulmdy(date, short *); 39 | extern int rdefmtdate(date *, char *, char *); 40 | extern int rfmtdate(date, char *, char *); 41 | extern int rmdyjul(short *, date *); 42 | extern int rstrdate(char *, date *); 43 | extern int rdayofweek(date); 44 | 45 | extern int rfmtlong(long, char *, char *); 46 | extern int rgetmsg(int, char *, int); 47 | extern int risnull(int, char *); 48 | extern int rsetnull(int, char *); 49 | extern int rtypalign(int, int); 50 | extern int rtypmsize(int, int); 51 | extern int rtypwidth(int, int); 52 | extern void rupshift(char *); 53 | 54 | extern int byleng(char *, int); 55 | extern void ldchar(char *, int, char *); 56 | 57 | extern void ECPG_informix_set_var(int, void *, int); 58 | extern void *ECPG_informix_get_var(int); 59 | extern void ECPG_informix_reset_sqlca(void); 60 | 61 | /* Informix defines these in decimal.h */ 62 | int decadd(decimal *, decimal *, decimal *); 63 | int deccmp(decimal *, decimal *); 64 | void deccopy(decimal *, decimal *); 65 | int deccvasc(char *, int, decimal *); 66 | int deccvdbl(double, decimal *); 67 | int deccvint(int, decimal *); 68 | int deccvlong(long, decimal *); 69 | int decdiv(decimal *, decimal *, decimal *); 70 | int decmul(decimal *, decimal *, decimal *); 71 | int decsub(decimal *, decimal *, decimal *); 72 | int dectoasc(decimal *, char *, int, int); 73 | int dectodbl(decimal *, double *); 74 | int dectoint(decimal *, int *); 75 | int dectolong(decimal *, long *); 76 | 77 | /* Informix defines these in datetime.h */ 78 | extern void dtcurrent(timestamp *); 79 | extern int dtcvasc(char *, timestamp *); 80 | extern int dtsub(timestamp *, timestamp *, interval *); 81 | extern int dttoasc(timestamp *, char *); 82 | extern int dttofmtasc(timestamp *, char *, int, char *); 83 | extern int intoasc(interval *, char *); 84 | extern int dtcvfmtasc(char *, char *, timestamp *); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* ndef _ECPG_INFORMIX_H */ 91 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/ecpgerrno.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/ecpgerrno.h */ 2 | 3 | #ifndef _ECPG_ERRNO_H 4 | #define _ECPG_ERRNO_H 5 | 6 | #include 7 | 8 | /* This is a list of all error codes the embedded SQL program can return */ 9 | #define ECPG_NO_ERROR 0 10 | #define ECPG_NOT_FOUND 100 11 | 12 | /* system error codes returned by ecpglib get the correct number, 13 | * but are made negative 14 | */ 15 | #define ECPG_OUT_OF_MEMORY -ENOMEM 16 | 17 | /* first we have a set of ecpg messages, they start at 200 */ 18 | #define ECPG_UNSUPPORTED -200 19 | #define ECPG_TOO_MANY_ARGUMENTS -201 20 | #define ECPG_TOO_FEW_ARGUMENTS -202 21 | #define ECPG_TOO_MANY_MATCHES -203 22 | #define ECPG_INT_FORMAT -204 23 | #define ECPG_UINT_FORMAT -205 24 | #define ECPG_FLOAT_FORMAT -206 25 | #define ECPG_NUMERIC_FORMAT -207 26 | #define ECPG_INTERVAL_FORMAT -208 27 | #define ECPG_DATE_FORMAT -209 28 | #define ECPG_TIMESTAMP_FORMAT -210 29 | #define ECPG_CONVERT_BOOL -211 30 | #define ECPG_EMPTY -212 31 | #define ECPG_MISSING_INDICATOR -213 32 | #define ECPG_NO_ARRAY -214 33 | #define ECPG_DATA_NOT_ARRAY -215 34 | #define ECPG_ARRAY_INSERT -216 35 | 36 | #define ECPG_NO_CONN -220 37 | #define ECPG_NOT_CONN -221 38 | 39 | #define ECPG_INVALID_STMT -230 40 | 41 | /* dynamic SQL related */ 42 | #define ECPG_UNKNOWN_DESCRIPTOR -240 43 | #define ECPG_INVALID_DESCRIPTOR_INDEX -241 44 | #define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242 45 | #define ECPG_VAR_NOT_NUMERIC -243 46 | #define ECPG_VAR_NOT_CHAR -244 47 | 48 | /* finally the backend error messages, they start at 400 */ 49 | #define ECPG_PGSQL -400 50 | #define ECPG_TRANS -401 51 | #define ECPG_CONNECT -402 52 | #define ECPG_DUPLICATE_KEY -403 53 | #define ECPG_SUBSELECT_NOT_ONE -404 54 | 55 | /* for compatibility we define some different error codes for the same error 56 | * if adding a new one make sure to not double define it */ 57 | #define ECPG_INFORMIX_DUPLICATE_KEY -239 58 | #define ECPG_INFORMIX_SUBSELECT_NOT_ONE -284 59 | 60 | /* backend WARNINGs, starting at 600 */ 61 | #define ECPG_WARNING_UNRECOGNIZED -600 62 | /* WARNING: (transaction aborted): queries ignored until END */ 63 | 64 | /* 65 | * WARNING: current transaction is aborted, queries ignored until end of 66 | * transaction block 67 | */ 68 | #define ECPG_WARNING_QUERY_IGNORED -601 69 | /* WARNING: PerformPortalClose: portal "*" not found */ 70 | #define ECPG_WARNING_UNKNOWN_PORTAL -602 71 | /* WARNING: BEGIN: already a transaction in progress */ 72 | #define ECPG_WARNING_IN_TRANSACTION -603 73 | /* WARNING: AbortTransaction and not in in-progress state */ 74 | /* WARNING: COMMIT: no transaction in progress */ 75 | #define ECPG_WARNING_NO_TRANSACTION -604 76 | /* WARNING: BlankPortalAssignName: portal * already exists */ 77 | #define ECPG_WARNING_PORTAL_EXISTS -605 78 | 79 | #endif /* !_ECPG_ERRNO_H */ 80 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/ecpglib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * this is a small part of c.h since we don't want to leak all postgres 3 | * definitions into ecpg programs 4 | * src/interfaces/ecpg/include/ecpglib.h 5 | */ 6 | 7 | #ifndef _ECPGLIB_H 8 | #define _ECPGLIB_H 9 | 10 | #include "libpq-fe.h" 11 | #include "ecpgtype.h" 12 | #include "sqlca.h" 13 | #include 14 | 15 | #ifdef ENABLE_NLS 16 | extern char *ecpg_gettext(const char *msgid) pg_attribute_format_arg(1); 17 | #else 18 | #define ecpg_gettext(x) (x) 19 | #endif 20 | 21 | #ifndef __cplusplus 22 | #ifndef bool 23 | #define bool char 24 | #endif /* ndef bool */ 25 | 26 | #ifndef true 27 | #define true ((bool) 1) 28 | #endif /* ndef true */ 29 | #ifndef false 30 | #define false ((bool) 0) 31 | #endif /* ndef false */ 32 | #endif /* not C++ */ 33 | 34 | #ifndef TRUE 35 | #define TRUE 1 36 | #endif /* TRUE */ 37 | 38 | #ifndef FALSE 39 | #define FALSE 0 40 | #endif /* FALSE */ 41 | 42 | #ifdef __cplusplus 43 | extern "C" 44 | { 45 | #endif 46 | 47 | void ECPGdebug(int, FILE *); 48 | bool ECPGstatus(int, const char *); 49 | bool ECPGsetcommit(int, const char *, const char *); 50 | bool ECPGsetconn(int, const char *); 51 | bool ECPGconnect(int, int, const char *, const char *, const char *, const char *, int); 52 | bool ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...); 53 | bool ECPGtrans(int, const char *, const char *); 54 | bool ECPGdisconnect(int, const char *); 55 | bool ECPGprepare(int, const char *, const bool, const char *, const char *); 56 | bool ECPGdeallocate(int, int, const char *, const char *); 57 | bool ECPGdeallocate_all(int, int, const char *); 58 | char *ECPGprepared_statement(const char *, const char *, int); 59 | PGconn *ECPGget_PGconn(const char *); 60 | PGTransactionStatusType ECPGtransactionStatus(const char *); 61 | 62 | char *ECPGerrmsg(void); 63 | 64 | /* print an error message */ 65 | void sqlprint(void); 66 | 67 | /* define this for simplicity as well as compatibility */ 68 | 69 | #define SQLCODE sqlca.sqlcode 70 | #define SQLSTATE sqlca.sqlstate 71 | 72 | /* dynamic SQL */ 73 | 74 | bool ECPGdo_descriptor(int, const char *, const char *, const char *); 75 | bool ECPGdeallocate_desc(int, const char *); 76 | bool ECPGallocate_desc(int, const char *); 77 | bool ECPGget_desc_header(int, const char *, int *); 78 | bool ECPGget_desc(int, const char *, int,...); 79 | bool ECPGset_desc_header(int, const char *, int); 80 | bool ECPGset_desc(int, const char *, int,...); 81 | 82 | void ECPGset_noind_null(enum ECPGttype, void *); 83 | bool ECPGis_noind_null(enum ECPGttype, void *); 84 | bool ECPGdescribe(int, int, bool, const char *, const char *,...); 85 | 86 | void ECPGset_var(int, void *, int); 87 | void *ECPGget_var(int number); 88 | 89 | /* dynamic result allocation */ 90 | void ECPGfree_auto_mem(void); 91 | 92 | #ifdef ENABLE_THREAD_SAFETY 93 | void ecpg_pthreads_init(void); 94 | #endif 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif /* _ECPGLIB_H */ 101 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/ecpgtype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file implements a data structure that is built and maintained by the 3 | * preprocessor. 4 | * 5 | * All types that can be handled for host variable declarations has to 6 | * be handled eventually. 7 | * 8 | * src/interfaces/ecpg/include/ecpgtype.h 9 | */ 10 | 11 | /* 12 | * Here are all the types that we are to handle. Note that it is the type 13 | * that is registered and that has nothing whatsoever to do with the storage 14 | * class. 15 | * 16 | * Simple types 17 | * integers: char, short, int, long (signed and unsigned) 18 | * floats: float, double 19 | * 20 | * Complex types: 21 | * VARCHAR, VARCHAR2 - Strings with length (maxlen is given in the declaration) 22 | * Arrays of simple types and of VARCHAR, VARCHAR2 (size given in declaration) 23 | * Records build of simple types, arrays and other structs. 24 | * 25 | * Complicating things: 26 | * typedefs and struct names! 27 | * 28 | * Conclusion: 29 | * This is a typically recursive definition. A structure of typed list elements 30 | * would probably work fine: 31 | */ 32 | 33 | #ifndef _ECPGTYPE_H 34 | #define _ECPGTYPE_H 35 | 36 | #ifdef __cplusplus 37 | extern "C" 38 | { 39 | #endif 40 | 41 | enum ECPGttype 42 | { 43 | ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short, 44 | ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long, 45 | ECPGt_long_long, ECPGt_unsigned_long_long, 46 | ECPGt_bool, 47 | ECPGt_float, ECPGt_double, 48 | ECPGt_varchar, ECPGt_varchar2, 49 | ECPGt_numeric, /* this is a decimal that stores its digits in 50 | * a malloced array */ 51 | ECPGt_decimal, /* this is a decimal that stores its digits in 52 | * a fixed array */ 53 | ECPGt_date, 54 | ECPGt_timestamp, 55 | ECPGt_interval, 56 | ECPGt_array, 57 | ECPGt_struct, 58 | ECPGt_union, 59 | ECPGt_descriptor, /* sql descriptor, no C variable */ 60 | ECPGt_char_variable, 61 | ECPGt_const, /* a constant is needed sometimes */ 62 | ECPGt_EOIT, /* End of insert types. */ 63 | ECPGt_EORT, /* End of result types. */ 64 | ECPGt_NO_INDICATOR, /* no indicator */ 65 | ECPGt_string, /* trimmed (char *) type */ 66 | ECPGt_sqlda /* C struct descriptor */ 67 | }; 68 | 69 | /* descriptor items */ 70 | enum ECPGdtype 71 | { 72 | ECPGd_count = 1, 73 | ECPGd_data, 74 | ECPGd_di_code, 75 | ECPGd_di_precision, 76 | ECPGd_indicator, 77 | ECPGd_key_member, 78 | ECPGd_length, 79 | ECPGd_name, 80 | ECPGd_nullable, 81 | ECPGd_octet, 82 | ECPGd_precision, 83 | ECPGd_ret_length, 84 | ECPGd_ret_octet, 85 | ECPGd_scale, 86 | ECPGd_type, 87 | ECPGd_EODT, /* End of descriptor types. */ 88 | ECPGd_cardinality 89 | }; 90 | 91 | #define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string)) 92 | 93 | /* we also have to handle different statement types */ 94 | enum ECPG_statement_type 95 | { 96 | ECPGst_normal, 97 | ECPGst_execute, 98 | ECPGst_exec_immediate, 99 | ECPGst_prepnormal 100 | }; 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif /* _ECPGTYPE_H */ 107 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/libpq-events.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * libpq-events.h 4 | * This file contains definitions that are useful to applications 5 | * that invoke the libpq "events" API, but are not interesting to 6 | * ordinary users of libpq. 7 | * 8 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 9 | * Portions Copyright (c) 1994, Regents of the University of California 10 | * 11 | * src/interfaces/libpq/libpq-events.h 12 | * 13 | *------------------------------------------------------------------------- 14 | */ 15 | 16 | #ifndef LIBPQ_EVENTS_H 17 | #define LIBPQ_EVENTS_H 18 | 19 | #include "libpq-fe.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif 25 | 26 | /* Callback Event Ids */ 27 | typedef enum 28 | { 29 | PGEVT_REGISTER, 30 | PGEVT_CONNRESET, 31 | PGEVT_CONNDESTROY, 32 | PGEVT_RESULTCREATE, 33 | PGEVT_RESULTCOPY, 34 | PGEVT_RESULTDESTROY 35 | } PGEventId; 36 | 37 | typedef struct 38 | { 39 | PGconn *conn; 40 | } PGEventRegister; 41 | 42 | typedef struct 43 | { 44 | PGconn *conn; 45 | } PGEventConnReset; 46 | 47 | typedef struct 48 | { 49 | PGconn *conn; 50 | } PGEventConnDestroy; 51 | 52 | typedef struct 53 | { 54 | PGconn *conn; 55 | PGresult *result; 56 | } PGEventResultCreate; 57 | 58 | typedef struct 59 | { 60 | const PGresult *src; 61 | PGresult *dest; 62 | } PGEventResultCopy; 63 | 64 | typedef struct 65 | { 66 | PGresult *result; 67 | } PGEventResultDestroy; 68 | 69 | typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); 70 | 71 | /* Registers an event proc with the given PGconn. */ 72 | extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, 73 | const char *name, void *passThrough); 74 | 75 | /* Sets the PGconn instance data for the provided proc to data. */ 76 | extern int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); 77 | 78 | /* Gets the PGconn instance data for the provided proc. */ 79 | extern void *PQinstanceData(const PGconn *conn, PGEventProc proc); 80 | 81 | /* Sets the PGresult instance data for the provided proc to data. */ 82 | extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data); 83 | 84 | /* Gets the PGresult instance data for the provided proc. */ 85 | extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); 86 | 87 | /* Fires RESULTCREATE events for an application-created PGresult. */ 88 | extern int PQfireResultCreateEvents(PGconn *conn, PGresult *res); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* LIBPQ_EVENTS_H */ 95 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/libpq/libpq-fs.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * libpq-fs.h 4 | * definitions for using Inversion file system routines (ie, large objects) 5 | * 6 | * 7 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 8 | * Portions Copyright (c) 1994, Regents of the University of California 9 | * 10 | * src/include/libpq/libpq-fs.h 11 | * 12 | *------------------------------------------------------------------------- 13 | */ 14 | #ifndef LIBPQ_FS_H 15 | #define LIBPQ_FS_H 16 | 17 | /* 18 | * Read/write mode flags for inversion (large object) calls 19 | */ 20 | 21 | #define INV_WRITE 0x00020000 22 | #define INV_READ 0x00040000 23 | 24 | #endif /* LIBPQ_FS_H */ 25 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pg_config_ext.h: -------------------------------------------------------------------------------- 1 | /* src/include/pg_config_ext.h. Generated from pg_config_ext.h.in by configure. */ 2 | /* 3 | * src/include/pg_config_ext.h.in. This is generated manually, not by 4 | * autoheader, since we want to limit which symbols get defined here. 5 | */ 6 | 7 | /* Define to the name of a signed 64-bit integer type. */ 8 | #define PG_INT64_TYPE __extension__ long long int 9 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pg_config_manual.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------ 2 | * PostgreSQL manual configuration settings 3 | * 4 | * This file contains various configuration symbols and limits. In 5 | * all cases, changing them is only useful in very rare situations or 6 | * for developers. If you edit any of these, be sure to do a *full* 7 | * rebuild (and an initdb if noted). 8 | * 9 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 10 | * Portions Copyright (c) 1994, Regents of the University of California 11 | * 12 | * src/include/pg_config_manual.h 13 | *------------------------------------------------------------------------ 14 | */ 15 | 16 | /* 17 | * Maximum length for identifiers (e.g. table names, column names, 18 | * function names). Names actually are limited to one less byte than this, 19 | * because the length must include a trailing zero byte. 20 | * 21 | * Changing this requires an initdb. 22 | */ 23 | #define NAMEDATALEN 64 24 | 25 | /* 26 | * Maximum number of arguments to a function. 27 | * 28 | * The minimum value is 8 (GIN indexes use 8-argument support functions). 29 | * The maximum possible value is around 600 (limited by index tuple size in 30 | * pg_proc's index; BLCKSZ larger than 8K would allow more). Values larger 31 | * than needed will waste memory and processing time, but do not directly 32 | * cost disk space. 33 | * 34 | * Changing this does not require an initdb, but it does require a full 35 | * backend recompile (including any user-defined C functions). 36 | */ 37 | #define FUNC_MAX_ARGS 100 38 | 39 | /* 40 | * Maximum number of columns in an index. There is little point in making 41 | * this anything but a multiple of 32, because the main cost is associated 42 | * with index tuple header size (see access/itup.h). 43 | * 44 | * Changing this requires an initdb. 45 | */ 46 | #define INDEX_MAX_KEYS 32 47 | 48 | /* 49 | * Set the upper and lower bounds of sequence values. 50 | */ 51 | #define SEQ_MAXVALUE PG_INT64_MAX 52 | #define SEQ_MINVALUE (-SEQ_MAXVALUE) 53 | 54 | /* 55 | * Number of spare LWLocks to allocate for user-defined add-on code. 56 | */ 57 | #define NUM_USER_DEFINED_LWLOCKS 4 58 | 59 | /* 60 | * When we don't have native spinlocks, we use semaphores to simulate them. 61 | * Decreasing this value reduces consumption of OS resources; increasing it 62 | * may improve performance, but supplying a real spinlock implementation is 63 | * probably far better. 64 | */ 65 | #define NUM_SPINLOCK_SEMAPHORES 1024 66 | 67 | /* 68 | * When we have neither spinlocks nor atomic operations support we're 69 | * implementing atomic operations on top of spinlock on top of semaphores. To 70 | * be safe against atomic operations while holding a spinlock separate 71 | * semaphores have to be used. 72 | */ 73 | #define NUM_ATOMICS_SEMAPHORES 64 74 | 75 | /* 76 | * Define this if you want to allow the lo_import and lo_export SQL 77 | * functions to be executed by ordinary users. By default these 78 | * functions are only available to the Postgres superuser. CAUTION: 79 | * These functions are SECURITY HOLES since they can read and write 80 | * any file that the PostgreSQL server has permission to access. If 81 | * you turn this on, don't say we didn't warn you. 82 | */ 83 | /* #define ALLOW_DANGEROUS_LO_FUNCTIONS */ 84 | 85 | /* 86 | * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, 87 | * maximum usable pathname length is one less). 88 | * 89 | * We'd use a standard system header symbol for this, if there weren't 90 | * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all 91 | * defined by different "standards", and often have different values 92 | * on the same platform! So we just punt and use a reasonably 93 | * generous setting here. 94 | */ 95 | #define MAXPGPATH 1024 96 | 97 | /* 98 | * PG_SOMAXCONN: maximum accept-queue length limit passed to 99 | * listen(2). You'd think we should use SOMAXCONN from 100 | * , but on many systems that symbol is much smaller 101 | * than the kernel's actual limit. In any case, this symbol need be 102 | * twiddled only if you have a kernel that refuses large limit values, 103 | * rather than silently reducing the value to what it can handle 104 | * (which is what most if not all Unixen do). 105 | */ 106 | #define PG_SOMAXCONN 10000 107 | 108 | /* 109 | * You can try changing this if you have a machine with bytes of 110 | * another size, but no guarantee... 111 | */ 112 | #define BITS_PER_BYTE 8 113 | 114 | /* 115 | * Preferred alignment for disk I/O buffers. On some CPUs, copies between 116 | * user space and kernel space are significantly faster if the user buffer 117 | * is aligned on a larger-than-MAXALIGN boundary. Ideally this should be 118 | * a platform-dependent value, but for now we just hard-wire it. 119 | */ 120 | #define ALIGNOF_BUFFER 32 121 | 122 | /* 123 | * Disable UNIX sockets for certain operating systems. 124 | */ 125 | #if defined(WIN32) 126 | #undef HAVE_UNIX_SOCKETS 127 | #endif 128 | 129 | /* 130 | * Define this if your operating system supports link() 131 | */ 132 | #if !defined(WIN32) && !defined(__CYGWIN__) 133 | #define HAVE_WORKING_LINK 1 134 | #endif 135 | 136 | /* 137 | * USE_POSIX_FADVISE controls whether Postgres will attempt to use the 138 | * posix_fadvise() kernel call. Usually the automatic configure tests are 139 | * sufficient, but some older Linux distributions had broken versions of 140 | * posix_fadvise(). If necessary you can remove the #define here. 141 | */ 142 | #if HAVE_DECL_POSIX_FADVISE && defined(HAVE_POSIX_FADVISE) 143 | #define USE_POSIX_FADVISE 144 | #endif 145 | 146 | /* 147 | * USE_PREFETCH code should be compiled only if we have a way to implement 148 | * prefetching. (This is decoupled from USE_POSIX_FADVISE because there 149 | * might in future be support for alternative low-level prefetch APIs.) 150 | */ 151 | #ifdef USE_POSIX_FADVISE 152 | #define USE_PREFETCH 153 | #endif 154 | 155 | /* 156 | * USE_SSL code should be compiled only when compiling with an SSL 157 | * implementation. (Currently, only OpenSSL is supported, but we might add 158 | * more implementations in the future.) 159 | */ 160 | #ifdef USE_OPENSSL 161 | #define USE_SSL 162 | #endif 163 | 164 | /* 165 | * This is the default directory in which AF_UNIX socket files are 166 | * placed. Caution: changing this risks breaking your existing client 167 | * applications, which are likely to continue to look in the old 168 | * directory. But if you just hate the idea of sockets in /tmp, 169 | * here's where to twiddle it. You can also override this at runtime 170 | * with the postmaster's -k switch. 171 | */ 172 | #define DEFAULT_PGSOCKET_DIR "/tmp" 173 | 174 | /* 175 | * This is the default event source for Windows event log. 176 | */ 177 | #define DEFAULT_EVENT_SOURCE "PostgreSQL" 178 | 179 | /* 180 | * The random() function is expected to yield values between 0 and 181 | * MAX_RANDOM_VALUE. Currently, all known implementations yield 182 | * 0..2^31-1, so we just hardwire this constant. We could do a 183 | * configure test if it proves to be necessary. CAUTION: Think not to 184 | * replace this with RAND_MAX. RAND_MAX defines the maximum value of 185 | * the older rand() function, which is often different from --- and 186 | * considerably inferior to --- random(). 187 | */ 188 | #define MAX_RANDOM_VALUE PG_INT32_MAX 189 | 190 | /* 191 | * On PPC machines, decide whether to use the mutex hint bit in LWARX 192 | * instructions. Setting the hint bit will slightly improve spinlock 193 | * performance on POWER6 and later machines, but does nothing before that, 194 | * and will result in illegal-instruction failures on some pre-POWER4 195 | * machines. By default we use the hint bit when building for 64-bit PPC, 196 | * which should be safe in nearly all cases. You might want to override 197 | * this if you are building 32-bit code for a known-recent PPC machine. 198 | */ 199 | #ifdef HAVE_PPC_LWARX_MUTEX_HINT /* must have assembler support in any case */ 200 | #if defined(__ppc64__) || defined(__powerpc64__) 201 | #define USE_PPC_LWARX_MUTEX_HINT 202 | #endif 203 | #endif 204 | 205 | /* 206 | * On PPC machines, decide whether to use LWSYNC instructions in place of 207 | * ISYNC and SYNC. This provides slightly better performance, but will 208 | * result in illegal-instruction failures on some pre-POWER4 machines. 209 | * By default we use LWSYNC when building for 64-bit PPC, which should be 210 | * safe in nearly all cases. 211 | */ 212 | #if defined(__ppc64__) || defined(__powerpc64__) 213 | #define USE_PPC_LWSYNC 214 | #endif 215 | 216 | /* 217 | * Assumed cache line size. This doesn't affect correctness, but can be used 218 | * for low-level optimizations. Currently, this is used to pad some data 219 | * structures in xlog.c, to ensure that highly-contended fields are on 220 | * different cache lines. Too small a value can hurt performance due to false 221 | * sharing, while the only downside of too large a value is a few bytes of 222 | * wasted memory. The default is 128, which should be large enough for all 223 | * supported platforms. 224 | */ 225 | #define PG_CACHE_LINE_SIZE 128 226 | 227 | /* 228 | *------------------------------------------------------------------------ 229 | * The following symbols are for enabling debugging code, not for 230 | * controlling user-visible features or resource limits. 231 | *------------------------------------------------------------------------ 232 | */ 233 | 234 | /* 235 | * Include Valgrind "client requests", mostly in the memory allocator, so 236 | * Valgrind understands PostgreSQL memory contexts. This permits detecting 237 | * memory errors that Valgrind would not detect on a vanilla build. See also 238 | * src/tools/valgrind.supp. "make installcheck" runs 20-30x longer under 239 | * Valgrind. Note that USE_VALGRIND slowed older versions of Valgrind by an 240 | * additional order of magnitude; Valgrind 3.8.1 does not have this problem. 241 | * The client requests fall in hot code paths, so USE_VALGRIND also slows 242 | * native execution by a few percentage points. 243 | * 244 | * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; 245 | * instrumentation of repalloc() is inferior without it. 246 | */ 247 | /* #define USE_VALGRIND */ 248 | 249 | /* 250 | * Define this to cause pfree()'d memory to be cleared immediately, to 251 | * facilitate catching bugs that refer to already-freed values. 252 | * Right now, this gets defined automatically if --enable-cassert. 253 | */ 254 | #ifdef USE_ASSERT_CHECKING 255 | #define CLOBBER_FREED_MEMORY 256 | #endif 257 | 258 | /* 259 | * Define this to check memory allocation errors (scribbling on more 260 | * bytes than were allocated). Right now, this gets defined 261 | * automatically if --enable-cassert or USE_VALGRIND. 262 | */ 263 | #if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND) 264 | #define MEMORY_CONTEXT_CHECKING 265 | #endif 266 | 267 | /* 268 | * Define this to cause palloc()'d memory to be filled with random data, to 269 | * facilitate catching code that depends on the contents of uninitialized 270 | * memory. Caution: this is horrendously expensive. 271 | */ 272 | /* #define RANDOMIZE_ALLOCATED_MEMORY */ 273 | 274 | /* 275 | * Define this to force all parse and plan trees to be passed through 276 | * copyObject(), to facilitate catching errors and omissions in 277 | * copyObject(). 278 | */ 279 | /* #define COPY_PARSE_PLAN_TREES */ 280 | 281 | /* 282 | * Enable debugging print statements for lock-related operations. 283 | */ 284 | /* #define LOCK_DEBUG */ 285 | 286 | /* 287 | * Enable debugging print statements for WAL-related operations; see 288 | * also the wal_debug GUC var. 289 | */ 290 | /* #define WAL_DEBUG */ 291 | 292 | /* 293 | * Enable tracing of resource consumption during sort operations; 294 | * see also the trace_sort GUC var. For 8.1 this is enabled by default. 295 | */ 296 | #define TRACE_SORT 1 297 | 298 | /* 299 | * Enable tracing of syncscan operations (see also the trace_syncscan GUC var). 300 | */ 301 | /* #define TRACE_SYNCSCAN */ 302 | 303 | /* 304 | * Other debug #defines (documentation, anyone?) 305 | */ 306 | /* #define HEAPDEBUGALL */ 307 | /* #define ACLDEBUG */ 308 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pg_config_os.h: -------------------------------------------------------------------------------- 1 | /* src/include/port/win32.h */ 2 | 3 | #if defined(_MSC_VER) || defined(__BORLANDC__) 4 | #define WIN32_ONLY_COMPILER 5 | #endif 6 | 7 | /* 8 | * Make sure _WIN32_WINNT has the minimum required value. 9 | * Leave a higher value in place. 10 | */ 11 | #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0501 12 | #undef _WIN32_WINNT 13 | #endif 14 | #ifndef _WIN32_WINNT 15 | #define _WIN32_WINNT 0x0501 16 | #endif 17 | /* 18 | * Always build with SSPI support. Keep it as a #define in case 19 | * we want a switch to disable it sometime in the future. 20 | */ 21 | #ifndef __BORLANDC__ 22 | #define ENABLE_SSPI 1 23 | #endif 24 | 25 | /* undefine and redefine after #include */ 26 | #undef mkdir 27 | 28 | #undef ERROR 29 | 30 | /* 31 | * The Mingw64 headers choke if this is already defined - they 32 | * define it themselves. 33 | */ 34 | #if !defined(__MINGW64_VERSION_MAJOR) || defined(WIN32_ONLY_COMPILER) 35 | #define _WINSOCKAPI_ 36 | #endif 37 | #include 38 | #include 39 | #include 40 | #undef small 41 | #include 42 | #include 43 | #include 44 | #include 45 | #ifndef __BORLANDC__ 46 | #include /* for non-unicode version */ 47 | #endif 48 | #undef near 49 | 50 | /* Must be here to avoid conflicting with prototype in windows.h */ 51 | #define mkdir(a,b) mkdir(a) 52 | 53 | #define ftruncate(a,b) chsize(a,b) 54 | 55 | /* Windows doesn't have fsync() as such, use _commit() */ 56 | #define fsync(fd) _commit(fd) 57 | 58 | /* 59 | * For historical reasons, we allow setting wal_sync_method to 60 | * fsync_writethrough on Windows, even though it's really identical to fsync 61 | * (both code paths wind up at _commit()). 62 | */ 63 | #define HAVE_FSYNC_WRITETHROUGH 64 | #define FSYNC_WRITETHROUGH_IS_FSYNC 65 | 66 | #define USES_WINSOCK 67 | 68 | /* defines for dynamic linking on Win32 platform 69 | * 70 | * http://support.microsoft.com/kb/132044 71 | * http://msdn.microsoft.com/en-us/library/8fskxacy(v=vs.80).aspx 72 | * http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx 73 | */ 74 | 75 | #if defined(WIN32) || defined(__CYGWIN__) 76 | 77 | #ifdef BUILDING_DLL 78 | #define PGDLLIMPORT __declspec (dllexport) 79 | #else /* not BUILDING_DLL */ 80 | #define PGDLLIMPORT __declspec (dllimport) 81 | #endif 82 | 83 | #ifdef _MSC_VER 84 | #define PGDLLEXPORT __declspec (dllexport) 85 | #else 86 | #define PGDLLEXPORT 87 | #endif 88 | #else /* not CYGWIN, not MSVC, not MingW */ 89 | #define PGDLLIMPORT 90 | #define PGDLLEXPORT 91 | #endif 92 | 93 | 94 | /* 95 | * IPC defines 96 | */ 97 | #undef HAVE_UNION_SEMUN 98 | #define HAVE_UNION_SEMUN 1 99 | 100 | #define IPC_RMID 256 101 | #define IPC_CREAT 512 102 | #define IPC_EXCL 1024 103 | #define IPC_PRIVATE 234564 104 | #define IPC_NOWAIT 2048 105 | #define IPC_STAT 4096 106 | 107 | #define EACCESS 2048 108 | #ifndef EIDRM 109 | #define EIDRM 4096 110 | #endif 111 | 112 | #define SETALL 8192 113 | #define GETNCNT 16384 114 | #define GETVAL 65536 115 | #define SETVAL 131072 116 | #define GETPID 262144 117 | 118 | 119 | /* 120 | * Signal stuff 121 | * 122 | * For WIN32, there is no wait() call so there are no wait() macros 123 | * to interpret the return value of system(). Instead, system() 124 | * return values < 0x100 are used for exit() termination, and higher 125 | * values are used to indicated non-exit() termination, which is 126 | * similar to a unix-style signal exit (think SIGSEGV == 127 | * STATUS_ACCESS_VIOLATION). Return values are broken up into groups: 128 | * 129 | * http://msdn2.microsoft.com/en-gb/library/aa489609.aspx 130 | * 131 | * NT_SUCCESS 0 - 0x3FFFFFFF 132 | * NT_INFORMATION 0x40000000 - 0x7FFFFFFF 133 | * NT_WARNING 0x80000000 - 0xBFFFFFFF 134 | * NT_ERROR 0xC0000000 - 0xFFFFFFFF 135 | * 136 | * Effectively, we don't care on the severity of the return value from 137 | * system(), we just need to know if it was because of exit() or generated 138 | * by the system, and it seems values >= 0x100 are system-generated. 139 | * See this URL for a list of WIN32 STATUS_* values: 140 | * 141 | * Wine (URL used in our error messages) - 142 | * http://source.winehq.org/source/include/ntstatus.h 143 | * Descriptions - http://www.comp.nus.edu.sg/~wuyongzh/my_doc/ntstatus.txt 144 | * MS SDK - http://www.nologs.com/ntstatus.html 145 | * 146 | * It seems the exception lists are in both ntstatus.h and winnt.h, but 147 | * ntstatus.h has a more comprehensive list, and it only contains 148 | * exception values, rather than winnt, which contains lots of other 149 | * things: 150 | * 151 | * http://www.microsoft.com/msj/0197/exception/exception.aspx 152 | * 153 | * The ExceptionCode parameter is the number that the operating system 154 | * assigned to the exception. You can see a list of various exception codes 155 | * in WINNT.H by searching for #defines that start with "STATUS_". For 156 | * example, the code for the all-too-familiar STATUS_ACCESS_VIOLATION is 157 | * 0xC0000005. A more complete set of exception codes can be found in 158 | * NTSTATUS.H from the Windows NT DDK. 159 | * 160 | * Some day we might want to print descriptions for the most common 161 | * exceptions, rather than printing an include file name. We could use 162 | * RtlNtStatusToDosError() and pass to FormatMessage(), which can print 163 | * the text of error values, but MinGW does not support 164 | * RtlNtStatusToDosError(). 165 | */ 166 | #define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) 167 | #define WIFSIGNALED(w) (!WIFEXITED(w)) 168 | #define WEXITSTATUS(w) (w) 169 | #define WTERMSIG(w) (w) 170 | 171 | #define sigmask(sig) ( 1 << ((sig)-1) ) 172 | 173 | /* Signal function return values */ 174 | #undef SIG_DFL 175 | #undef SIG_ERR 176 | #undef SIG_IGN 177 | #define SIG_DFL ((pqsigfunc)0) 178 | #define SIG_ERR ((pqsigfunc)-1) 179 | #define SIG_IGN ((pqsigfunc)1) 180 | 181 | /* Some extra signals */ 182 | #define SIGHUP 1 183 | #define SIGQUIT 3 184 | #define SIGTRAP 5 185 | #define SIGABRT 22 /* Set to match W32 value -- not UNIX value */ 186 | #define SIGKILL 9 187 | #define SIGPIPE 13 188 | #define SIGALRM 14 189 | #define SIGSTOP 17 190 | #define SIGTSTP 18 191 | #define SIGCONT 19 192 | #define SIGCHLD 20 193 | #define SIGTTIN 21 194 | #define SIGTTOU 22 /* Same as SIGABRT -- no problem, I hope */ 195 | #define SIGWINCH 28 196 | #ifndef __BORLANDC__ 197 | #define SIGUSR1 30 198 | #define SIGUSR2 31 199 | #endif 200 | 201 | /* 202 | * New versions of mingw have gettimeofday() and also declare 203 | * struct timezone to support it. 204 | */ 205 | #ifndef HAVE_GETTIMEOFDAY 206 | struct timezone 207 | { 208 | int tz_minuteswest; /* Minutes west of GMT. */ 209 | int tz_dsttime; /* Nonzero if DST is ever in effect. */ 210 | }; 211 | #endif 212 | 213 | /* for setitimer in backend/port/win32/timer.c */ 214 | #define ITIMER_REAL 0 215 | struct itimerval 216 | { 217 | struct timeval it_interval; 218 | struct timeval it_value; 219 | }; 220 | 221 | int setitimer(int which, const struct itimerval * value, struct itimerval * ovalue); 222 | 223 | /* 224 | * WIN32 does not provide 64-bit off_t, but does provide the functions operating 225 | * with 64-bit offsets. 226 | */ 227 | #define pgoff_t __int64 228 | #ifdef WIN32_ONLY_COMPILER 229 | #define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin) 230 | #define ftello(stream) _ftelli64(stream) 231 | #else 232 | #ifndef fseeko 233 | #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin) 234 | #endif 235 | #ifndef ftello 236 | #define ftello(stream) ftello64(stream) 237 | #endif 238 | #endif 239 | 240 | /* 241 | * Supplement to . 242 | * 243 | * Perl already has typedefs for uid_t and gid_t. 244 | */ 245 | #ifndef PLPERL_HAVE_UID_GID 246 | typedef int uid_t; 247 | typedef int gid_t; 248 | #endif 249 | typedef long key_t; 250 | 251 | #ifdef WIN32_ONLY_COMPILER 252 | typedef int pid_t; 253 | #endif 254 | 255 | /* 256 | * Supplement to . 257 | */ 258 | #define lstat(path, sb) stat((path), (sb)) 259 | 260 | /* 261 | * Supplement to . 262 | * This is the same value as _O_NOINHERIT in the MS header file. This is 263 | * to ensure that we don't collide with a future definition. It means 264 | * we cannot use _O_NOINHERIT ourselves. 265 | */ 266 | #define O_DSYNC 0x0080 267 | 268 | /* 269 | * Supplement to . 270 | */ 271 | #undef EAGAIN 272 | #undef EINTR 273 | #define EINTR WSAEINTR 274 | #define EAGAIN WSAEWOULDBLOCK 275 | #undef EMSGSIZE 276 | #define EMSGSIZE WSAEMSGSIZE 277 | #undef EAFNOSUPPORT 278 | #define EAFNOSUPPORT WSAEAFNOSUPPORT 279 | #undef EWOULDBLOCK 280 | #define EWOULDBLOCK WSAEWOULDBLOCK 281 | #undef ECONNRESET 282 | #define ECONNRESET WSAECONNRESET 283 | #undef EINPROGRESS 284 | #define EINPROGRESS WSAEINPROGRESS 285 | #undef ENOBUFS 286 | #define ENOBUFS WSAENOBUFS 287 | #undef EPROTONOSUPPORT 288 | #define EPROTONOSUPPORT WSAEPROTONOSUPPORT 289 | #undef ECONNREFUSED 290 | #define ECONNREFUSED WSAECONNREFUSED 291 | #undef EBADFD 292 | #define EBADFD WSAENOTSOCK 293 | #undef EOPNOTSUPP 294 | #define EOPNOTSUPP WSAEOPNOTSUPP 295 | 296 | /* 297 | * For Microsoft Visual Studio 2010 and above we intentionally redefine 298 | * the regular Berkeley error constants and set them to the WSA constants. 299 | * Note that this will break if those constants are used for anything else 300 | * than Windows Sockets errors. 301 | */ 302 | #if _MSC_VER >= 1600 303 | #pragma warning(disable:4005) 304 | #define EMSGSIZE WSAEMSGSIZE 305 | #define EAFNOSUPPORT WSAEAFNOSUPPORT 306 | #define EWOULDBLOCK WSAEWOULDBLOCK 307 | #define EPROTONOSUPPORT WSAEPROTONOSUPPORT 308 | #define ECONNRESET WSAECONNRESET 309 | #define EINPROGRESS WSAEINPROGRESS 310 | #define ENOBUFS WSAENOBUFS 311 | #define ECONNREFUSED WSAECONNREFUSED 312 | #define EOPNOTSUPP WSAEOPNOTSUPP 313 | #pragma warning(default:4005) 314 | #endif 315 | 316 | /* 317 | * Extended locale functions with gratuitous underscore prefixes. 318 | * (These APIs are nevertheless fully documented by Microsoft.) 319 | */ 320 | #define locale_t _locale_t 321 | #define tolower_l _tolower_l 322 | #define toupper_l _toupper_l 323 | #define towlower_l _towlower_l 324 | #define towupper_l _towupper_l 325 | #define isdigit_l _isdigit_l 326 | #define iswdigit_l _iswdigit_l 327 | #define isalpha_l _isalpha_l 328 | #define iswalpha_l _iswalpha_l 329 | #define isalnum_l _isalnum_l 330 | #define iswalnum_l _iswalnum_l 331 | #define isupper_l _isupper_l 332 | #define iswupper_l _iswupper_l 333 | #define islower_l _islower_l 334 | #define iswlower_l _iswlower_l 335 | #define isgraph_l _isgraph_l 336 | #define iswgraph_l _iswgraph_l 337 | #define isprint_l _isprint_l 338 | #define iswprint_l _iswprint_l 339 | #define ispunct_l _ispunct_l 340 | #define iswpunct_l _iswpunct_l 341 | #define isspace_l _isspace_l 342 | #define iswspace_l _iswspace_l 343 | #define strcoll_l _strcoll_l 344 | #define strxfrm_l _strxfrm_l 345 | #define wcscoll_l _wcscoll_l 346 | #define wcstombs_l _wcstombs_l 347 | #define mbstowcs_l _mbstowcs_l 348 | 349 | 350 | /* In backend/port/win32/signal.c */ 351 | extern PGDLLIMPORT volatile int pg_signal_queue; 352 | extern PGDLLIMPORT int pg_signal_mask; 353 | extern HANDLE pgwin32_signal_event; 354 | extern HANDLE pgwin32_initial_signal_pipe; 355 | 356 | #define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask) 357 | 358 | 359 | void pgwin32_signal_initialize(void); 360 | HANDLE pgwin32_create_signal_listener(pid_t pid); 361 | void pgwin32_dispatch_queued_signals(void); 362 | void pg_queue_signal(int signum); 363 | 364 | /* In backend/port/win32/socket.c */ 365 | #ifndef FRONTEND 366 | #define socket(af, type, protocol) pgwin32_socket(af, type, protocol) 367 | #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen) 368 | #define connect(s, name, namelen) pgwin32_connect(s, name, namelen) 369 | #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout) 370 | #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags) 371 | #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags) 372 | 373 | SOCKET pgwin32_socket(int af, int type, int protocol); 374 | SOCKET pgwin32_accept(SOCKET s, struct sockaddr * addr, int *addrlen); 375 | int pgwin32_connect(SOCKET s, const struct sockaddr * name, int namelen); 376 | int pgwin32_select(int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval * timeout); 377 | int pgwin32_recv(SOCKET s, char *buf, int len, int flags); 378 | int pgwin32_send(SOCKET s, const void *buf, int len, int flags); 379 | 380 | const char *pgwin32_socket_strerror(int err); 381 | int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout); 382 | 383 | extern int pgwin32_noblock; 384 | 385 | /* in backend/port/win32/security.c */ 386 | extern int pgwin32_is_admin(void); 387 | extern int pgwin32_is_service(void); 388 | #endif 389 | 390 | /* in backend/port/win32_shmem.c */ 391 | extern int pgwin32_ReserveSharedMemoryRegion(HANDLE); 392 | 393 | /* in backend/port/win32/crashdump.c */ 394 | extern void pgwin32_install_crashdump_handler(void); 395 | 396 | /* in port/win32error.c */ 397 | extern void _dosmaperr(unsigned long); 398 | 399 | /* in port/win32env.c */ 400 | extern int pgwin32_putenv(const char *); 401 | extern void pgwin32_unsetenv(const char *); 402 | 403 | #define putenv(x) pgwin32_putenv(x) 404 | #define unsetenv(x) pgwin32_unsetenv(x) 405 | 406 | /* Things that exist in MingW headers, but need to be added to MSVC & BCC */ 407 | #ifdef WIN32_ONLY_COMPILER 408 | 409 | #ifndef _WIN64 410 | typedef long ssize_t; 411 | #else 412 | typedef __int64 ssize_t; 413 | #endif 414 | 415 | #ifndef __BORLANDC__ 416 | typedef unsigned short mode_t; 417 | 418 | #define S_IRUSR _S_IREAD 419 | #define S_IWUSR _S_IWRITE 420 | #define S_IXUSR _S_IEXEC 421 | #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) 422 | /* see also S_IRGRP etc below */ 423 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 424 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 425 | #endif /* __BORLANDC__ */ 426 | 427 | #define F_OK 0 428 | #define W_OK 2 429 | #define R_OK 4 430 | 431 | #if (_MSC_VER < 1800) 432 | #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) || (_fpclass(x) == _FPCLASS_NINF)) 433 | #define isnan(x) _isnan(x) 434 | #endif 435 | 436 | /* Pulled from Makefile.port in mingw */ 437 | #define DLSUFFIX ".dll" 438 | 439 | #ifdef __BORLANDC__ 440 | 441 | /* for port/dirent.c */ 442 | #ifndef INVALID_FILE_ATTRIBUTES 443 | #define INVALID_FILE_ATTRIBUTES ((DWORD) -1) 444 | #endif 445 | 446 | /* for port/open.c */ 447 | #ifndef O_RANDOM 448 | #define O_RANDOM 0x0010 /* File access is primarily random */ 449 | #define O_SEQUENTIAL 0x0020 /* File access is primarily sequential */ 450 | #define O_TEMPORARY 0x0040 /* Temporary file bit */ 451 | #define O_SHORT_LIVED 0x1000 /* Temporary storage file, try not to flush */ 452 | #define _O_SHORT_LIVED O_SHORT_LIVED 453 | #endif /* ifndef O_RANDOM */ 454 | #endif /* __BORLANDC__ */ 455 | #endif /* WIN32_ONLY_COMPILER */ 456 | 457 | /* These aren't provided by either MingW or MSVC */ 458 | #ifndef __BORLANDC__ 459 | #define S_IRGRP 0 460 | #define S_IWGRP 0 461 | #define S_IXGRP 0 462 | #define S_IRWXG 0 463 | #define S_IROTH 0 464 | #define S_IWOTH 0 465 | #define S_IXOTH 0 466 | #define S_IRWXO 0 467 | 468 | #endif /* __BORLANDC__ */ 469 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pgtypes_date.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/pgtypes_date.h */ 2 | 3 | #ifndef PGTYPES_DATETIME 4 | #define PGTYPES_DATETIME 5 | 6 | #include 7 | 8 | typedef long date; 9 | 10 | #ifdef __cplusplus 11 | extern "C" 12 | { 13 | #endif 14 | 15 | extern date *PGTYPESdate_new(void); 16 | extern void PGTYPESdate_free(date *); 17 | extern date PGTYPESdate_from_asc(char *, char **); 18 | extern char *PGTYPESdate_to_asc(date); 19 | extern date PGTYPESdate_from_timestamp(timestamp); 20 | extern void PGTYPESdate_julmdy(date, int *); 21 | extern void PGTYPESdate_mdyjul(int *, date *); 22 | extern int PGTYPESdate_dayofweek(date); 23 | extern void PGTYPESdate_today(date *); 24 | extern int PGTYPESdate_defmt_asc(date *, const char *, char *); 25 | extern int PGTYPESdate_fmt_asc(date, const char *, char *); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* PGTYPES_DATETIME */ 32 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pgtypes_error.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/pgtypes_error.h */ 2 | 3 | #define PGTYPES_NUM_OVERFLOW 301 4 | #define PGTYPES_NUM_BAD_NUMERIC 302 5 | #define PGTYPES_NUM_DIVIDE_ZERO 303 6 | #define PGTYPES_NUM_UNDERFLOW 304 7 | 8 | #define PGTYPES_DATE_BAD_DATE 310 9 | #define PGTYPES_DATE_ERR_EARGS 311 10 | #define PGTYPES_DATE_ERR_ENOSHORTDATE 312 11 | #define PGTYPES_DATE_ERR_ENOTDMY 313 12 | #define PGTYPES_DATE_BAD_DAY 314 13 | #define PGTYPES_DATE_BAD_MONTH 315 14 | 15 | #define PGTYPES_TS_BAD_TIMESTAMP 320 16 | #define PGTYPES_TS_ERR_EINFTIME 321 17 | 18 | #define PGTYPES_INTVL_BAD_INTERVAL 330 19 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pgtypes_interval.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/pgtypes_interval.h */ 2 | 3 | #ifndef PGTYPES_INTERVAL 4 | #define PGTYPES_INTERVAL 5 | 6 | #include 7 | 8 | #ifndef C_H 9 | 10 | #ifdef HAVE_LONG_INT_64 11 | #ifndef HAVE_INT64 12 | typedef long int int64; 13 | #endif 14 | #elif defined(HAVE_LONG_LONG_INT_64) 15 | #ifndef HAVE_INT64 16 | typedef __extension__ long long int int64; 17 | #endif 18 | #else 19 | /* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ 20 | #error must have a working 64-bit integer datatype 21 | #endif 22 | 23 | #ifdef USE_INTEGER_DATETIMES 24 | #define HAVE_INT64_TIMESTAMP 25 | #endif 26 | #endif /* C_H */ 27 | 28 | typedef struct 29 | { 30 | #ifdef HAVE_INT64_TIMESTAMP 31 | int64 time; /* all time units other than months and years */ 32 | #else 33 | double time; /* all time units other than months and years */ 34 | #endif 35 | long month; /* months and years, after time for alignment */ 36 | } interval; 37 | 38 | #ifdef __cplusplus 39 | extern "C" 40 | { 41 | #endif 42 | 43 | extern interval *PGTYPESinterval_new(void); 44 | extern void PGTYPESinterval_free(interval *); 45 | extern interval *PGTYPESinterval_from_asc(char *, char **); 46 | extern char *PGTYPESinterval_to_asc(interval *); 47 | extern int PGTYPESinterval_copy(interval *, interval *); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* PGTYPES_INTERVAL */ 54 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pgtypes_numeric.h: -------------------------------------------------------------------------------- 1 | #ifndef PGTYPES_NUMERIC 2 | #define PGTYPES_NUMERIC 3 | 4 | #define NUMERIC_POS 0x0000 5 | #define NUMERIC_NEG 0x4000 6 | #define NUMERIC_NAN 0xC000 7 | #define NUMERIC_NULL 0xF000 8 | #define NUMERIC_MAX_PRECISION 1000 9 | #define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION 10 | #define NUMERIC_MIN_DISPLAY_SCALE 0 11 | #define NUMERIC_MIN_SIG_DIGITS 16 12 | 13 | #define DECSIZE 30 14 | 15 | typedef unsigned char NumericDigit; 16 | typedef struct 17 | { 18 | int ndigits; /* number of digits in digits[] - can be 0! */ 19 | int weight; /* weight of first digit */ 20 | int rscale; /* result scale */ 21 | int dscale; /* display scale */ 22 | int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ 23 | NumericDigit *buf; /* start of alloc'd space for digits[] */ 24 | NumericDigit *digits; /* decimal digits */ 25 | } numeric; 26 | 27 | typedef struct 28 | { 29 | int ndigits; /* number of digits in digits[] - can be 0! */ 30 | int weight; /* weight of first digit */ 31 | int rscale; /* result scale */ 32 | int dscale; /* display scale */ 33 | int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ 34 | NumericDigit digits[DECSIZE]; /* decimal digits */ 35 | } decimal; 36 | 37 | #ifdef __cplusplus 38 | extern "C" 39 | { 40 | #endif 41 | 42 | numeric *PGTYPESnumeric_new(void); 43 | decimal *PGTYPESdecimal_new(void); 44 | void PGTYPESnumeric_free(numeric *); 45 | void PGTYPESdecimal_free(decimal *); 46 | numeric *PGTYPESnumeric_from_asc(char *, char **); 47 | char *PGTYPESnumeric_to_asc(numeric *, int); 48 | int PGTYPESnumeric_add(numeric *, numeric *, numeric *); 49 | int PGTYPESnumeric_sub(numeric *, numeric *, numeric *); 50 | int PGTYPESnumeric_mul(numeric *, numeric *, numeric *); 51 | int PGTYPESnumeric_div(numeric *, numeric *, numeric *); 52 | int PGTYPESnumeric_cmp(numeric *, numeric *); 53 | int PGTYPESnumeric_from_int(signed int, numeric *); 54 | int PGTYPESnumeric_from_long(signed long int, numeric *); 55 | int PGTYPESnumeric_copy(numeric *, numeric *); 56 | int PGTYPESnumeric_from_double(double, numeric *); 57 | int PGTYPESnumeric_to_double(numeric *, double *); 58 | int PGTYPESnumeric_to_int(numeric *, int *); 59 | int PGTYPESnumeric_to_long(numeric *, long *); 60 | int PGTYPESnumeric_to_decimal(numeric *, decimal *); 61 | int PGTYPESnumeric_from_decimal(decimal *, numeric *); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /* PGTYPES_NUMERIC */ 68 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/pgtypes_timestamp.h: -------------------------------------------------------------------------------- 1 | /* src/interfaces/ecpg/include/pgtypes_timestamp.h */ 2 | 3 | #ifndef PGTYPES_TIMESTAMP 4 | #define PGTYPES_TIMESTAMP 5 | 6 | /* pgtypes_interval.h includes ecpg_config.h */ 7 | #include 8 | 9 | #ifdef HAVE_INT64_TIMESTAMP 10 | typedef int64 timestamp; 11 | typedef int64 TimestampTz; 12 | #else 13 | typedef double timestamp; 14 | typedef double TimestampTz; 15 | #endif 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | extern timestamp PGTYPEStimestamp_from_asc(char *, char **); 23 | extern char *PGTYPEStimestamp_to_asc(timestamp); 24 | extern int PGTYPEStimestamp_sub(timestamp *, timestamp *, interval *); 25 | extern int PGTYPEStimestamp_fmt_asc(timestamp *, char *, int, const char *); 26 | extern void PGTYPEStimestamp_current(timestamp *); 27 | extern int PGTYPEStimestamp_defmt_asc(char *, const char *, timestamp *); 28 | extern int PGTYPEStimestamp_add_interval(timestamp * tin, interval * span, timestamp * tout); 29 | extern int PGTYPEStimestamp_sub_interval(timestamp * tin, interval * span, timestamp * tout); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* PGTYPES_TIMESTAMP */ 36 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/postgres_ext.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * postgres_ext.h 4 | * 5 | * This file contains declarations of things that are visible everywhere 6 | * in PostgreSQL *and* are visible to clients of frontend interface libraries. 7 | * For example, the Oid type is part of the API of libpq and other libraries. 8 | * 9 | * Declarations which are specific to a particular interface should 10 | * go in the header file for that interface (such as libpq-fe.h). This 11 | * file is only for fundamental Postgres declarations. 12 | * 13 | * User-written C functions don't count as "external to Postgres." 14 | * Those function much as local modifications to the backend itself, and 15 | * use header files that are otherwise internal to Postgres to interface 16 | * with the backend. 17 | * 18 | * src/include/postgres_ext.h 19 | * 20 | *------------------------------------------------------------------------- 21 | */ 22 | 23 | #ifndef POSTGRES_EXT_H 24 | #define POSTGRES_EXT_H 25 | 26 | #include "pg_config_ext.h" 27 | 28 | /* 29 | * Object ID is a fundamental type in Postgres. 30 | */ 31 | typedef unsigned int Oid; 32 | 33 | #ifdef __cplusplus 34 | #define InvalidOid (Oid(0)) 35 | #else 36 | #define InvalidOid ((Oid) 0) 37 | #endif 38 | 39 | #define OID_MAX UINT_MAX 40 | /* you will need to include to use the above #define */ 41 | 42 | /* Define a signed 64-bit integer type for use in client API declarations. */ 43 | typedef PG_INT64_TYPE pg_int64; 44 | 45 | 46 | /* 47 | * Identifiers of error message fields. Kept here to keep common 48 | * between frontend and backend, and also to export them to libpq 49 | * applications. 50 | */ 51 | #define PG_DIAG_SEVERITY 'S' 52 | #define PG_DIAG_SQLSTATE 'C' 53 | #define PG_DIAG_MESSAGE_PRIMARY 'M' 54 | #define PG_DIAG_MESSAGE_DETAIL 'D' 55 | #define PG_DIAG_MESSAGE_HINT 'H' 56 | #define PG_DIAG_STATEMENT_POSITION 'P' 57 | #define PG_DIAG_INTERNAL_POSITION 'p' 58 | #define PG_DIAG_INTERNAL_QUERY 'q' 59 | #define PG_DIAG_CONTEXT 'W' 60 | #define PG_DIAG_SCHEMA_NAME 's' 61 | #define PG_DIAG_TABLE_NAME 't' 62 | #define PG_DIAG_COLUMN_NAME 'c' 63 | #define PG_DIAG_DATATYPE_NAME 'd' 64 | #define PG_DIAG_CONSTRAINT_NAME 'n' 65 | #define PG_DIAG_SOURCE_FILE 'F' 66 | #define PG_DIAG_SOURCE_LINE 'L' 67 | #define PG_DIAG_SOURCE_FUNCTION 'R' 68 | 69 | #endif /* POSTGRES_EXT_H */ 70 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/postgresql/internal/libpq/pqcomm.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * pqcomm.h 4 | * Definitions common to frontends and backends. 5 | * 6 | * NOTE: for historical reasons, this does not correspond to pqcomm.c. 7 | * pqcomm.c's routines are declared in libpq.h. 8 | * 9 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 10 | * Portions Copyright (c) 1994, Regents of the University of California 11 | * 12 | * src/include/libpq/pqcomm.h 13 | * 14 | *------------------------------------------------------------------------- 15 | */ 16 | #ifndef PQCOMM_H 17 | #define PQCOMM_H 18 | 19 | #include 20 | #include 21 | #ifdef HAVE_SYS_UN_H 22 | #include 23 | #endif 24 | #include 25 | 26 | #ifdef HAVE_STRUCT_SOCKADDR_STORAGE 27 | 28 | #ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 29 | #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 30 | #define ss_family __ss_family 31 | #else 32 | #error struct sockaddr_storage does not provide an ss_family member 33 | #endif 34 | #endif 35 | 36 | #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 37 | #define ss_len __ss_len 38 | #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 39 | #endif 40 | #else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ 41 | 42 | /* Define a struct sockaddr_storage if we don't have one. */ 43 | 44 | struct sockaddr_storage 45 | { 46 | union 47 | { 48 | struct sockaddr sa; /* get the system-dependent fields */ 49 | int64 ss_align; /* ensures struct is properly aligned */ 50 | char ss_pad[128]; /* ensures struct has desired size */ 51 | } ss_stuff; 52 | }; 53 | 54 | #define ss_family ss_stuff.sa.sa_family 55 | /* It should have an ss_len field if sockaddr has sa_len. */ 56 | #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 57 | #define ss_len ss_stuff.sa.sa_len 58 | #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 59 | #endif 60 | #endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ 61 | 62 | typedef struct 63 | { 64 | struct sockaddr_storage addr; 65 | ACCEPT_TYPE_ARG3 salen; 66 | } SockAddr; 67 | 68 | /* Configure the UNIX socket location for the well known port. */ 69 | 70 | #define UNIXSOCK_PATH(path, port, sockdir) \ 71 | snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \ 72 | ((sockdir) && *(sockdir) != '\0') ? (sockdir) : \ 73 | DEFAULT_PGSOCKET_DIR, \ 74 | (port)) 75 | 76 | /* 77 | * The maximum workable length of a socket path is what will fit into 78 | * struct sockaddr_un. This is usually only 100 or so bytes :-(. 79 | * 80 | * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), 81 | * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. 82 | * (Because the standard API for getaddrinfo doesn't allow it to complain in 83 | * a useful way when the socket pathname is too long, we have to test for 84 | * this explicitly, instead of just letting the subroutine return an error.) 85 | */ 86 | #define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) 87 | 88 | 89 | /* 90 | * These manipulate the frontend/backend protocol version number. 91 | * 92 | * The major number should be incremented for incompatible changes. The minor 93 | * number should be incremented for compatible changes (eg. additional 94 | * functionality). 95 | * 96 | * If a backend supports version m.n of the protocol it must actually support 97 | * versions m.[0..n]. Backend support for version m-1 can be dropped after a 98 | * `reasonable' length of time. 99 | * 100 | * A frontend isn't required to support anything other than the current 101 | * version. 102 | */ 103 | 104 | #define PG_PROTOCOL_MAJOR(v) ((v) >> 16) 105 | #define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) 106 | #define PG_PROTOCOL(m,n) (((m) << 16) | (n)) 107 | 108 | /* The earliest and latest frontend/backend protocol version supported. */ 109 | 110 | #define PG_PROTOCOL_EARLIEST PG_PROTOCOL(1,0) 111 | #define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) 112 | 113 | typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ 114 | 115 | typedef ProtocolVersion MsgType; 116 | 117 | 118 | /* 119 | * Packet lengths are 4 bytes in network byte order. 120 | * 121 | * The initial length is omitted from the packet layouts appearing below. 122 | */ 123 | 124 | typedef uint32 PacketLen; 125 | 126 | 127 | /* 128 | * Old-style startup packet layout with fixed-width fields. This is used in 129 | * protocol 1.0 and 2.0, but not in later versions. Note that the fields 130 | * in this layout are '\0' terminated only if there is room. 131 | */ 132 | 133 | #define SM_DATABASE 64 134 | #define SM_USER 32 135 | /* We append database name if db_user_namespace true. */ 136 | #define SM_DATABASE_USER (SM_DATABASE+SM_USER+1) /* +1 for @ */ 137 | #define SM_OPTIONS 64 138 | #define SM_UNUSED 64 139 | #define SM_TTY 64 140 | 141 | typedef struct StartupPacket 142 | { 143 | ProtocolVersion protoVersion; /* Protocol version */ 144 | char database[SM_DATABASE]; /* Database name */ 145 | /* Db_user_namespace appends dbname */ 146 | char user[SM_USER]; /* User name */ 147 | char options[SM_OPTIONS]; /* Optional additional args */ 148 | char unused[SM_UNUSED]; /* Unused */ 149 | char tty[SM_TTY]; /* Tty for debug output */ 150 | } StartupPacket; 151 | 152 | extern bool Db_user_namespace; 153 | 154 | /* 155 | * In protocol 3.0 and later, the startup packet length is not fixed, but 156 | * we set an arbitrary limit on it anyway. This is just to prevent simple 157 | * denial-of-service attacks via sending enough data to run the server 158 | * out of memory. 159 | */ 160 | #define MAX_STARTUP_PACKET_LENGTH 10000 161 | 162 | 163 | /* These are the authentication request codes sent by the backend. */ 164 | 165 | #define AUTH_REQ_OK 0 /* User is authenticated */ 166 | #define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ 167 | #define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ 168 | #define AUTH_REQ_PASSWORD 3 /* Password */ 169 | #define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ 170 | #define AUTH_REQ_MD5 5 /* md5 password */ 171 | #define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */ 172 | #define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ 173 | #define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ 174 | #define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ 175 | 176 | typedef uint32 AuthRequest; 177 | 178 | 179 | /* 180 | * A client can also send a cancel-current-operation request to the postmaster. 181 | * This is uglier than sending it directly to the client's backend, but it 182 | * avoids depending on out-of-band communication facilities. 183 | * 184 | * The cancel request code must not match any protocol version number 185 | * we're ever likely to use. This random choice should do. 186 | */ 187 | #define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) 188 | 189 | typedef struct CancelRequestPacket 190 | { 191 | /* Note that each field is stored in network byte order! */ 192 | MsgType cancelRequestCode; /* code to identify a cancel request */ 193 | uint32 backendPID; /* PID of client's backend */ 194 | uint32 cancelAuthCode; /* secret key to authorize cancel */ 195 | } CancelRequestPacket; 196 | 197 | 198 | /* 199 | * A client can also start by sending a SSL negotiation request, to get a 200 | * secure channel. 201 | */ 202 | #define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) 203 | 204 | #endif /* PQCOMM_H */ 205 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/postgresql/internal/port.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * port.h 4 | * Header for src/port/ compatibility functions. 5 | * 6 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 7 | * Portions Copyright (c) 1994, Regents of the University of California 8 | * 9 | * src/include/port.h 10 | * 11 | *------------------------------------------------------------------------- 12 | */ 13 | #ifndef PG_PORT_H 14 | #define PG_PORT_H 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /* socket has a different definition on WIN32 */ 21 | #ifndef WIN32 22 | typedef int pgsocket; 23 | 24 | #define PGINVALID_SOCKET (-1) 25 | #else 26 | typedef SOCKET pgsocket; 27 | 28 | #define PGINVALID_SOCKET INVALID_SOCKET 29 | #endif 30 | 31 | /* non-blocking */ 32 | extern bool pg_set_noblock(pgsocket sock); 33 | extern bool pg_set_block(pgsocket sock); 34 | 35 | /* Portable path handling for Unix/Win32 (in path.c) */ 36 | 37 | extern bool has_drive_prefix(const char *filename); 38 | extern char *first_dir_separator(const char *filename); 39 | extern char *last_dir_separator(const char *filename); 40 | extern char *first_path_var_separator(const char *pathlist); 41 | extern void join_path_components(char *ret_path, 42 | const char *head, const char *tail); 43 | extern void canonicalize_path(char *path); 44 | extern void make_native_path(char *path); 45 | extern bool path_contains_parent_reference(const char *path); 46 | extern bool path_is_relative_and_below_cwd(const char *path); 47 | extern bool path_is_prefix_of_path(const char *path1, const char *path2); 48 | extern char *make_absolute_path(const char *path); 49 | extern const char *get_progname(const char *argv0); 50 | extern void get_share_path(const char *my_exec_path, char *ret_path); 51 | extern void get_etc_path(const char *my_exec_path, char *ret_path); 52 | extern void get_include_path(const char *my_exec_path, char *ret_path); 53 | extern void get_pkginclude_path(const char *my_exec_path, char *ret_path); 54 | extern void get_includeserver_path(const char *my_exec_path, char *ret_path); 55 | extern void get_lib_path(const char *my_exec_path, char *ret_path); 56 | extern void get_pkglib_path(const char *my_exec_path, char *ret_path); 57 | extern void get_locale_path(const char *my_exec_path, char *ret_path); 58 | extern void get_doc_path(const char *my_exec_path, char *ret_path); 59 | extern void get_html_path(const char *my_exec_path, char *ret_path); 60 | extern void get_man_path(const char *my_exec_path, char *ret_path); 61 | extern bool get_home_path(char *ret_path); 62 | extern void get_parent_directory(char *path); 63 | 64 | /* common/pgfnames.c */ 65 | extern char **pgfnames(const char *path); 66 | extern void pgfnames_cleanup(char **filenames); 67 | 68 | /* 69 | * is_absolute_path 70 | * 71 | * By making this a macro we avoid needing to include path.c in libpq. 72 | */ 73 | #ifndef WIN32 74 | #define IS_DIR_SEP(ch) ((ch) == '/') 75 | 76 | #define is_absolute_path(filename) \ 77 | ( \ 78 | IS_DIR_SEP((filename)[0]) \ 79 | ) 80 | #else 81 | #define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') 82 | 83 | /* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ 84 | #define is_absolute_path(filename) \ 85 | ( \ 86 | IS_DIR_SEP((filename)[0]) || \ 87 | (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ 88 | IS_DIR_SEP((filename)[2])) \ 89 | ) 90 | #endif 91 | 92 | /* Portable locale initialization (in exec.c) */ 93 | extern void set_pglocale_pgservice(const char *argv0, const char *app); 94 | 95 | /* Portable way to find binaries (in exec.c) */ 96 | extern int find_my_exec(const char *argv0, char *retpath); 97 | extern int find_other_exec(const char *argv0, const char *target, 98 | const char *versionstr, char *retpath); 99 | 100 | /* Windows security token manipulation (in exec.c) */ 101 | #ifdef WIN32 102 | extern BOOL AddUserToTokenDacl(HANDLE hToken); 103 | #endif 104 | 105 | 106 | #if defined(WIN32) || defined(__CYGWIN__) 107 | #define EXE ".exe" 108 | #else 109 | #define EXE "" 110 | #endif 111 | 112 | #if defined(WIN32) && !defined(__CYGWIN__) 113 | #define DEVNULL "nul" 114 | #else 115 | #define DEVNULL "/dev/null" 116 | #endif 117 | 118 | /* Portable delay handling */ 119 | extern void pg_usleep(long microsec); 120 | 121 | /* Portable SQL-like case-independent comparisons and conversions */ 122 | extern int pg_strcasecmp(const char *s1, const char *s2); 123 | extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); 124 | extern unsigned char pg_toupper(unsigned char ch); 125 | extern unsigned char pg_tolower(unsigned char ch); 126 | extern unsigned char pg_ascii_toupper(unsigned char ch); 127 | extern unsigned char pg_ascii_tolower(unsigned char ch); 128 | 129 | #ifdef USE_REPL_SNPRINTF 130 | 131 | /* 132 | * Versions of libintl >= 0.13 try to replace printf() and friends with 133 | * macros to their own versions that understand the %$ format. We do the 134 | * same, so disable their macros, if they exist. 135 | */ 136 | #ifdef vsnprintf 137 | #undef vsnprintf 138 | #endif 139 | #ifdef snprintf 140 | #undef snprintf 141 | #endif 142 | #ifdef sprintf 143 | #undef sprintf 144 | #endif 145 | #ifdef vfprintf 146 | #undef vfprintf 147 | #endif 148 | #ifdef fprintf 149 | #undef fprintf 150 | #endif 151 | #ifdef printf 152 | #undef printf 153 | #endif 154 | 155 | extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); 156 | extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); 157 | extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); 158 | extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args); 159 | extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); 160 | extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); 161 | 162 | /* 163 | * The GCC-specific code below prevents the pg_attribute_printf above from 164 | * being replaced, and this is required because gcc doesn't know anything 165 | * about pg_printf. 166 | */ 167 | #ifdef __GNUC__ 168 | #define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) 169 | #define snprintf(...) pg_snprintf(__VA_ARGS__) 170 | #define sprintf(...) pg_sprintf(__VA_ARGS__) 171 | #define vfprintf(...) pg_vfprintf(__VA_ARGS__) 172 | #define fprintf(...) pg_fprintf(__VA_ARGS__) 173 | #define printf(...) pg_printf(__VA_ARGS__) 174 | #else 175 | #define vsnprintf pg_vsnprintf 176 | #define snprintf pg_snprintf 177 | #define sprintf pg_sprintf 178 | #define vfprintf pg_vfprintf 179 | #define fprintf pg_fprintf 180 | #define printf pg_printf 181 | #endif 182 | #endif /* USE_REPL_SNPRINTF */ 183 | 184 | #if defined(WIN32) 185 | /* 186 | * Versions of libintl >= 0.18? try to replace setlocale() with a macro 187 | * to their own versions. Remove the macro, if it exists, because it 188 | * ends up calling the wrong version when the backend and libintl use 189 | * different versions of msvcrt. 190 | */ 191 | #if defined(setlocale) 192 | #undef setlocale 193 | #endif 194 | 195 | /* 196 | * Define our own wrapper macro around setlocale() to work around bugs in 197 | * Windows' native setlocale() function. 198 | */ 199 | extern char *pgwin32_setlocale(int category, const char *locale); 200 | 201 | #define setlocale(a,b) pgwin32_setlocale(a,b) 202 | #endif /* WIN32 */ 203 | 204 | /* Portable prompt handling */ 205 | extern char *simple_prompt(const char *prompt, int maxlen, bool echo); 206 | 207 | #ifdef WIN32 208 | #define PG_SIGNAL_COUNT 32 209 | #define kill(pid,sig) pgkill(pid,sig) 210 | extern int pgkill(int pid, int sig); 211 | #endif 212 | 213 | extern int pclose_check(FILE *stream); 214 | 215 | /* Global variable holding time zone information. */ 216 | #ifndef __CYGWIN__ 217 | #define TIMEZONE_GLOBAL timezone 218 | #define TZNAME_GLOBAL tzname 219 | #else 220 | #define TIMEZONE_GLOBAL _timezone 221 | #define TZNAME_GLOBAL _tzname 222 | #endif 223 | 224 | #if defined(WIN32) || defined(__CYGWIN__) 225 | /* 226 | * Win32 doesn't have reliable rename/unlink during concurrent access. 227 | */ 228 | extern int pgrename(const char *from, const char *to); 229 | extern int pgunlink(const char *path); 230 | 231 | /* Include this first so later includes don't see these defines */ 232 | #ifdef WIN32_ONLY_COMPILER 233 | #include 234 | #endif 235 | 236 | #define rename(from, to) pgrename(from, to) 237 | #define unlink(path) pgunlink(path) 238 | #endif /* defined(WIN32) || defined(__CYGWIN__) */ 239 | 240 | /* 241 | * Win32 also doesn't have symlinks, but we can emulate them with 242 | * junction points on newer Win32 versions. 243 | * 244 | * Cygwin has its own symlinks which work on Win95/98/ME where 245 | * junction points don't, so use those instead. We have no way of 246 | * knowing what type of system Cygwin binaries will be run on. 247 | * Note: Some CYGWIN includes might #define WIN32. 248 | */ 249 | #if defined(WIN32) && !defined(__CYGWIN__) 250 | extern int pgsymlink(const char *oldpath, const char *newpath); 251 | extern int pgreadlink(const char *path, char *buf, size_t size); 252 | extern bool pgwin32_is_junction(char *path); 253 | 254 | #define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) 255 | #define readlink(path, buf, size) pgreadlink(path, buf, size) 256 | #endif 257 | 258 | extern bool rmtree(const char *path, bool rmtopdir); 259 | 260 | /* 261 | * stat() is not guaranteed to set the st_size field on win32, so we 262 | * redefine it to our own implementation that is. 263 | * 264 | * We must pull in sys/stat.h here so the system header definition 265 | * goes in first, and we redefine that, and not the other way around. 266 | * 267 | * Some frontends don't need the size from stat, so if UNSAFE_STAT_OK 268 | * is defined we don't bother with this. 269 | */ 270 | #if defined(WIN32) && !defined(__CYGWIN__) && !defined(UNSAFE_STAT_OK) 271 | #include 272 | extern int pgwin32_safestat(const char *path, struct stat * buf); 273 | 274 | #define stat(a,b) pgwin32_safestat(a,b) 275 | #endif 276 | 277 | #if defined(WIN32) && !defined(__CYGWIN__) 278 | 279 | /* 280 | * open() and fopen() replacements to allow deletion of open files and 281 | * passing of other special options. 282 | */ 283 | #define O_DIRECT 0x80000000 284 | extern int pgwin32_open(const char *, int,...); 285 | extern FILE *pgwin32_fopen(const char *, const char *); 286 | 287 | #ifndef FRONTEND 288 | #define open(a,b,c) pgwin32_open(a,b,c) 289 | #define fopen(a,b) pgwin32_fopen(a,b) 290 | #endif 291 | 292 | /* 293 | * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want 294 | * to use our popen wrapper, rather than plain _popen, so override that. For 295 | * consistency, use our version of pclose, too. 296 | */ 297 | #ifdef popen 298 | #undef popen 299 | #endif 300 | #ifdef pclose 301 | #undef pclose 302 | #endif 303 | 304 | /* 305 | * system() and popen() replacements to enclose the command in an extra 306 | * pair of quotes. 307 | */ 308 | extern int pgwin32_system(const char *command); 309 | extern FILE *pgwin32_popen(const char *command, const char *type); 310 | 311 | #define system(a) pgwin32_system(a) 312 | #define popen(a,b) pgwin32_popen(a,b) 313 | #define pclose(a) _pclose(a) 314 | 315 | /* New versions of MingW have gettimeofday, old mingw and msvc don't */ 316 | #ifndef HAVE_GETTIMEOFDAY 317 | /* Last parameter not used */ 318 | extern int gettimeofday(struct timeval * tp, struct timezone * tzp); 319 | #endif 320 | #else /* !WIN32 */ 321 | 322 | /* 323 | * Win32 requires a special close for sockets and pipes, while on Unix 324 | * close() does them all. 325 | */ 326 | #define closesocket close 327 | #endif /* WIN32 */ 328 | 329 | /* 330 | * On Windows, setvbuf() does not support _IOLBF mode, and interprets that 331 | * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) 332 | * crashes outright if "parameter validation" is enabled. Therefore, in 333 | * places where we'd like to select line-buffered mode, we fall back to 334 | * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF 335 | * directly in order to implement this behavior. 336 | */ 337 | #ifndef WIN32 338 | #define PG_IOLBF _IOLBF 339 | #else 340 | #define PG_IOLBF _IONBF 341 | #endif 342 | 343 | /* 344 | * Default "extern" declarations or macro substitutes for library routines. 345 | * When necessary, these routines are provided by files in src/port/. 346 | */ 347 | #ifndef HAVE_CRYPT 348 | extern char *crypt(const char *key, const char *setting); 349 | #endif 350 | 351 | /* WIN32 handled in port/win32.h */ 352 | #ifndef WIN32 353 | #define pgoff_t off_t 354 | #ifdef __NetBSD__ 355 | extern int fseeko(FILE *stream, off_t offset, int whence); 356 | extern off_t ftello(FILE *stream); 357 | #endif 358 | #endif 359 | 360 | extern double pg_erand48(unsigned short xseed[3]); 361 | extern long pg_lrand48(void); 362 | extern void pg_srand48(long seed); 363 | 364 | #ifndef HAVE_FLS 365 | extern int fls(int mask); 366 | #endif 367 | 368 | #ifndef HAVE_FSEEKO 369 | #define fseeko(a, b, c) fseek(a, b, c) 370 | #define ftello(a) ftell(a) 371 | #endif 372 | 373 | #if !defined(HAVE_GETPEEREID) && !defined(WIN32) 374 | extern int getpeereid(int sock, uid_t *uid, gid_t *gid); 375 | #endif 376 | 377 | #ifndef HAVE_ISINF 378 | extern int isinf(double x); 379 | #endif 380 | 381 | #ifndef HAVE_MKDTEMP 382 | extern char *mkdtemp(char *path); 383 | #endif 384 | 385 | #ifndef HAVE_RINT 386 | extern double rint(double x); 387 | #endif 388 | 389 | #ifndef HAVE_INET_ATON 390 | #include 391 | #include 392 | extern int inet_aton(const char *cp, struct in_addr * addr); 393 | #endif 394 | 395 | #if !HAVE_DECL_STRLCAT 396 | extern size_t strlcat(char *dst, const char *src, size_t siz); 397 | #endif 398 | 399 | #if !HAVE_DECL_STRLCPY 400 | extern size_t strlcpy(char *dst, const char *src, size_t siz); 401 | #endif 402 | 403 | #if !defined(HAVE_RANDOM) && !defined(__BORLANDC__) 404 | extern long random(void); 405 | #endif 406 | 407 | #ifndef HAVE_UNSETENV 408 | extern void unsetenv(const char *name); 409 | #endif 410 | 411 | #ifndef HAVE_SRANDOM 412 | extern void srandom(unsigned int seed); 413 | #endif 414 | 415 | #ifndef HAVE_SSL_GET_CURRENT_COMPRESSION 416 | #define SSL_get_current_compression(x) 0 417 | #endif 418 | 419 | /* thread.h */ 420 | extern char *pqStrerror(int errnum, char *strerrbuf, size_t buflen); 421 | 422 | #ifndef WIN32 423 | extern int pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer, 424 | size_t buflen, struct passwd ** result); 425 | #endif 426 | 427 | extern int pqGethostbyname(const char *name, 428 | struct hostent * resultbuf, 429 | char *buffer, size_t buflen, 430 | struct hostent ** result, 431 | int *herrno); 432 | 433 | extern void pg_qsort(void *base, size_t nel, size_t elsize, 434 | int (*cmp) (const void *, const void *)); 435 | extern int pg_qsort_strcmp(const void *a, const void *b); 436 | 437 | #define qsort(a,b,c,d) pg_qsort(a,b,c,d) 438 | 439 | typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); 440 | 441 | extern void qsort_arg(void *base, size_t nel, size_t elsize, 442 | qsort_arg_comparator cmp, void *arg); 443 | 444 | /* port/chklocale.c */ 445 | extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); 446 | 447 | #if defined(WIN32) && !defined(FRONTEND) 448 | extern int pg_codepage_to_encoding(UINT cp); 449 | #endif 450 | 451 | /* port/inet_net_ntop.c */ 452 | extern char *inet_net_ntop(int af, const void *src, int bits, 453 | char *dst, size_t size); 454 | 455 | /* port/pgcheckdir.c */ 456 | extern int pg_check_dir(const char *dir); 457 | 458 | /* port/pgmkdirp.c */ 459 | extern int pg_mkdir_p(char *path, int omode); 460 | 461 | /* port/pqsignal.c */ 462 | typedef void (*pqsigfunc) (int signo); 463 | extern pqsigfunc pqsignal(int signo, pqsigfunc func); 464 | 465 | /* port/quotes.c */ 466 | extern char *escape_single_quotes_ascii(const char *src); 467 | 468 | /* port/wait_error.c */ 469 | extern char *wait_result_to_str(int exit_status); 470 | 471 | #endif /* PG_PORT_H */ 472 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/postgresql/internal/postgres_fe.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * postgres_fe.h 4 | * Primary include file for PostgreSQL client-side .c files 5 | * 6 | * This should be the first file included by PostgreSQL client libraries and 7 | * application programs --- but not by backend modules, which should include 8 | * postgres.h. 9 | * 10 | * 11 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 12 | * Portions Copyright (c) 1995, Regents of the University of California 13 | * 14 | * src/include/postgres_fe.h 15 | * 16 | *------------------------------------------------------------------------- 17 | */ 18 | #ifndef POSTGRES_FE_H 19 | #define POSTGRES_FE_H 20 | 21 | #ifndef FRONTEND 22 | #define FRONTEND 1 23 | #endif 24 | 25 | #include "c.h" 26 | 27 | #include "common/fe_memutils.h" 28 | 29 | #endif /* POSTGRES_FE_H */ 30 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/postgresql/internal/pqexpbuffer.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * pqexpbuffer.h 4 | * Declarations/definitions for "PQExpBuffer" functions. 5 | * 6 | * PQExpBuffer provides an indefinitely-extensible string data type. 7 | * It can be used to buffer either ordinary C strings (null-terminated text) 8 | * or arbitrary binary data. All storage is allocated with malloc(). 9 | * 10 | * This module is essentially the same as the backend's StringInfo data type, 11 | * but it is intended for use in frontend libpq and client applications. 12 | * Thus, it does not rely on palloc() nor elog(). 13 | * 14 | * It does rely on vsnprintf(); if configure finds that libc doesn't provide 15 | * a usable vsnprintf(), then a copy of our own implementation of it will 16 | * be linked into libpq. 17 | * 18 | * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group 19 | * Portions Copyright (c) 1994, Regents of the University of California 20 | * 21 | * src/interfaces/libpq/pqexpbuffer.h 22 | * 23 | *------------------------------------------------------------------------- 24 | */ 25 | #ifndef PQEXPBUFFER_H 26 | #define PQEXPBUFFER_H 27 | 28 | /*------------------------- 29 | * PQExpBufferData holds information about an extensible string. 30 | * data is the current buffer for the string (allocated with malloc). 31 | * len is the current string length. There is guaranteed to be 32 | * a terminating '\0' at data[len], although this is not very 33 | * useful when the string holds binary data rather than text. 34 | * maxlen is the allocated size in bytes of 'data', i.e. the maximum 35 | * string size (including the terminating '\0' char) that we can 36 | * currently store in 'data' without having to reallocate 37 | * more space. We must always have maxlen > len. 38 | * 39 | * An exception occurs if we failed to allocate enough memory for the string 40 | * buffer. In that case data points to a statically allocated empty string, 41 | * and len = maxlen = 0. 42 | *------------------------- 43 | */ 44 | typedef struct PQExpBufferData 45 | { 46 | char *data; 47 | size_t len; 48 | size_t maxlen; 49 | } PQExpBufferData; 50 | 51 | typedef PQExpBufferData *PQExpBuffer; 52 | 53 | /*------------------------ 54 | * Test for a broken (out of memory) PQExpBuffer. 55 | * When a buffer is "broken", all operations except resetting or deleting it 56 | * are no-ops. 57 | *------------------------ 58 | */ 59 | #define PQExpBufferBroken(str) \ 60 | ((str) == NULL || (str)->maxlen == 0) 61 | 62 | /*------------------------ 63 | * Same, but for use when using a static or local PQExpBufferData struct. 64 | * For that, a null-pointer test is useless and may draw compiler warnings. 65 | *------------------------ 66 | */ 67 | #define PQExpBufferDataBroken(buf) \ 68 | ((buf).maxlen == 0) 69 | 70 | /*------------------------ 71 | * Initial size of the data buffer in a PQExpBuffer. 72 | * NB: this must be large enough to hold error messages that might 73 | * be returned by PQrequestCancel(). 74 | *------------------------ 75 | */ 76 | #define INITIAL_EXPBUFFER_SIZE 256 77 | 78 | /*------------------------ 79 | * There are two ways to create a PQExpBuffer object initially: 80 | * 81 | * PQExpBuffer stringptr = createPQExpBuffer(); 82 | * Both the PQExpBufferData and the data buffer are malloc'd. 83 | * 84 | * PQExpBufferData string; 85 | * initPQExpBuffer(&string); 86 | * The data buffer is malloc'd but the PQExpBufferData is presupplied. 87 | * This is appropriate if the PQExpBufferData is a field of another 88 | * struct. 89 | *------------------------- 90 | */ 91 | 92 | /*------------------------ 93 | * createPQExpBuffer 94 | * Create an empty 'PQExpBufferData' & return a pointer to it. 95 | */ 96 | extern PQExpBuffer createPQExpBuffer(void); 97 | 98 | /*------------------------ 99 | * initPQExpBuffer 100 | * Initialize a PQExpBufferData struct (with previously undefined contents) 101 | * to describe an empty string. 102 | */ 103 | extern void initPQExpBuffer(PQExpBuffer str); 104 | 105 | /*------------------------ 106 | * To destroy a PQExpBuffer, use either: 107 | * 108 | * destroyPQExpBuffer(str); 109 | * free()s both the data buffer and the PQExpBufferData. 110 | * This is the inverse of createPQExpBuffer(). 111 | * 112 | * termPQExpBuffer(str) 113 | * free()s the data buffer but not the PQExpBufferData itself. 114 | * This is the inverse of initPQExpBuffer(). 115 | * 116 | * NOTE: some routines build up a string using PQExpBuffer, and then 117 | * release the PQExpBufferData but return the data string itself to their 118 | * caller. At that point the data string looks like a plain malloc'd 119 | * string. 120 | */ 121 | extern void destroyPQExpBuffer(PQExpBuffer str); 122 | extern void termPQExpBuffer(PQExpBuffer str); 123 | 124 | /*------------------------ 125 | * resetPQExpBuffer 126 | * Reset a PQExpBuffer to empty 127 | * 128 | * Note: if possible, a "broken" PQExpBuffer is returned to normal. 129 | */ 130 | extern void resetPQExpBuffer(PQExpBuffer str); 131 | 132 | /*------------------------ 133 | * enlargePQExpBuffer 134 | * Make sure there is enough space for 'needed' more bytes in the buffer 135 | * ('needed' does not include the terminating null). 136 | * 137 | * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case 138 | * the buffer is left in "broken" state.) 139 | */ 140 | extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed); 141 | 142 | /*------------------------ 143 | * printfPQExpBuffer 144 | * Format text data under the control of fmt (an sprintf-like format string) 145 | * and insert it into str. More space is allocated to str if necessary. 146 | * This is a convenience routine that does the same thing as 147 | * resetPQExpBuffer() followed by appendPQExpBuffer(). 148 | */ 149 | extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); 150 | 151 | /*------------------------ 152 | * appendPQExpBuffer 153 | * Format text data under the control of fmt (an sprintf-like format string) 154 | * and append it to whatever is already in str. More space is allocated 155 | * to str if necessary. This is sort of like a combination of sprintf and 156 | * strcat. 157 | */ 158 | extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); 159 | 160 | /*------------------------ 161 | * appendPQExpBufferStr 162 | * Append the given string to a PQExpBuffer, allocating more space 163 | * if necessary. 164 | */ 165 | extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); 166 | 167 | /*------------------------ 168 | * appendPQExpBufferChar 169 | * Append a single byte to str. 170 | * Like appendPQExpBuffer(str, "%c", ch) but much faster. 171 | */ 172 | extern void appendPQExpBufferChar(PQExpBuffer str, char ch); 173 | 174 | /*------------------------ 175 | * appendBinaryPQExpBuffer 176 | * Append arbitrary binary data to a PQExpBuffer, allocating more space 177 | * if necessary. 178 | */ 179 | extern void appendBinaryPQExpBuffer(PQExpBuffer str, 180 | const char *data, size_t datalen); 181 | 182 | #endif /* PQEXPBUFFER_H */ 183 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/sql3types.h: -------------------------------------------------------------------------------- 1 | #ifndef _ECPG_SQL3TYPES_H 2 | #define _ECPG_SQL3TYPES_H 3 | 4 | /* SQL3 dynamic type codes */ 5 | 6 | /* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */ 7 | 8 | enum 9 | { 10 | SQL3_CHARACTER = 1, 11 | SQL3_NUMERIC, 12 | SQL3_DECIMAL, 13 | SQL3_INTEGER, 14 | SQL3_SMALLINT, 15 | SQL3_FLOAT, 16 | SQL3_REAL, 17 | SQL3_DOUBLE_PRECISION, 18 | SQL3_DATE_TIME_TIMESTAMP, 19 | SQL3_INTERVAL, /* 10 */ 20 | SQL3_CHARACTER_VARYING = 12, 21 | SQL3_ENUMERATED, 22 | SQL3_BIT, 23 | SQL3_BIT_VARYING, 24 | SQL3_BOOLEAN, 25 | SQL3_abstract 26 | /* the rest is xLOB stuff */ 27 | }; 28 | 29 | /* chapter 13.1 table 3: Codes associated with datetime data types in Dynamic SQL */ 30 | 31 | enum 32 | { 33 | SQL3_DDT_DATE = 1, 34 | SQL3_DDT_TIME, 35 | SQL3_DDT_TIMESTAMP, 36 | SQL3_DDT_TIME_WITH_TIME_ZONE, 37 | SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE, 38 | 39 | SQL3_DDT_ILLEGAL /* not a datetime data type (not part of 40 | * standard) */ 41 | }; 42 | 43 | #endif /* !_ECPG_SQL3TYPES_H */ 44 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/sqlca.h: -------------------------------------------------------------------------------- 1 | #ifndef POSTGRES_SQLCA_H 2 | #define POSTGRES_SQLCA_H 3 | 4 | #ifndef PGDLLIMPORT 5 | #if defined(WIN32) || defined(__CYGWIN__) 6 | #define PGDLLIMPORT __declspec (dllimport) 7 | #else 8 | #define PGDLLIMPORT 9 | #endif /* __CYGWIN__ */ 10 | #endif /* PGDLLIMPORT */ 11 | 12 | #define SQLERRMC_LEN 150 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | 19 | struct sqlca_t 20 | { 21 | char sqlcaid[8]; 22 | long sqlabc; 23 | long sqlcode; 24 | struct 25 | { 26 | int sqlerrml; 27 | char sqlerrmc[SQLERRMC_LEN]; 28 | } sqlerrm; 29 | char sqlerrp[8]; 30 | long sqlerrd[6]; 31 | /* Element 0: empty */ 32 | /* 1: OID of processed tuple if applicable */ 33 | /* 2: number of rows processed */ 34 | /* after an INSERT, UPDATE or */ 35 | /* DELETE statement */ 36 | /* 3: empty */ 37 | /* 4: empty */ 38 | /* 5: empty */ 39 | char sqlwarn[8]; 40 | /* Element 0: set to 'W' if at least one other is 'W' */ 41 | /* 1: if 'W' at least one character string */ 42 | /* value was truncated when it was */ 43 | /* stored into a host variable. */ 44 | 45 | /* 46 | * 2: if 'W' a (hopefully) non-fatal notice occurred 47 | */ /* 3: empty */ 48 | /* 4: empty */ 49 | /* 5: empty */ 50 | /* 6: empty */ 51 | /* 7: empty */ 52 | 53 | char sqlstate[5]; 54 | }; 55 | 56 | struct sqlca_t *ECPGget_sqlca(void); 57 | 58 | #ifndef POSTGRES_ECPG_INTERNAL 59 | #define sqlca (*ECPGget_sqlca()) 60 | #endif 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/sqlda-compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pgsql/src/interfaces/ecpg/include/sqlda-infx-compat.h 3 | */ 4 | 5 | #ifndef ECPG_SQLDA_COMPAT_H 6 | #define ECPG_SQLDA_COMPAT_H 7 | 8 | struct sqlvar_compat 9 | { 10 | short sqltype; /* variable type */ 11 | int sqllen; /* length in bytes */ 12 | char *sqldata; /* pointer to data */ 13 | short *sqlind; /* pointer to indicator */ 14 | char *sqlname; /* variable name */ 15 | char *sqlformat; /* reserved for future use */ 16 | short sqlitype; /* ind variable type */ 17 | short sqlilen; /* ind length in bytes */ 18 | char *sqlidata; /* ind data pointer */ 19 | int sqlxid; /* extended id type */ 20 | char *sqltypename; /* extended type name */ 21 | short sqltypelen; /* length of extended type name */ 22 | short sqlownerlen; /* length of owner name */ 23 | short sqlsourcetype; /* source type for distinct of built-ins */ 24 | char *sqlownername; /* owner name */ 25 | int sqlsourceid; /* extended id of source type */ 26 | 27 | /* 28 | * sqlilongdata is new. It supports data that exceeds the 32k limit. 29 | * sqlilen and sqlidata are for backward compatibility and they have 30 | * maximum value of <32K. 31 | */ 32 | char *sqlilongdata; /* for data field beyond 32K */ 33 | int sqlflags; /* for internal use only */ 34 | void *sqlreserved; /* reserved for future use */ 35 | }; 36 | 37 | struct sqlda_compat 38 | { 39 | short sqld; 40 | struct sqlvar_compat *sqlvar; 41 | char desc_name[19]; /* descriptor name */ 42 | short desc_occ; /* size of sqlda structure */ 43 | struct sqlda_compat *desc_next; /* pointer to next sqlda struct */ 44 | void *reserved; /* reserved for future use */ 45 | }; 46 | 47 | #endif /* ECPG_SQLDA_COMPAT_H */ 48 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/sqlda-native.h: -------------------------------------------------------------------------------- 1 | /* 2 | * src/interfaces/ecpg/include/sqlda-native.h 3 | */ 4 | 5 | #ifndef ECPG_SQLDA_NATIVE_H 6 | #define ECPG_SQLDA_NATIVE_H 7 | 8 | /* 9 | * Maximum length for identifiers (e.g. table names, column names, 10 | * function names). Names actually are limited to one less byte than this, 11 | * because the length must include a trailing zero byte. 12 | * 13 | * This should be at least as much as NAMEDATALEN of the database the 14 | * applications run against. 15 | */ 16 | #define NAMEDATALEN 64 17 | 18 | struct sqlname 19 | { 20 | short length; 21 | char data[NAMEDATALEN]; 22 | }; 23 | 24 | struct sqlvar_struct 25 | { 26 | short sqltype; 27 | short sqllen; 28 | char *sqldata; 29 | short *sqlind; 30 | struct sqlname sqlname; 31 | }; 32 | 33 | struct sqlda_struct 34 | { 35 | char sqldaid[8]; 36 | long sqldabc; 37 | short sqln; 38 | short sqld; 39 | struct sqlda_struct *desc_next; 40 | struct sqlvar_struct sqlvar[1]; 41 | }; 42 | 43 | #endif /* ECPG_SQLDA_NATIVE_H */ 44 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/include/sqlda.h: -------------------------------------------------------------------------------- 1 | #ifndef ECPG_SQLDA_H 2 | #define ECPG_SQLDA_H 3 | 4 | #ifdef _ECPG_INFORMIX_H 5 | 6 | #include "sqlda-compat.h" 7 | typedef struct sqlvar_compat sqlvar_t; 8 | typedef struct sqlda_compat sqlda_t; 9 | 10 | #else 11 | 12 | #include "sqlda-native.h" 13 | typedef struct sqlvar_struct sqlvar_t; 14 | typedef struct sqlda_struct sqlda_t; 15 | 16 | #endif 17 | 18 | #endif /* ECPG_SQLDA_H */ 19 | -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/i386/libcrypto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/i386/libcrypto.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/i386/libpq.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/i386/libpq.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/i386/libssl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/i386/libssl.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/x64/libcrypto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/x64/libcrypto.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/x64/libpq.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/x64/libpq.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/lib/x64/libssl.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keittlab/rpg/eb7cc4206f32c1174cc65b0616bce74dd9dbf2f8/windows/libpq-9.5.2/lib/x64/libssl.a -------------------------------------------------------------------------------- /windows/libpq-9.5.2/readme.md: -------------------------------------------------------------------------------- 1 | Library was built from patched msys2 sources with: 2 | 3 | ```sh 4 | ../postgresql-9.5.2/configure \ 5 | --disable-thread-safety \ 6 | --with-openssl \ 7 | --enable-integer-datetimes \ 8 | --disable-nls \ 9 | --with-ldap \ 10 | --with-libxml \ 11 | --with-libxslt \ 12 | --with-python \ 13 | --without-perl \ 14 | --with-tcl 15 | ``` 16 | 17 | Note that `--disable-thread-safety` avoids depending on pthread, so the same build can be used with gcc-4-6.3 as gcc-4.9.3. 18 | 19 | Unfortunately the standard libpq Makefile does not generate static 20 | libraries. To build `libqp.a`, first run the usualy `make`. Then append file `src/interfaces/libpq/Makefile` with: 21 | 22 | ```make 23 | libpq.a: $(OBJS) 24 | ar rcs $@ $^ 25 | ``` 26 | 27 | And then run `make libpq.a`. To link use: 28 | 29 | ```make 30 | PKG_LIBS= -lpq -lssl -lcrypto -lwsock32 -lsecur32 -lws2_32 -lgdi32 -lcrypt32 -lwldap32 31 | ``` 32 | --------------------------------------------------------------------------------