diff --git a/.Rbuildignore b/.Rbuildignore index a6ebad59c..4a3ca304e 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -26,3 +26,4 @@ windows ^\.gitpod\.yml$ ^\.gitpod\.Dockerfile$ ^CMakeLists\.txt$ +^vscode-install\.r$ diff --git a/DESCRIPTION b/DESCRIPTION index 0d2e6a036..9f6c3907c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -26,7 +26,6 @@ Imports: hms (>= 1.0.0), lubridate, methods, - Rcpp (>= 1.0.7), withr Suggests: callr, @@ -36,8 +35,8 @@ Suggests: rmarkdown, testthat (>= 3.0.0) LinkingTo: - plogr (>= 0.2.0), - Rcpp + cpp11, + plogr (>= 0.2.0) VignetteBuilder: knitr Config/autostyle/scope: line_breaks @@ -47,15 +46,15 @@ Encoding: UTF-8 LazyLoad: true Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 -SystemRequirements: libpq >= 9.0: libpq-dev (deb) or postgresql-devel - (rpm) +SystemRequirements: + libpq >= 9.0: libpq-dev (deb) or postgresql-devel (rpm) Collate: 'PqDriver.R' 'PqConnection.R' 'PqResult.R' 'RPostgres-pkg.R' - 'RcppExports.R' 'Redshift.R' + 'cpp11.R' 'dbAppendTable_PqConnection.R' 'dbBegin_PqConnection.R' 'dbBind_PqResult.R' diff --git a/NAMESPACE b/NAMESPACE index 4f569ea19..b7be7a48b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -56,7 +56,6 @@ exportMethods(show) exportMethods(sqlData) import(DBI) import(methods) -importFrom(Rcpp,sourceCpp) importFrom(bit64,integer64) importFrom(blob,blob) importFrom(hms,hms) diff --git a/R/PqDriver.R b/R/PqDriver.R index 4afca6849..072994691 100644 --- a/R/PqDriver.R +++ b/R/PqDriver.R @@ -2,7 +2,6 @@ #' #' @export #' @useDynLib RPostgres, .registration = TRUE -#' @importFrom Rcpp sourceCpp #' @import methods DBI Postgres <- function() { new("PqDriver") diff --git a/R/RcppExports.R b/R/RcppExports.R deleted file mode 100644 index f17181be9..000000000 --- a/R/RcppExports.R +++ /dev/null @@ -1,107 +0,0 @@ -# Generated by using Rcpp::compileAttributes() -> do not edit by hand -# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 - -client_version <- function() { - .Call(`_RPostgres_client_version`) -} - -connection_create <- function(keys, values, check_interrupts) { - .Call(`_RPostgres_connection_create`, keys, values, check_interrupts) -} - -connection_valid <- function(con_) { - .Call(`_RPostgres_connection_valid`, con_) -} - -connection_release <- function(con_) { - invisible(.Call(`_RPostgres_connection_release`, con_)) -} - -connection_info <- function(con) { - .Call(`_RPostgres_connection_info`, con) -} - -connection_quote_string <- function(con, xs) { - .Call(`_RPostgres_connection_quote_string`, con, xs) -} - -connection_quote_identifier <- function(con, xs) { - .Call(`_RPostgres_connection_quote_identifier`, con, xs) -} - -connection_is_transacting <- function(con) { - .Call(`_RPostgres_connection_is_transacting`, con) -} - -connection_set_transacting <- function(con, transacting) { - invisible(.Call(`_RPostgres_connection_set_transacting`, con, transacting)) -} - -connection_copy_data <- function(con, sql, df) { - invisible(.Call(`_RPostgres_connection_copy_data`, con, sql, df)) -} - -connection_wait_for_notify <- function(con, timeout_secs) { - .Call(`_RPostgres_connection_wait_for_notify`, con, timeout_secs) -} - -connection_get_temp_schema <- function(con) { - .Call(`_RPostgres_connection_get_temp_schema`, con) -} - -connection_set_temp_schema <- function(con, temp_schema) { - invisible(.Call(`_RPostgres_connection_set_temp_schema`, con, temp_schema)) -} - -encode_vector <- function(x) { - .Call(`_RPostgres_encode_vector`, x) -} - -encode_data_frame <- function(x) { - .Call(`_RPostgres_encode_data_frame`, x) -} - -encrypt_password <- function(password, user) { - .Call(`_RPostgres_encrypt_password`, password, user) -} - -init_logging <- function(log_level) { - invisible(.Call(`_RPostgres_init_logging`, log_level)) -} - -result_create <- function(con, sql, immediate) { - .Call(`_RPostgres_result_create`, con, sql, immediate) -} - -result_release <- function(res) { - invisible(.Call(`_RPostgres_result_release`, res)) -} - -result_valid <- function(res_) { - .Call(`_RPostgres_result_valid`, res_) -} - -result_fetch <- function(res, n) { - .Call(`_RPostgres_result_fetch`, res, n) -} - -result_bind <- function(res, params) { - invisible(.Call(`_RPostgres_result_bind`, res, params)) -} - -result_has_completed <- function(res) { - .Call(`_RPostgres_result_has_completed`, res) -} - -result_rows_fetched <- function(res) { - .Call(`_RPostgres_result_rows_fetched`, res) -} - -result_rows_affected <- function(res) { - .Call(`_RPostgres_result_rows_affected`, res) -} - -result_column_info <- function(res) { - .Call(`_RPostgres_result_column_info`, res) -} - diff --git a/R/cpp11.R b/R/cpp11.R new file mode 100644 index 000000000..5c1d0cd2d --- /dev/null +++ b/R/cpp11.R @@ -0,0 +1,105 @@ +# Generated by cpp11: do not edit by hand + +client_version <- function() { + .Call(`_RPostgres_client_version`) +} + +connection_create <- function(keys, values, check_interrupts) { + .Call(`_RPostgres_connection_create`, keys, values, check_interrupts) +} + +connection_valid <- function(con_) { + .Call(`_RPostgres_connection_valid`, con_) +} + +connection_release <- function(con_) { + invisible(.Call(`_RPostgres_connection_release`, con_)) +} + +connection_info <- function(con) { + .Call(`_RPostgres_connection_info`, con) +} + +connection_quote_string <- function(con, xs) { + .Call(`_RPostgres_connection_quote_string`, con, xs) +} + +connection_quote_identifier <- function(con, xs) { + .Call(`_RPostgres_connection_quote_identifier`, con, xs) +} + +connection_is_transacting <- function(con) { + .Call(`_RPostgres_connection_is_transacting`, con) +} + +connection_set_transacting <- function(con, transacting) { + invisible(.Call(`_RPostgres_connection_set_transacting`, con, transacting)) +} + +connection_copy_data <- function(con, sql, df) { + invisible(.Call(`_RPostgres_connection_copy_data`, con, sql, df)) +} + +connection_wait_for_notify <- function(con, timeout_secs) { + .Call(`_RPostgres_connection_wait_for_notify`, con, timeout_secs) +} + +connection_get_temp_schema <- function(con) { + .Call(`_RPostgres_connection_get_temp_schema`, con) +} + +connection_set_temp_schema <- function(con, temp_schema) { + invisible(.Call(`_RPostgres_connection_set_temp_schema`, con, temp_schema)) +} + +encode_vector <- function(x) { + .Call(`_RPostgres_encode_vector`, x) +} + +encode_data_frame <- function(x) { + .Call(`_RPostgres_encode_data_frame`, x) +} + +encrypt_password <- function(password, user) { + .Call(`_RPostgres_encrypt_password`, password, user) +} + +init_logging <- function(log_level) { + invisible(.Call(`_RPostgres_init_logging`, log_level)) +} + +result_create <- function(con, sql, immediate) { + .Call(`_RPostgres_result_create`, con, sql, immediate) +} + +result_release <- function(res) { + invisible(.Call(`_RPostgres_result_release`, res)) +} + +result_valid <- function(res_) { + .Call(`_RPostgres_result_valid`, res_) +} + +result_fetch <- function(res, n) { + .Call(`_RPostgres_result_fetch`, res, n) +} + +result_bind <- function(res, params) { + invisible(.Call(`_RPostgres_result_bind`, res, params)) +} + +result_has_completed <- function(res) { + .Call(`_RPostgres_result_has_completed`, res) +} + +result_rows_fetched <- function(res) { + .Call(`_RPostgres_result_rows_fetched`, res) +} + +result_rows_affected <- function(res) { + .Call(`_RPostgres_result_rows_affected`, res) +} + +result_column_info <- function(res) { + .Call(`_RPostgres_result_column_info`, res) +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a3f16ef4..021d13f85 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,7 @@ add_library(RPostgres PqUtils.h RPostgres-init.c RPostgres_types.h - RcppExports.cpp + cpp11.cpp connection.cpp encode.cpp encode.h diff --git a/src/DbColumn.cpp b/src/DbColumn.cpp index 575163728..96c12da23 100644 --- a/src/DbColumn.cpp +++ b/src/DbColumn.cpp @@ -29,7 +29,7 @@ void DbColumn::finalize(const int n_) { n = n_; } -void DbColumn::warn_type_conflicts(const String& name) const { +void DbColumn::warn_type_conflicts(const cpp11::r_string& name) const { std::set my_data_types_seen = data_types_seen; DATA_TYPE dt = get_last_storage()->get_data_type(); @@ -52,11 +52,8 @@ void DbColumn::warn_type_conflicts(const String& name) const { if (my_data_types_seen.size() == 0) return; - String name_utf8 = name; - name_utf8.set_encoding(CE_UTF8); - std::stringstream ss; - ss << "Column `" << name_utf8.get_cstring() << "`: " << + ss << "Column `" << static_cast(name) << "`: " << "mixed type, first seen values of type " << format_data_type(dt) << ", " << "coercing other values of type "; @@ -67,7 +64,7 @@ void DbColumn::warn_type_conflicts(const String& name) const { ss << format_data_type(*it); } - warning(ss.str()); + cpp11::warning(ss.str()); } DbColumn::operator SEXP() const { diff --git a/src/DbColumn.h b/src/DbColumn.h index 6d4da7373..c9258600a 100644 --- a/src/DbColumn.h +++ b/src/DbColumn.h @@ -1,6 +1,7 @@ #ifndef DB_COLUMN_H #define DB_COLUMN_H +#include #include "DbColumnDataType.h" #include "DbColumnDataSourceFactory.h" @@ -25,7 +26,7 @@ class DbColumn { public: void set_col_value(); void finalize(const int n_); - void warn_type_conflicts(const String& name) const; + void warn_type_conflicts(const cpp11::r_string& name) const; operator SEXP() const; DATA_TYPE get_type() const; diff --git a/src/DbColumnStorage.cpp b/src/DbColumnStorage.cpp index 3ff8a0b2e..b5a91ce23 100644 --- a/src/DbColumnStorage.cpp +++ b/src/DbColumnStorage.cpp @@ -3,9 +3,6 @@ #include "DbColumnDataSource.h" #include "integer64.h" - -using namespace Rcpp; - DbColumnStorage::DbColumnStorage(DATA_TYPE dt_, const R_xlen_t capacity_, const int n_max_, const DbColumnDataSource& source_) : @@ -36,7 +33,7 @@ DATA_TYPE DbColumnStorage::get_data_type() const { SEXP DbColumnStorage::allocate(const R_xlen_t length, DATA_TYPE dt) { SEXPTYPE type = sexptype_from_datatype(dt); - RObject class_ = class_from_datatype(dt); + auto class_ = class_from_datatype(dt); SEXP ret = PROTECT(Rf_allocVector(type, length)); if (!Rf_isNull(class_)) Rf_setAttrib(ret, R_ClassSymbol, class_); @@ -148,7 +145,7 @@ void DbColumnStorage::fetch_value() { break; default: - stop("NYI"); + cpp11::stop("NYI"); } } @@ -180,21 +177,20 @@ SEXPTYPE DbColumnStorage::sexptype_from_datatype(DATA_TYPE dt) { return VECSXP; default: - stop("Unknown type %d", dt); + cpp11::stop("Unknown type %d", dt); } } -Rcpp::RObject DbColumnStorage::class_from_datatype(DATA_TYPE dt) { +cpp11::sexp DbColumnStorage::class_from_datatype(DATA_TYPE dt) { switch (dt) { case DT_INT64: - return CharacterVector::create("integer64"); - + return cpp11::as_sexp("integer64"); case DT_DATE: - return CharacterVector::create("Date"); + return cpp11::as_sexp("Date"); case DT_DATETIME: case DT_DATETIMETZ: - return CharacterVector::create("POSIXct", "POSIXt"); + return cpp11::as_sexp({"POSIXct", "POSIXt"}); default: return R_NilValue; @@ -210,7 +206,7 @@ SEXP DbColumnStorage::set_attribs_from_datatype(SEXP x, DATA_TYPE dt) { return new_hms(x); case DT_DATETIME: { - Rcpp::RObject ro = Rcpp::RObject(x); + cpp11::sexp ro = x; ro.attr("tzone") = "UTC"; return ro; } @@ -220,12 +216,12 @@ SEXP DbColumnStorage::set_attribs_from_datatype(SEXP x, DATA_TYPE dt) { } SEXP DbColumnStorage::new_blob(SEXP x) { - static Function new_blob = Function("new_blob", Rcpp::Environment::namespace_env("blob")); + static cpp11::function new_blob = cpp11::package("blob")["new_blob"]; return new_blob(x); } SEXP DbColumnStorage::new_hms(SEXP x) { - static Function new_hms = Function("new_hms", Rcpp::Environment::namespace_env("hms")); + static cpp11::function new_hms = cpp11::package("hms")["new_hms"]; return new_hms(x); } @@ -260,7 +256,7 @@ void DbColumnStorage::fill_default_value(SEXP data, DATA_TYPE dt, R_xlen_t i) { break; case DT_UNKNOWN: - stop("Not setting value for unknown data type"); + cpp11::stop("Not setting value for unknown data type"); } } @@ -333,7 +329,7 @@ void DbColumnStorage::copy_value(SEXP x, DATA_TYPE dt, const int tgt, const int break; default: - stop("NYI: default"); + cpp11::stop("NYI: default"); } } } diff --git a/src/DbColumnStorage.h b/src/DbColumnStorage.h index f386c72c0..518266176 100644 --- a/src/DbColumnStorage.h +++ b/src/DbColumnStorage.h @@ -8,7 +8,7 @@ class DbColumnDataSource; class DbColumnStorage { - Rcpp::RObject data; + cpp11::sexp data; int i; DATA_TYPE dt; const int n_max; @@ -42,7 +42,7 @@ class DbColumnStorage { void fetch_value(); // allocate() - static Rcpp::RObject class_from_datatype(DATA_TYPE dt); + static cpp11::sexp class_from_datatype(DATA_TYPE dt); static SEXP set_attribs_from_datatype(SEXP x, DATA_TYPE dt); static SEXP new_blob(SEXP x); static SEXP new_hms(SEXP x); diff --git a/src/DbConnection.cpp b/src/DbConnection.cpp index 7f8c0aa96..696ba002b 100644 --- a/src/DbConnection.cpp +++ b/src/DbConnection.cpp @@ -12,7 +12,7 @@ DbConnection::DbConnection(std::vector keys, std::vector c_keys(n + 1), c_values(n + 1); @@ -29,7 +29,7 @@ DbConnection::DbConnection(std::vector keys, std::vector(-1)); - SEXP escaped = Rf_mkCharCE(pq_escaped, CE_UTF8); + const auto str = static_cast(x); + char* pq_escaped = PQescapeLiteral(pConn_, str.c_str(), static_cast(-1)); + auto escaped = Rf_mkCharCE(pq_escaped, CE_UTF8); PQfreemem(pq_escaped); return escaped; } -SEXP DbConnection::quote_identifier(const String& x) { +SEXP DbConnection::quote_identifier(const cpp11::r_string& x) { // Returns a single CHRSXP check_connection(); - char* pq_escaped = PQescapeIdentifier(pConn_, x.get_cstring(), static_cast(-1)); - SEXP escaped = Rf_mkCharCE(pq_escaped, CE_UTF8); + const auto str = static_cast(x); + char* pq_escaped = PQescapeIdentifier(pConn_, str.c_str(), static_cast(-1)); + auto escaped = Rf_mkCharCE(pq_escaped, CE_UTF8); PQfreemem(pq_escaped); return escaped; } SEXP DbConnection::get_null_string() { - static RObject null = Rf_mkCharCE("NULL::text", CE_UTF8); + static cpp11::sexp null = Rf_mkCharCE("NULL::text", CE_UTF8); return null; } @@ -252,11 +255,11 @@ void DbConnection::set_transacting(bool transacting) { transacting_ = transacting; } -CharacterVector DbConnection::get_temp_schema() const { +cpp11::strings DbConnection::get_temp_schema() const { return temp_schema_; } -void DbConnection::set_temp_schema(CharacterVector temp_schema) { +void DbConnection::set_temp_schema(cpp11::strings temp_schema) { temp_schema_ = temp_schema; } @@ -265,57 +268,61 @@ void DbConnection::conn_stop(const char* msg) { } void DbConnection::conn_stop(PGconn* conn, const char* msg) { - stop("%s: %s", msg, PQerrorMessage(conn)); + cpp11::stop(std::string(msg) + " : " + PQerrorMessage(conn)); } void DbConnection::cleanup_query() { + if (!pConn_) { + return; + } + if (pCurrentResult_ != NULL && !(pCurrentResult_->complete())) { cancel_query(); } finish_query(pConn_); } -List DbConnection::wait_for_notify(int timeout_secs) { +cpp11::list DbConnection::wait_for_notify(int timeout_secs) { + using namespace cpp11::literals; PGnotify *notify; - List out; + cpp11::writable::list out; int socket = -1; fd_set input; while (TRUE) { // See if there's a notification waiting, if so return it if (!PQconsumeInput(pConn_)) { - stop("Failed to consume input from the server"); + cpp11::stop("Failed to consume input from the server"); } if ((notify = PQnotifies(pConn_)) != NULL) { - out = Rcpp::List::create( - _["channel"] = CharacterVector::create(notify->relname), - _["pid"] = IntegerVector::create(notify->be_pid), - _["payload"] = CharacterVector::create(notify->extra) - ); + out = cpp11::list({ + "channel"_nm = cpp11::writable::strings({notify->relname}), + "pid"_nm = cpp11::writable::integers({notify->be_pid}), + "payload"_nm = cpp11::writable::strings({notify->extra}) + }); PQfreemem(notify); return out; } if (socket != -1) { // Socket open, so already been round once, give up. - return R_NilValue; + return cpp11::list(); } // Open DB socket and wait for new data for at most (timeout_secs) seconds if ((socket = PQsocket(pConn_)) < 0) { - stop("Failed to get connection socket"); + cpp11::stop("Failed to get connection socket"); } FD_ZERO(&input); FD_SET(socket, &input); timeval timeout = {0, 0}; timeout.tv_sec = timeout_secs; if (select(socket + 1, &input, NULL, NULL, &timeout) < 0) { - stop("select() on the connection failed"); + cpp11::stop("select() on the connection failed"); } } } void DbConnection::process_notice(void* /*This*/, const char* message) { - Rcpp::CharacterVector msg(message); - Rcpp::message(msg); + cpp11::message(message); } diff --git a/src/DbConnection.h b/src/DbConnection.h index f5768155a..a0a704818 100644 --- a/src/DbConnection.h +++ b/src/DbConnection.h @@ -17,7 +17,7 @@ class DbConnection : boost::noncopyable { const DbResult* pCurrentResult_; bool transacting_; bool check_interrupts_; - CharacterVector temp_schema_; + cpp11::strings temp_schema_; public: DbConnection(std::vector keys, std::vector values, @@ -34,29 +34,29 @@ class DbConnection : boost::noncopyable { bool is_current_result(const DbResult* pResult); bool has_query(); - void copy_data(std::string sql, List df); + void copy_data(std::string sql, cpp11::list df); void check_connection(); - List info(); + cpp11::list info(); bool is_check_interrupts() const; - SEXP quote_string(const String& x); - SEXP quote_identifier(const String& x); + SEXP quote_string(const cpp11::r_string& x); + SEXP quote_identifier(const cpp11::r_string& x); static SEXP get_null_string(); bool is_transacting() const; void set_transacting(bool transacting); - CharacterVector get_temp_schema() const; - void set_temp_schema(CharacterVector temp_schema); + cpp11::strings get_temp_schema() const; + void set_temp_schema(cpp11::strings temp_schema); void conn_stop(const char* msg); static void conn_stop(PGconn* conn, const char* msg); void cleanup_query(); static void finish_query(PGconn* pConn); - List wait_for_notify(int timeout_secs); + cpp11::list wait_for_notify(int timeout_secs); void cancel_query(); diff --git a/src/DbDataFrame.cpp b/src/DbDataFrame.cpp index 7c1e83b48..e2294a885 100644 --- a/src/DbDataFrame.cpp +++ b/src/DbDataFrame.cpp @@ -33,18 +33,18 @@ bool DbDataFrame::advance() { ++i; if (i % 1024 == 0) - checkUserInterrupt(); + cpp11::check_user_interrupt(); return (n_max < 0 || i < n_max); } -List DbDataFrame::get_data() { +cpp11::list DbDataFrame::get_data() { // Throws away new data types std::vector types_; return get_data(types_); } -List DbDataFrame::get_data(std::vector& types_) { +cpp11::list DbDataFrame::get_data(std::vector& types_) { // Trim back to what we actually used finalize_cols(); @@ -53,14 +53,21 @@ List DbDataFrame::get_data(std::vector& types_) { boost::for_each(data, names, boost::bind(&DbColumn::warn_type_conflicts, _1, _2)); - List out(data.begin(), data.end()); - StringVector names_utf8 = wrap(names); + cpp11::writable::list out(data.size()); + auto it = data.begin(); + for (int i = 0; i < data.size(); i++) { + out[i] = *it; + it++; + } + auto names_utf8 = static_cast(cpp11::as_sexp(names)); for (int j = 0; j < names_utf8.size(); ++j) { - names_utf8[j] = Rf_mkCharCE(names_utf8[j], CE_UTF8); + const auto name = static_cast(names_utf8[j]); + const auto name_str = static_cast(name); + names_utf8[j] = Rf_mkCharCE(name_str.c_str(), CE_UTF8); } out.attr("names") = names_utf8; out.attr("class") = "data.frame"; - out.attr("row.names") = IntegerVector::create(NA_INTEGER, -i); + out.attr("row.names") = cpp11::integers({NA_INTEGER, -i}); return out; } diff --git a/src/DbDataFrame.h b/src/DbDataFrame.h index 0c29997c2..214c92f34 100644 --- a/src/DbDataFrame.h +++ b/src/DbDataFrame.h @@ -26,8 +26,8 @@ class DbDataFrame { void set_col_values(); bool advance(); - List get_data(); - List get_data(std::vector& types); + cpp11::list get_data(); + cpp11::list get_data(std::vector& types); size_t get_ncols() const; private: diff --git a/src/DbResult.cpp b/src/DbResult.cpp index b6a376fe5..25f70e18e 100644 --- a/src/DbResult.cpp +++ b/src/DbResult.cpp @@ -44,22 +44,22 @@ int DbResult::n_rows_affected() { return impl->n_rows_affected(); } -void DbResult::bind(const List& params) { +void DbResult::bind(const cpp11::list& params) { validate_params(params); impl->bind(params); } -List DbResult::fetch(const int n_max) { +cpp11::list DbResult::fetch(const int n_max) { if (!is_active()) - stop("Inactive result set"); + cpp11::stop("Inactive result set"); return impl->fetch(n_max); } -List DbResult::get_column_info() { - List out = impl->get_column_info(); +cpp11::list DbResult::get_column_info() { + cpp11::writable::list out = impl->get_column_info(); - out.attr("row.names") = IntegerVector::create(NA_INTEGER, -Rf_length(out[0])); + out.attr("row.names") = cpp11::integers({NA_INTEGER, -Rf_length(out[0])}); out.attr("class") = "data.frame"; return out; @@ -72,7 +72,7 @@ void DbResult::close() { // Privates /////////////////////////////////////////////////////////////////// -void DbResult::validate_params(const List& params) const { +void DbResult::validate_params(const cpp11::list& params) const { if (params.size() != 0) { SEXP first_col = params[0]; int n = Rf_length(first_col); @@ -80,7 +80,7 @@ void DbResult::validate_params(const List& params) const { for (int j = 1; j < params.size(); ++j) { SEXP col = params[j]; if (Rf_length(col) != n) - stop("Parameter %i does not have length %d.", j + 1, n); + cpp11::stop("Parameter %i does not have length %d.", j + 1, n); } } } diff --git a/src/DbResult.h b/src/DbResult.h index f6d637173..ae9b93735 100644 --- a/src/DbResult.h +++ b/src/DbResult.h @@ -33,13 +33,13 @@ class DbResult : boost::noncopyable { int n_rows_fetched(); int n_rows_affected(); - void bind(const List& params); - List fetch(int n_max = -1); + void bind(const cpp11::list& params); + cpp11::list fetch(int n_max = -1); - List get_column_info(); + cpp11::list get_column_info(); private: - void validate_params(const List& params) const; + void validate_params(const cpp11::list& params) const; }; #endif // __RDBI_DB_RESULT__ diff --git a/src/Makevars.win b/src/Makevars.win index 5af9c71c3..ab0719ace 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -3,7 +3,6 @@ RWINLIB = ../windows/libpq-$(VERSION) PKG_CPPFLAGS = -I$(RWINLIB)/include -Ivendor -DSTRICT_R_HEADERS -DRCPP_DEFAULT_INCLUDE_CALL=false -DRCPP_USING_UTF8_ERROR_STRING -DBOOST_NO_AUTO_PTR PKG_LIBS = -L$(RWINLIB)/lib${R_ARCH}${CRT} \ -lpq -lpgport -lpgcommon -lssl -lcrypto -lwsock32 -lsecur32 -lws2_32 -lgdi32 -lcrypt32 -lwldap32 -CXX_STD = CXX11 $(SHLIB): diff --git a/src/PqResultImpl.cpp b/src/PqResultImpl.cpp index 0c6ff7870..3b6f55ade 100644 --- a/src/PqResultImpl.cpp +++ b/src/PqResultImpl.cpp @@ -77,10 +77,10 @@ void PqResultImpl::_cache::set(PGresult* spec) if (initialized_ || new_names.size() == 0) { LOG_VERBOSE; if (names_.size() != 0 && new_names.size() != 0 && names_ != new_names) { - stop("Multiple queries must use the same column names."); + cpp11::stop("Multiple queries must use the same column names."); } if (oids_.size() != 0 && new_oids.size() != 0 && oids_ != new_oids) { - stop("Multiple queries must use the same column types."); + cpp11::stop("Multiple queries must use the same column types."); } return; } @@ -271,25 +271,25 @@ int PqResultImpl::n_rows_affected() { return rows_affected_; } -void PqResultImpl::bind(const List& params) { +void PqResultImpl::bind(const cpp11::list& params) { LOG_DEBUG << params.size(); if (immediate_ && params.size() > 0) { - stop("Immediate query cannot be parameterized."); + cpp11::stop("Immediate query cannot be parameterized."); } if (params.size() != cache.nparams_) { - stop("Query requires %i params; %i supplied.", + cpp11::stop("Query requires %i params; %i supplied.", cache.nparams_, params.size()); } if (params.size() == 0 && ready_) { - stop("Query does not require parameters."); + cpp11::stop("Query does not require parameters."); } set_params(params); - if (params.length() > 0) { + if (params.size() > 0) { SEXP first_col = params[0]; groups_ = Rf_length(first_col); } @@ -304,14 +304,14 @@ void PqResultImpl::bind(const List& params) { after_bind(has_params); } -List PqResultImpl::fetch(const int n_max) { +cpp11::list PqResultImpl::fetch(const int n_max) { LOG_DEBUG << n_max; if (!ready_) - stop("Query needs to be bound before fetching"); + cpp11::stop("Query needs to be bound before fetching"); int n = 0; - List out; + cpp11::list out; if (n_max != 0) out = fetch_rows(n_max, n); @@ -321,22 +321,26 @@ List PqResultImpl::fetch(const int n_max) { return out; } -List PqResultImpl::get_column_info() { +cpp11::list PqResultImpl::get_column_info() { + using namespace cpp11::literals; peek_first_row(); - CharacterVector names(cache.names_.begin(), cache.names_.end()); + cpp11::writable::strings names(cache.names_.size()); + auto it = cache.names_.begin(); + for (int i = 0; i < names.size(); i++, it++) + names[i] = *it; - CharacterVector types(cache.ncols_); + cpp11::writable::strings types(cache.ncols_); for (size_t i = 0; i < cache.ncols_; i++) { types[i] = Rf_type2char(DbColumnStorage::sexptype_from_datatype(cache.types_[i])); } - return Rcpp::List::create( - _["name"] = names, - _["type"] = types, - _[".oid"] = cache.oids_, - _[".known"] = cache.known_ - ); + return cpp11::list({ + "name"_nm = names, + "type"_nm = types, + ".oid"_nm = cache.oids_, + ".known"_nm = cache.known_ + }); } @@ -348,7 +352,7 @@ List PqResultImpl::get_column_info() { // Privates //////////////////////////////////////////////////////////////////// -void PqResultImpl::set_params(const List& params) { +void PqResultImpl::set_params(const cpp11::list& params) { params_ = params; } @@ -370,7 +374,7 @@ bool PqResultImpl::bind_row() { std::vector lengths(cache.nparams_); for (int i = 0; i < cache.nparams_; ++i) { if (TYPEOF(params_[i]) == VECSXP) { - List param(params_[i]); + cpp11::list param(params_[i]); if (!Rf_isNull(param[group_])) { Rbyte* param_value = RAW(param[group_]); c_params[i] = reinterpret_cast(param_value); @@ -379,7 +383,7 @@ bool PqResultImpl::bind_row() { } } else { - CharacterVector param(params_[i]); + cpp11::strings param(params_[i]); if (param[group_] != NA_STRING) { c_params[i] = CHAR(param[group_]); } @@ -420,7 +424,7 @@ void PqResultImpl::after_bind(bool params_have_rows) { step(); } -List PqResultImpl::fetch_rows(const int n_max, int& n) { +cpp11::list PqResultImpl::fetch_rows(const int n_max, int& n) { LOG_DEBUG << n_max << "/" << n; n = (n_max < 0) ? 100 : n_max; @@ -428,7 +432,7 @@ List PqResultImpl::fetch_rows(const int n_max, int& n) { PqDataFrame data(this, cache.names_, n_max, cache.types_); if (complete_ && data.get_ncols() == 0) { - warning("Don't need to call dbFetch() for statements, only for queries"); + cpp11::warning(std::string("Don't need to call dbFetch() for statements, only for queries")); } while (!complete_) { @@ -442,7 +446,7 @@ List PqResultImpl::fetch_rows(const int n_max, int& n) { } LOG_VERBOSE << nrows_; - List ret = data.get_data(); + cpp11::writable::list ret = data.get_data(); add_oids(ret); return ret; } @@ -477,7 +481,7 @@ bool PqResultImpl::step_run() { if (!proceed) { pConnPtr_->cancel_query(); complete_ = TRUE; - stop("Interrupted."); + cpp11::stop("Interrupted."); } need_cache_reset = true; @@ -542,14 +546,14 @@ bool PqResultImpl::step_done() { return more_params; } -List PqResultImpl::peek_first_row() { +cpp11::list PqResultImpl::peek_first_row() { PqDataFrame data(this, cache.names_, 1, cache.types_); if (!complete_) data.set_col_values(); // Not calling data.advance(), remains a zero-row data frame - List ret = data.get_data(); + cpp11::writable::list ret = data.get_data(); add_oids(ret); return ret; } @@ -559,14 +563,14 @@ void PqResultImpl::conn_stop(const char* msg) const { } void PqResultImpl::bind() { - bind(List()); + bind(cpp11::list()); } -void PqResultImpl::add_oids(List& data) const { - data.attr("oids") = cache.oids_; - data.attr("known") = cache.known_; +void PqResultImpl::add_oids(cpp11::writable::list& data) const { + data.attr("oids") = cpp11::as_sexp(cache.oids_); + data.attr("known") = cpp11::as_sexp(cache.known_); - LogicalVector is_without_tz = LogicalVector(cache.types_.size()); + auto is_without_tz = cpp11::writable::logicals(cache.types_.size()); for (size_t i = 0; i < cache.types_.size(); ++i) { bool set = (cache.types_[i] == DT_DATETIME); LOG_VERBOSE << "is_without_tz[" << i << "]: " << set; @@ -590,7 +594,7 @@ bool PqResultImpl::wait_for_data() { // update db connection state using data available on the socket if (!PQconsumeInput(pConn_)) { - stop("Failed to consume input from the server"); + cpp11::stop("Failed to consume input from the server"); } // check if PQgetResult will block before waiting @@ -604,7 +608,7 @@ bool PqResultImpl::wait_for_data() { socket = PQsocket(pConn_); if (socket < 0) { - stop("Failed to get connection socket"); + cpp11::stop("Failed to get connection socket"); } do { @@ -623,7 +627,7 @@ bool PqResultImpl::wait_for_data() { // timeout reached - check user interrupt try { // FIXME: Do we even need this? - checkUserInterrupt(); + cpp11::check_user_interrupt(); } catch (...) { LOG_DEBUG; @@ -636,13 +640,13 @@ bool PqResultImpl::wait_for_data() { return false; } else { LOG_DEBUG; - stop("select() failed with error code %d", SOCKERR); + cpp11::stop("select() failed with error code %d", SOCKERR); } } // update db connection state using data available on the socket if (!PQconsumeInput(pConn_)) { - stop("Failed to consume input from the server"); + cpp11::stop("Failed to consume input from the server"); } } while (PQisBusy(pConn_)); // check if PQgetResult will still block diff --git a/src/PqResultImpl.h b/src/PqResultImpl.h index e6ef9f2c0..aa7a79615 100644 --- a/src/PqResultImpl.h +++ b/src/PqResultImpl.h @@ -49,7 +49,7 @@ class PqResultImpl : boost::noncopyable, public PqResultSource { bool data_ready_; int nrows_; int rows_affected_; - List params_; + cpp11::list params_; int group_, groups_; PGresult* pRes_; @@ -66,28 +66,28 @@ class PqResultImpl : boost::noncopyable, public PqResultSource { bool complete() const; int n_rows_fetched(); int n_rows_affected(); - void bind(const List& params); - List fetch(const int n_max); + void bind(const cpp11::list& params); + cpp11::list fetch(const int n_max); - List get_column_info(); + cpp11::list get_column_info(); private: - void set_params(const List& params); + void set_params(const cpp11::list& params); bool bind_row(); void after_bind(bool params_have_rows); - List fetch_rows(int n_max, int& n); + cpp11::list fetch_rows(int n_max, int& n); void step(); bool step_run(); bool step_done(); - List peek_first_row(); + cpp11::list peek_first_row(); private: void conn_stop(const char* msg) const; void bind(); - void add_oids(List& data) const; + void add_oids(cpp11::writable::list& data) const; public: // PqResultSource diff --git a/src/RPostgres_types.h b/src/RPostgres_types.h index 57c4af795..8f67f4595 100644 --- a/src/RPostgres_types.h +++ b/src/RPostgres_types.h @@ -6,13 +6,23 @@ #include "DbConnection.h" #include "DbResult.h" -namespace Rcpp { +namespace cpp11 { -template<> -DbConnection* as(SEXP x); +template +enable_if_t, DbConnection*>::value, decay_t> as_cpp(SEXP from) { + DbConnectionPtr* connection = (DbConnectionPtr*)(R_ExternalPtrAddr(from)); + if (!connection) + stop("Invalid connection"); + return connection->get(); +} -template<> -DbResult* as(SEXP x); +template +enable_if_t, DbResult*>::value, decay_t> as_cpp(SEXP from) { + DbResult* result = (DbResult*)(R_ExternalPtrAddr(from)); + if (!result) + stop("Invalid result set"); + return result; +} } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp deleted file mode 100644 index 01dc884db..000000000 --- a/src/RcppExports.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// Generated by using Rcpp::compileAttributes() -> do not edit by hand -// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 - -#include "RPostgres_types.h" -#include - -using namespace Rcpp; - -#ifdef RCPP_USE_GLOBAL_ROSTREAM -Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); -Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); -#endif - -// client_version -int client_version(); -RcppExport SEXP _RPostgres_client_version() { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - rcpp_result_gen = Rcpp::wrap(client_version()); - return rcpp_result_gen; -END_RCPP -} -// connection_create -XPtr connection_create(std::vector keys, std::vector values, bool check_interrupts); -RcppExport SEXP _RPostgres_connection_create(SEXP keysSEXP, SEXP valuesSEXP, SEXP check_interruptsSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< std::vector >::type keys(keysSEXP); - Rcpp::traits::input_parameter< std::vector >::type values(valuesSEXP); - Rcpp::traits::input_parameter< bool >::type check_interrupts(check_interruptsSEXP); - rcpp_result_gen = Rcpp::wrap(connection_create(keys, values, check_interrupts)); - return rcpp_result_gen; -END_RCPP -} -// connection_valid -bool connection_valid(XPtr con_); -RcppExport SEXP _RPostgres_connection_valid(SEXP con_SEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< XPtr >::type con_(con_SEXP); - rcpp_result_gen = Rcpp::wrap(connection_valid(con_)); - return rcpp_result_gen; -END_RCPP -} -// connection_release -void connection_release(XPtr con_); -RcppExport SEXP _RPostgres_connection_release(SEXP con_SEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< XPtr >::type con_(con_SEXP); - connection_release(con_); - return R_NilValue; -END_RCPP -} -// connection_info -List connection_info(DbConnection* con); -RcppExport SEXP _RPostgres_connection_info(SEXP conSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - rcpp_result_gen = Rcpp::wrap(connection_info(con)); - return rcpp_result_gen; -END_RCPP -} -// connection_quote_string -CharacterVector connection_quote_string(DbConnection* con, CharacterVector xs); -RcppExport SEXP _RPostgres_connection_quote_string(SEXP conSEXP, SEXP xsSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type xs(xsSEXP); - rcpp_result_gen = Rcpp::wrap(connection_quote_string(con, xs)); - return rcpp_result_gen; -END_RCPP -} -// connection_quote_identifier -CharacterVector connection_quote_identifier(DbConnection* con, CharacterVector xs); -RcppExport SEXP _RPostgres_connection_quote_identifier(SEXP conSEXP, SEXP xsSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type xs(xsSEXP); - rcpp_result_gen = Rcpp::wrap(connection_quote_identifier(con, xs)); - return rcpp_result_gen; -END_RCPP -} -// connection_is_transacting -bool connection_is_transacting(DbConnection* con); -RcppExport SEXP _RPostgres_connection_is_transacting(SEXP conSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - rcpp_result_gen = Rcpp::wrap(connection_is_transacting(con)); - return rcpp_result_gen; -END_RCPP -} -// connection_set_transacting -void connection_set_transacting(DbConnection* con, bool transacting); -RcppExport SEXP _RPostgres_connection_set_transacting(SEXP conSEXP, SEXP transactingSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< bool >::type transacting(transactingSEXP); - connection_set_transacting(con, transacting); - return R_NilValue; -END_RCPP -} -// connection_copy_data -void connection_copy_data(DbConnection* con, std::string sql, List df); -RcppExport SEXP _RPostgres_connection_copy_data(SEXP conSEXP, SEXP sqlSEXP, SEXP dfSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< std::string >::type sql(sqlSEXP); - Rcpp::traits::input_parameter< List >::type df(dfSEXP); - connection_copy_data(con, sql, df); - return R_NilValue; -END_RCPP -} -// connection_wait_for_notify -List connection_wait_for_notify(DbConnection* con, int timeout_secs); -RcppExport SEXP _RPostgres_connection_wait_for_notify(SEXP conSEXP, SEXP timeout_secsSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< int >::type timeout_secs(timeout_secsSEXP); - rcpp_result_gen = Rcpp::wrap(connection_wait_for_notify(con, timeout_secs)); - return rcpp_result_gen; -END_RCPP -} -// connection_get_temp_schema -CharacterVector connection_get_temp_schema(DbConnection* con); -RcppExport SEXP _RPostgres_connection_get_temp_schema(SEXP conSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - rcpp_result_gen = Rcpp::wrap(connection_get_temp_schema(con)); - return rcpp_result_gen; -END_RCPP -} -// connection_set_temp_schema -void connection_set_temp_schema(DbConnection* con, CharacterVector temp_schema); -RcppExport SEXP _RPostgres_connection_set_temp_schema(SEXP conSEXP, SEXP temp_schemaSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbConnection* >::type con(conSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type temp_schema(temp_schemaSEXP); - connection_set_temp_schema(con, temp_schema); - return R_NilValue; -END_RCPP -} -// encode_vector -std::string encode_vector(RObject x); -RcppExport SEXP _RPostgres_encode_vector(SEXP xSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< RObject >::type x(xSEXP); - rcpp_result_gen = Rcpp::wrap(encode_vector(x)); - return rcpp_result_gen; -END_RCPP -} -// encode_data_frame -std::string encode_data_frame(List x); -RcppExport SEXP _RPostgres_encode_data_frame(SEXP xSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< List >::type x(xSEXP); - rcpp_result_gen = Rcpp::wrap(encode_data_frame(x)); - return rcpp_result_gen; -END_RCPP -} -// encrypt_password -String encrypt_password(String password, String user); -RcppExport SEXP _RPostgres_encrypt_password(SEXP passwordSEXP, SEXP userSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< String >::type password(passwordSEXP); - Rcpp::traits::input_parameter< String >::type user(userSEXP); - rcpp_result_gen = Rcpp::wrap(encrypt_password(password, user)); - return rcpp_result_gen; -END_RCPP -} -// init_logging -void init_logging(const std::string& log_level); -RcppExport SEXP _RPostgres_init_logging(SEXP log_levelSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< const std::string& >::type log_level(log_levelSEXP); - init_logging(log_level); - return R_NilValue; -END_RCPP -} -// result_create -XPtr result_create(XPtr con, std::string sql, bool immediate); -RcppExport SEXP _RPostgres_result_create(SEXP conSEXP, SEXP sqlSEXP, SEXP immediateSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< XPtr >::type con(conSEXP); - Rcpp::traits::input_parameter< std::string >::type sql(sqlSEXP); - Rcpp::traits::input_parameter< bool >::type immediate(immediateSEXP); - rcpp_result_gen = Rcpp::wrap(result_create(con, sql, immediate)); - return rcpp_result_gen; -END_RCPP -} -// result_release -void result_release(XPtr res); -RcppExport SEXP _RPostgres_result_release(SEXP resSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< XPtr >::type res(resSEXP); - result_release(res); - return R_NilValue; -END_RCPP -} -// result_valid -bool result_valid(XPtr res_); -RcppExport SEXP _RPostgres_result_valid(SEXP res_SEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< XPtr >::type res_(res_SEXP); - rcpp_result_gen = Rcpp::wrap(result_valid(res_)); - return rcpp_result_gen; -END_RCPP -} -// result_fetch -List result_fetch(DbResult* res, const int n); -RcppExport SEXP _RPostgres_result_fetch(SEXP resSEXP, SEXP nSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - Rcpp::traits::input_parameter< const int >::type n(nSEXP); - rcpp_result_gen = Rcpp::wrap(result_fetch(res, n)); - return rcpp_result_gen; -END_RCPP -} -// result_bind -void result_bind(DbResult* res, List params); -RcppExport SEXP _RPostgres_result_bind(SEXP resSEXP, SEXP paramsSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - Rcpp::traits::input_parameter< List >::type params(paramsSEXP); - result_bind(res, params); - return R_NilValue; -END_RCPP -} -// result_has_completed -bool result_has_completed(DbResult* res); -RcppExport SEXP _RPostgres_result_has_completed(SEXP resSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - rcpp_result_gen = Rcpp::wrap(result_has_completed(res)); - return rcpp_result_gen; -END_RCPP -} -// result_rows_fetched -int result_rows_fetched(DbResult* res); -RcppExport SEXP _RPostgres_result_rows_fetched(SEXP resSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - rcpp_result_gen = Rcpp::wrap(result_rows_fetched(res)); - return rcpp_result_gen; -END_RCPP -} -// result_rows_affected -int result_rows_affected(DbResult* res); -RcppExport SEXP _RPostgres_result_rows_affected(SEXP resSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - rcpp_result_gen = Rcpp::wrap(result_rows_affected(res)); - return rcpp_result_gen; -END_RCPP -} -// result_column_info -List result_column_info(DbResult* res); -RcppExport SEXP _RPostgres_result_column_info(SEXP resSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< DbResult* >::type res(resSEXP); - rcpp_result_gen = Rcpp::wrap(result_column_info(res)); - return rcpp_result_gen; -END_RCPP -} - -static const R_CallMethodDef CallEntries[] = { - {"_RPostgres_client_version", (DL_FUNC) &_RPostgres_client_version, 0}, - {"_RPostgres_connection_create", (DL_FUNC) &_RPostgres_connection_create, 3}, - {"_RPostgres_connection_valid", (DL_FUNC) &_RPostgres_connection_valid, 1}, - {"_RPostgres_connection_release", (DL_FUNC) &_RPostgres_connection_release, 1}, - {"_RPostgres_connection_info", (DL_FUNC) &_RPostgres_connection_info, 1}, - {"_RPostgres_connection_quote_string", (DL_FUNC) &_RPostgres_connection_quote_string, 2}, - {"_RPostgres_connection_quote_identifier", (DL_FUNC) &_RPostgres_connection_quote_identifier, 2}, - {"_RPostgres_connection_is_transacting", (DL_FUNC) &_RPostgres_connection_is_transacting, 1}, - {"_RPostgres_connection_set_transacting", (DL_FUNC) &_RPostgres_connection_set_transacting, 2}, - {"_RPostgres_connection_copy_data", (DL_FUNC) &_RPostgres_connection_copy_data, 3}, - {"_RPostgres_connection_wait_for_notify", (DL_FUNC) &_RPostgres_connection_wait_for_notify, 2}, - {"_RPostgres_connection_get_temp_schema", (DL_FUNC) &_RPostgres_connection_get_temp_schema, 1}, - {"_RPostgres_connection_set_temp_schema", (DL_FUNC) &_RPostgres_connection_set_temp_schema, 2}, - {"_RPostgres_encode_vector", (DL_FUNC) &_RPostgres_encode_vector, 1}, - {"_RPostgres_encode_data_frame", (DL_FUNC) &_RPostgres_encode_data_frame, 1}, - {"_RPostgres_encrypt_password", (DL_FUNC) &_RPostgres_encrypt_password, 2}, - {"_RPostgres_init_logging", (DL_FUNC) &_RPostgres_init_logging, 1}, - {"_RPostgres_result_create", (DL_FUNC) &_RPostgres_result_create, 3}, - {"_RPostgres_result_release", (DL_FUNC) &_RPostgres_result_release, 1}, - {"_RPostgres_result_valid", (DL_FUNC) &_RPostgres_result_valid, 1}, - {"_RPostgres_result_fetch", (DL_FUNC) &_RPostgres_result_fetch, 2}, - {"_RPostgres_result_bind", (DL_FUNC) &_RPostgres_result_bind, 2}, - {"_RPostgres_result_has_completed", (DL_FUNC) &_RPostgres_result_has_completed, 1}, - {"_RPostgres_result_rows_fetched", (DL_FUNC) &_RPostgres_result_rows_fetched, 1}, - {"_RPostgres_result_rows_affected", (DL_FUNC) &_RPostgres_result_rows_affected, 1}, - {"_RPostgres_result_column_info", (DL_FUNC) &_RPostgres_result_column_info, 1}, - {NULL, NULL, 0} -}; - -RcppExport void R_init_RPostgres(DllInfo *dll) { - R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); - R_useDynamicSymbols(dll, FALSE); -} diff --git a/src/connection.cpp b/src/connection.cpp index 0deffa327..2e0cb172a 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -2,13 +2,13 @@ #include "RPostgres_types.h" -// [[Rcpp::export]] +[[cpp11::register]] int client_version() { return PQlibVersion(); } -// [[Rcpp::export]] -XPtr connection_create( +[[cpp11::register]] +cpp11::external_pointer connection_create( std::vector keys, std::vector values, bool check_interrupts @@ -19,61 +19,59 @@ XPtr connection_create( new DbConnection(keys, values, check_interrupts) ); - return XPtr(pConn, true); + return cpp11::external_pointer(pConn, true); } -// [[Rcpp::export]] -bool connection_valid(XPtr con_) { +[[cpp11::register]] +bool connection_valid(cpp11::external_pointer con_) { DbConnectionPtr* con = con_.get(); return con; } -// [[Rcpp::export]] -void connection_release(XPtr con_) { +[[cpp11::register]] +void connection_release(cpp11::external_pointer con_) { if (!connection_valid(con_)) { - warning("Already disconnected"); + cpp11::warning(std::string("Already disconnected")); return; } DbConnectionPtr* con = con_.get(); if (con->get()->has_query()) { - warning("%s\n%s", - "There is a result object still in use.", - "The connection will be automatically released when it is closed" - ); + cpp11::warning(std::string("There is a result object still in use.\n" + "The connection will be automatically released when it is closed")); } con->get()->disconnect(); - con_.release(); + con_.reset(); } -// [[Rcpp::export]] -List connection_info(DbConnection* con) { +[[cpp11::register]] +cpp11::list connection_info(DbConnection* con) { return con->info(); } // Quoting -// [[Rcpp::export]] -CharacterVector connection_quote_string(DbConnection* con, CharacterVector xs) { - R_xlen_t n = xs.size(); - CharacterVector output(n); +[[cpp11::register]] +cpp11::strings connection_quote_string(DbConnection* con, cpp11::strings xs) { + const auto n = xs.size(); + cpp11::writable::strings output(n); for (R_xlen_t i = 0; i < n; ++i) { - String x = xs[i]; + auto x = xs[i]; output[i] = con->quote_string(x); } return output; } -// [[Rcpp::export]] -CharacterVector connection_quote_identifier(DbConnection* con, CharacterVector xs) { - R_xlen_t n = xs.size(); - CharacterVector output(n); +[[cpp11::register]] +cpp11::strings connection_quote_identifier(DbConnection* con, cpp11::strings xs) { + const auto n = xs.size(); + cpp11::writable::strings output(n); for (R_xlen_t i = 0; i < n; ++i) { - String x = xs[i]; + auto x = xs[i]; output[i] = con->quote_identifier(x); } @@ -82,48 +80,35 @@ CharacterVector connection_quote_identifier(DbConnection* con, CharacterVector x // Transactions -// [[Rcpp::export]] +[[cpp11::register]] bool connection_is_transacting(DbConnection* con) { return con->is_transacting(); } -// [[Rcpp::export]] +[[cpp11::register]] void connection_set_transacting(DbConnection* con, bool transacting) { con->set_transacting(transacting); } // Specific functions -// [[Rcpp::export]] -void connection_copy_data(DbConnection* con, std::string sql, List df) { +[[cpp11::register]] +void connection_copy_data(DbConnection* con, std::string sql, cpp11::list df) { return con->copy_data(sql, df); } -// [[Rcpp::export]] -List connection_wait_for_notify(DbConnection* con, int timeout_secs) { +[[cpp11::register]] +cpp11::list connection_wait_for_notify(DbConnection* con, int timeout_secs) { return con->wait_for_notify(timeout_secs); } // Temporary Schema -// [[Rcpp::export]] -CharacterVector connection_get_temp_schema(DbConnection* con) { +[[cpp11::register]] +cpp11::strings connection_get_temp_schema(DbConnection* con) { return con->get_temp_schema(); } -// [[Rcpp::export]] -void connection_set_temp_schema(DbConnection* con, CharacterVector temp_schema) { - con->set_temp_schema(temp_schema); -} - -// as() override - -namespace Rcpp { - -template<> -DbConnection* as(SEXP x) { - DbConnectionPtr* connection = (DbConnectionPtr*)(R_ExternalPtrAddr(x)); - if (!connection) - stop("Invalid connection"); - return connection->get(); -} +[[cpp11::register]] +void connection_set_temp_schema(DbConnection* con, cpp11::strings temp_schema) { + con->set_temp_schema(temp_schema); } diff --git a/src/cpp11.cpp b/src/cpp11.cpp new file mode 100644 index 000000000..bf613ab9c --- /dev/null +++ b/src/cpp11.cpp @@ -0,0 +1,234 @@ +// Generated by cpp11: do not edit by hand +// clang-format off + +#include "RPostgres_types.h" +#include "cpp11/declarations.hpp" +#include + +// connection.cpp +int client_version(); +extern "C" SEXP _RPostgres_client_version() { + BEGIN_CPP11 + return cpp11::as_sexp(client_version()); + END_CPP11 +} +// connection.cpp +cpp11::external_pointer connection_create(std::vector keys, std::vector values, bool check_interrupts); +extern "C" SEXP _RPostgres_connection_create(SEXP keys, SEXP values, SEXP check_interrupts) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_create(cpp11::as_cpp>>(keys), cpp11::as_cpp>>(values), cpp11::as_cpp>(check_interrupts))); + END_CPP11 +} +// connection.cpp +bool connection_valid(cpp11::external_pointer con_); +extern "C" SEXP _RPostgres_connection_valid(SEXP con_) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_valid(cpp11::as_cpp>>(con_))); + END_CPP11 +} +// connection.cpp +void connection_release(cpp11::external_pointer con_); +extern "C" SEXP _RPostgres_connection_release(SEXP con_) { + BEGIN_CPP11 + connection_release(cpp11::as_cpp>>(con_)); + return R_NilValue; + END_CPP11 +} +// connection.cpp +cpp11::list connection_info(DbConnection* con); +extern "C" SEXP _RPostgres_connection_info(SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_info(cpp11::as_cpp>(con))); + END_CPP11 +} +// connection.cpp +cpp11::strings connection_quote_string(DbConnection* con, cpp11::strings xs); +extern "C" SEXP _RPostgres_connection_quote_string(SEXP con, SEXP xs) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_quote_string(cpp11::as_cpp>(con), cpp11::as_cpp>(xs))); + END_CPP11 +} +// connection.cpp +cpp11::strings connection_quote_identifier(DbConnection* con, cpp11::strings xs); +extern "C" SEXP _RPostgres_connection_quote_identifier(SEXP con, SEXP xs) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_quote_identifier(cpp11::as_cpp>(con), cpp11::as_cpp>(xs))); + END_CPP11 +} +// connection.cpp +bool connection_is_transacting(DbConnection* con); +extern "C" SEXP _RPostgres_connection_is_transacting(SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_is_transacting(cpp11::as_cpp>(con))); + END_CPP11 +} +// connection.cpp +void connection_set_transacting(DbConnection* con, bool transacting); +extern "C" SEXP _RPostgres_connection_set_transacting(SEXP con, SEXP transacting) { + BEGIN_CPP11 + connection_set_transacting(cpp11::as_cpp>(con), cpp11::as_cpp>(transacting)); + return R_NilValue; + END_CPP11 +} +// connection.cpp +void connection_copy_data(DbConnection* con, std::string sql, cpp11::list df); +extern "C" SEXP _RPostgres_connection_copy_data(SEXP con, SEXP sql, SEXP df) { + BEGIN_CPP11 + connection_copy_data(cpp11::as_cpp>(con), cpp11::as_cpp>(sql), cpp11::as_cpp>(df)); + return R_NilValue; + END_CPP11 +} +// connection.cpp +cpp11::list connection_wait_for_notify(DbConnection* con, int timeout_secs); +extern "C" SEXP _RPostgres_connection_wait_for_notify(SEXP con, SEXP timeout_secs) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_wait_for_notify(cpp11::as_cpp>(con), cpp11::as_cpp>(timeout_secs))); + END_CPP11 +} +// connection.cpp +cpp11::strings connection_get_temp_schema(DbConnection* con); +extern "C" SEXP _RPostgres_connection_get_temp_schema(SEXP con) { + BEGIN_CPP11 + return cpp11::as_sexp(connection_get_temp_schema(cpp11::as_cpp>(con))); + END_CPP11 +} +// connection.cpp +void connection_set_temp_schema(DbConnection* con, cpp11::strings temp_schema); +extern "C" SEXP _RPostgres_connection_set_temp_schema(SEXP con, SEXP temp_schema) { + BEGIN_CPP11 + connection_set_temp_schema(cpp11::as_cpp>(con), cpp11::as_cpp>(temp_schema)); + return R_NilValue; + END_CPP11 +} +// encode.cpp +std::string encode_vector(cpp11::sexp x); +extern "C" SEXP _RPostgres_encode_vector(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(encode_vector(cpp11::as_cpp>(x))); + END_CPP11 +} +// encode.cpp +std::string encode_data_frame(cpp11::list x); +extern "C" SEXP _RPostgres_encode_data_frame(SEXP x) { + BEGIN_CPP11 + return cpp11::as_sexp(encode_data_frame(cpp11::as_cpp>(x))); + END_CPP11 +} +// encrypt.cpp +std::string encrypt_password(cpp11::r_string password, cpp11::r_string user); +extern "C" SEXP _RPostgres_encrypt_password(SEXP password, SEXP user) { + BEGIN_CPP11 + return cpp11::as_sexp(encrypt_password(cpp11::as_cpp>(password), cpp11::as_cpp>(user))); + END_CPP11 +} +// logging.cpp +void init_logging(const std::string& log_level); +extern "C" SEXP _RPostgres_init_logging(SEXP log_level) { + BEGIN_CPP11 + init_logging(cpp11::as_cpp>(log_level)); + return R_NilValue; + END_CPP11 +} +// result.cpp +cpp11::external_pointer result_create(cpp11::external_pointer con, std::string sql, bool immediate); +extern "C" SEXP _RPostgres_result_create(SEXP con, SEXP sql, SEXP immediate) { + BEGIN_CPP11 + return cpp11::as_sexp(result_create(cpp11::as_cpp>>(con), cpp11::as_cpp>(sql), cpp11::as_cpp>(immediate))); + END_CPP11 +} +// result.cpp +void result_release(cpp11::external_pointer res); +extern "C" SEXP _RPostgres_result_release(SEXP res) { + BEGIN_CPP11 + result_release(cpp11::as_cpp>>(res)); + return R_NilValue; + END_CPP11 +} +// result.cpp +bool result_valid(cpp11::external_pointer res_); +extern "C" SEXP _RPostgres_result_valid(SEXP res_) { + BEGIN_CPP11 + return cpp11::as_sexp(result_valid(cpp11::as_cpp>>(res_))); + END_CPP11 +} +// result.cpp +cpp11::list result_fetch(DbResult* res, const int n); +extern "C" SEXP _RPostgres_result_fetch(SEXP res, SEXP n) { + BEGIN_CPP11 + return cpp11::as_sexp(result_fetch(cpp11::as_cpp>(res), cpp11::as_cpp>(n))); + END_CPP11 +} +// result.cpp +void result_bind(DbResult* res, cpp11::list params); +extern "C" SEXP _RPostgres_result_bind(SEXP res, SEXP params) { + BEGIN_CPP11 + result_bind(cpp11::as_cpp>(res), cpp11::as_cpp>(params)); + return R_NilValue; + END_CPP11 +} +// result.cpp +bool result_has_completed(DbResult* res); +extern "C" SEXP _RPostgres_result_has_completed(SEXP res) { + BEGIN_CPP11 + return cpp11::as_sexp(result_has_completed(cpp11::as_cpp>(res))); + END_CPP11 +} +// result.cpp +int result_rows_fetched(DbResult* res); +extern "C" SEXP _RPostgres_result_rows_fetched(SEXP res) { + BEGIN_CPP11 + return cpp11::as_sexp(result_rows_fetched(cpp11::as_cpp>(res))); + END_CPP11 +} +// result.cpp +int result_rows_affected(DbResult* res); +extern "C" SEXP _RPostgres_result_rows_affected(SEXP res) { + BEGIN_CPP11 + return cpp11::as_sexp(result_rows_affected(cpp11::as_cpp>(res))); + END_CPP11 +} +// result.cpp +cpp11::list result_column_info(DbResult* res); +extern "C" SEXP _RPostgres_result_column_info(SEXP res) { + BEGIN_CPP11 + return cpp11::as_sexp(result_column_info(cpp11::as_cpp>(res))); + END_CPP11 +} + +extern "C" { +static const R_CallMethodDef CallEntries[] = { + {"_RPostgres_client_version", (DL_FUNC) &_RPostgres_client_version, 0}, + {"_RPostgres_connection_copy_data", (DL_FUNC) &_RPostgres_connection_copy_data, 3}, + {"_RPostgres_connection_create", (DL_FUNC) &_RPostgres_connection_create, 3}, + {"_RPostgres_connection_get_temp_schema", (DL_FUNC) &_RPostgres_connection_get_temp_schema, 1}, + {"_RPostgres_connection_info", (DL_FUNC) &_RPostgres_connection_info, 1}, + {"_RPostgres_connection_is_transacting", (DL_FUNC) &_RPostgres_connection_is_transacting, 1}, + {"_RPostgres_connection_quote_identifier", (DL_FUNC) &_RPostgres_connection_quote_identifier, 2}, + {"_RPostgres_connection_quote_string", (DL_FUNC) &_RPostgres_connection_quote_string, 2}, + {"_RPostgres_connection_release", (DL_FUNC) &_RPostgres_connection_release, 1}, + {"_RPostgres_connection_set_temp_schema", (DL_FUNC) &_RPostgres_connection_set_temp_schema, 2}, + {"_RPostgres_connection_set_transacting", (DL_FUNC) &_RPostgres_connection_set_transacting, 2}, + {"_RPostgres_connection_valid", (DL_FUNC) &_RPostgres_connection_valid, 1}, + {"_RPostgres_connection_wait_for_notify", (DL_FUNC) &_RPostgres_connection_wait_for_notify, 2}, + {"_RPostgres_encode_data_frame", (DL_FUNC) &_RPostgres_encode_data_frame, 1}, + {"_RPostgres_encode_vector", (DL_FUNC) &_RPostgres_encode_vector, 1}, + {"_RPostgres_encrypt_password", (DL_FUNC) &_RPostgres_encrypt_password, 2}, + {"_RPostgres_init_logging", (DL_FUNC) &_RPostgres_init_logging, 1}, + {"_RPostgres_result_bind", (DL_FUNC) &_RPostgres_result_bind, 2}, + {"_RPostgres_result_column_info", (DL_FUNC) &_RPostgres_result_column_info, 1}, + {"_RPostgres_result_create", (DL_FUNC) &_RPostgres_result_create, 3}, + {"_RPostgres_result_fetch", (DL_FUNC) &_RPostgres_result_fetch, 2}, + {"_RPostgres_result_has_completed", (DL_FUNC) &_RPostgres_result_has_completed, 1}, + {"_RPostgres_result_release", (DL_FUNC) &_RPostgres_result_release, 1}, + {"_RPostgres_result_rows_affected", (DL_FUNC) &_RPostgres_result_rows_affected, 1}, + {"_RPostgres_result_rows_fetched", (DL_FUNC) &_RPostgres_result_rows_fetched, 1}, + {"_RPostgres_result_valid", (DL_FUNC) &_RPostgres_result_valid, 1}, + {NULL, NULL, 0} +}; +} + +extern "C" attribute_visible void R_init_RPostgres(DllInfo* dll){ + R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); + R_useDynamicSymbols(dll, FALSE); + R_forceSymbols(dll, TRUE); +} diff --git a/src/encode.cpp b/src/encode.cpp index 84c8cb301..0babc91d1 100644 --- a/src/encode.cpp +++ b/src/encode.cpp @@ -2,8 +2,8 @@ #include "encode.h" -// [[Rcpp::export]] -std::string encode_vector(RObject x) { +[[cpp11::register]] +std::string encode_vector(cpp11::sexp x) { std::string buffer; int n = Rf_length(x); @@ -16,12 +16,12 @@ std::string encode_vector(RObject x) { return buffer; } -void encode_row_in_buffer(List x, int i, std::string& buffer, +void encode_row_in_buffer(cpp11::list x, int i, std::string& buffer, std::string fieldDelim, std::string lineDelim) { int p = Rf_length(x); for (int j = 0; j < p; ++j) { - RObject xj(x[j]); + auto xj(x[j]); encode_in_buffer(xj, i, buffer); if (j != p - 1) buffer.append(fieldDelim); @@ -29,8 +29,8 @@ void encode_row_in_buffer(List x, int i, std::string& buffer, buffer.append(lineDelim); } -// [[Rcpp::export]] -std::string encode_data_frame(List x) { +[[cpp11::register]] +std::string encode_data_frame(cpp11::list x) { if (Rf_length(x) == 0) return (""); int n = Rf_length(x[0]); @@ -48,7 +48,7 @@ std::string encode_data_frame(List x) { // Written by: tomoakin@kenroku.kanazawa-u.ac.jp // License: GPL-2 -void encode_in_buffer(RObject x, int i, std::string& buffer) { +void encode_in_buffer(cpp11::sexp x, int i, std::string& buffer) { switch (TYPEOF(x)) { case LGLSXP: { @@ -96,7 +96,7 @@ void encode_in_buffer(RObject x, int i, std::string& buffer) { } case STRSXP: { - RObject value = STRING_ELT(x, i); + cpp11::sexp value = STRING_ELT(x, i); if (value == NA_STRING) { buffer.append("\\N"); } else { @@ -106,8 +106,7 @@ void encode_in_buffer(RObject x, int i, std::string& buffer) { break; } default: - stop("Don't know how to handle vector of type %s.", - Rf_type2char(TYPEOF(x))); + cpp11::stop(std::string("Don't know how to handle vector of type ") + Rf_type2char(TYPEOF(x)) + "."); } } diff --git a/src/encode.h b/src/encode.h index 3c489ab2b..073ebae43 100644 --- a/src/encode.h +++ b/src/encode.h @@ -4,10 +4,10 @@ // Defined in encode.cpp ------------------------------------------------------- void escape_in_buffer(const char* string, std::string& buffer); -void encode_in_buffer(RObject x, int i, std::string& buffer); -void encode_row_in_buffer(List x, int i, std::string& buffer, +void encode_in_buffer(cpp11::sexp x, int i, std::string& buffer); +void encode_row_in_buffer(cpp11::list x, int i, std::string& buffer, std::string fieldDelim = "\t", std::string lineDelim = "\n"); -std::string encode_data_frame(List x); +std::string encode_data_frame(cpp11::list x); #endif diff --git a/src/encrypt.cpp b/src/encrypt.cpp index 2b9705726..2b4477ea3 100644 --- a/src/encrypt.cpp +++ b/src/encrypt.cpp @@ -1,12 +1,12 @@ #include "pch.h" -// [[Rcpp::export]] -String encrypt_password(String password, String user) { - char* encrypted = PQencryptPassword(password.get_cstring(), user.get_cstring()); - - String copy(encrypted); - PQfreemem(encrypted); - - return copy; +[[cpp11::register]] +std::string encrypt_password(cpp11::r_string password, cpp11::r_string user) { + const auto pass = static_cast(password); + const auto u = static_cast(user); + + const char* encrypted = PQencryptPassword(pass.c_str(), u.c_str()); + + return encrypted; } diff --git a/src/logging.cpp b/src/logging.cpp index 672619fe1..68ded2db0 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -2,7 +2,7 @@ #include -// [[Rcpp::export]] +[[cpp11::register]] void init_logging(const std::string& log_level) { plog::init_r(log_level); } diff --git a/src/pch.h b/src/pch.h index 9b640c240..811463b63 100644 --- a/src/pch.h +++ b/src/pch.h @@ -1,6 +1,4 @@ -#include +#include #include #include - -using namespace Rcpp; diff --git a/src/result.cpp b/src/result.cpp index daf863b43..b63470ace 100644 --- a/src/result.cpp +++ b/src/result.cpp @@ -3,62 +3,50 @@ #include "PqResult.h" -// [[Rcpp::export]] -XPtr result_create(XPtr con, std::string sql, bool immediate) { +[[cpp11::register]] +cpp11::external_pointer result_create(cpp11::external_pointer con, std::string sql, bool immediate) { (*con)->check_connection(); DbResult* res = PqResult::create_and_send_query(*con, sql, immediate); - return XPtr(res, true); + return cpp11::external_pointer(res, true); } -// [[Rcpp::export]] -void result_release(XPtr res) { - res.release(); +[[cpp11::register]] +void result_release(cpp11::external_pointer res) { + res.reset(); } -// [[Rcpp::export]] -bool result_valid(XPtr res_) { +[[cpp11::register]] +bool result_valid(cpp11::external_pointer res_) { DbResult* res = res_.get(); return res != NULL && res->is_active(); } -// [[Rcpp::export]] -List result_fetch(DbResult* res, const int n) { +[[cpp11::register]] +cpp11::list result_fetch(DbResult* res, const int n) { return res->fetch(n); } -// [[Rcpp::export]] -void result_bind(DbResult* res, List params) { +[[cpp11::register]] +void result_bind(DbResult* res, cpp11::list params) { res->bind(params); } -// [[Rcpp::export]] +[[cpp11::register]] bool result_has_completed(DbResult* res) { return res->complete(); } -// [[Rcpp::export]] +[[cpp11::register]] int result_rows_fetched(DbResult* res) { return res->n_rows_fetched(); } -// [[Rcpp::export]] +[[cpp11::register]] int result_rows_affected(DbResult* res) { return res->n_rows_affected(); } -// [[Rcpp::export]] -List result_column_info(DbResult* res) { +[[cpp11::register]] +cpp11::list result_column_info(DbResult* res) { return res->get_column_info(); } - -namespace Rcpp { - -template<> -DbResult* as(SEXP x) { - DbResult* result = (DbResult*)(R_ExternalPtrAddr(x)); - if (!result) - stop("Invalid result set"); - return result; -} - -} diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index 7db36e4e9..fec1923de 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -1,7 +1,7 @@ test_that("querying closed connection throws error", { db <- postgresDefault() dbDisconnect(db) - expect_error(dbSendQuery(db, "select * from foo"), "not valid") + expect_error(dbSendQuery(db, "select * from foo"), "bad_weak_ptr") }) test_that("warn if previous result set is invalidated", { diff --git a/vscode-install.r b/vscode-install.r new file mode 100644 index 000000000..5e8292dbe --- /dev/null +++ b/vscode-install.r @@ -0,0 +1,4 @@ +if (!require(covr)) install.packages("covr") +if (!require(DBItest)) install.packages("DBItest") +devtools::install(upgrade = "never") +devtools::check()