amoeba commented on code in PR #1269: URL: https://github.com/apache/arrow-adbc/pull/1269#discussion_r1387443931
########## r/adbcdrivermanager/src/driver_test.cc: ########## @@ -0,0 +1,280 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#define R_NO_REMAP +#include <R.h> +#include <Rinternals.h> + +#include <cstring> + +#include "driver_base.h" + +#include <adbc.h> + +using adbc::r::Option; + +using VoidDriver = + adbc::r::Driver<adbc::r::DatabaseObjectBase, adbc::r::ConnectionObjectBase, + adbc::r::StatementObjectBase>; + +static AdbcStatusCode VoidDriverInitFunc(int version, void* raw_driver, + AdbcError* error) { + return VoidDriver::Init(version, raw_driver, error); +} + +extern "C" SEXP RAdbcVoidDriverInitFunc(void) { + SEXP xptr = + PROTECT(R_MakeExternalPtrFn((DL_FUNC)VoidDriverInitFunc, R_NilValue, R_NilValue)); + Rf_setAttrib(xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func")); + UNPROTECT(1); + return xptr; +} + +class MonkeyDriverStatement : public adbc::r::StatementObjectBase { + public: + MonkeyDriverStatement() { stream_.release = nullptr; } + + ~MonkeyDriverStatement() { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + } + + AdbcStatusCode BindStream(ArrowArrayStream* stream, AdbcError* error) { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + + std::memcpy(&stream_, stream, sizeof(ArrowArrayStream)); + stream->release = nullptr; + return ADBC_STATUS_OK; + } + + AdbcStatusCode ExecuteQuery(ArrowArrayStream* stream, int64_t* rows_affected, + AdbcError* error) { + if (stream != nullptr) { + std::memcpy(stream, &stream_, sizeof(ArrowArrayStream)); + stream_.release = nullptr; + } + + *rows_affected = -1; + return ADBC_STATUS_OK; + } + + private: + ArrowArrayStream stream_; +}; + +using MonkeyDriver = + adbc::r::Driver<adbc::r::DatabaseObjectBase, adbc::r::ConnectionObjectBase, + MonkeyDriverStatement>; + +static AdbcStatusCode MonkeyDriverInitFunc(int version, void* raw_driver, + AdbcError* error) { + return MonkeyDriver::Init(version, raw_driver, error); +} + +extern "C" SEXP RAdbcMonkeyDriverInitFunc(void) { + SEXP xptr = + PROTECT(R_MakeExternalPtrFn((DL_FUNC)MonkeyDriverInitFunc, R_NilValue, R_NilValue)); + Rf_setAttrib(xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func")); + UNPROTECT(1); + return xptr; +} + +class LogDriverDatabase : public adbc::r::DatabaseObjectBase { + public: + LogDriverDatabase() { Rprintf("LogDatabaseNew()\n"); } + + ~LogDriverDatabase() { Rprintf("LogDatabaseRelease()\n"); } + + AdbcStatusCode SetOption(const std::string& key, const Option& value) { Review Comment: Feel free to ignore, but the method order within this class and others jumped out at me. Here, it's SetOption, Init, GetOption, elsewhere it's Init, SetOption, GetOption. Consistency has some advantages, as does some sort of natural ordering. For me that'd be Init, GetOption, SetOption, and the rest in whatever natural order makes sense. ########## r/adbcdrivermanager/src/driver_test.cc: ########## @@ -0,0 +1,280 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#define R_NO_REMAP +#include <R.h> +#include <Rinternals.h> + +#include <cstring> + +#include "driver_base.h" + +#include <adbc.h> + +using adbc::r::Option; + +using VoidDriver = + adbc::r::Driver<adbc::r::DatabaseObjectBase, adbc::r::ConnectionObjectBase, + adbc::r::StatementObjectBase>; + +static AdbcStatusCode VoidDriverInitFunc(int version, void* raw_driver, + AdbcError* error) { + return VoidDriver::Init(version, raw_driver, error); +} + +extern "C" SEXP RAdbcVoidDriverInitFunc(void) { + SEXP xptr = + PROTECT(R_MakeExternalPtrFn((DL_FUNC)VoidDriverInitFunc, R_NilValue, R_NilValue)); + Rf_setAttrib(xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func")); + UNPROTECT(1); + return xptr; +} + +class MonkeyDriverStatement : public adbc::r::StatementObjectBase { + public: + MonkeyDriverStatement() { stream_.release = nullptr; } + + ~MonkeyDriverStatement() { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + } + + AdbcStatusCode BindStream(ArrowArrayStream* stream, AdbcError* error) { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + + std::memcpy(&stream_, stream, sizeof(ArrowArrayStream)); + stream->release = nullptr; + return ADBC_STATUS_OK; + } + + AdbcStatusCode ExecuteQuery(ArrowArrayStream* stream, int64_t* rows_affected, + AdbcError* error) { + if (stream != nullptr) { + std::memcpy(stream, &stream_, sizeof(ArrowArrayStream)); + stream_.release = nullptr; + } + + *rows_affected = -1; Review Comment: Still learning ADBC as I go, but the change from 0 to -1 here caused me to go look it up. I see -1 here is matching the spec so 👍 but I also noticed, > Pass NULL if the client does not want this information. Is that relevant here and, if so, should it be handled here and lots of other places? I see the C SQLite driver guards it with a null-check, ```c if (rows_affected) *rows_affected = row_count; ``` https://github.com/apache/arrow-adbc/blob/a9c4f55da8d227f160705b7f9a31838fc555ab20/c/driver/sqlite/sqlite.c/#L1412 ########## r/adbcdrivermanager/src/driver_test.cc: ########## @@ -0,0 +1,280 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#define R_NO_REMAP +#include <R.h> +#include <Rinternals.h> + +#include <cstring> + +#include "driver_base.h" + +#include <adbc.h> + +using adbc::r::Option; + +using VoidDriver = + adbc::r::Driver<adbc::r::DatabaseObjectBase, adbc::r::ConnectionObjectBase, + adbc::r::StatementObjectBase>; + +static AdbcStatusCode VoidDriverInitFunc(int version, void* raw_driver, + AdbcError* error) { + return VoidDriver::Init(version, raw_driver, error); +} + +extern "C" SEXP RAdbcVoidDriverInitFunc(void) { + SEXP xptr = + PROTECT(R_MakeExternalPtrFn((DL_FUNC)VoidDriverInitFunc, R_NilValue, R_NilValue)); + Rf_setAttrib(xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func")); + UNPROTECT(1); + return xptr; +} + +class MonkeyDriverStatement : public adbc::r::StatementObjectBase { + public: + MonkeyDriverStatement() { stream_.release = nullptr; } + + ~MonkeyDriverStatement() { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + } + + AdbcStatusCode BindStream(ArrowArrayStream* stream, AdbcError* error) { + if (stream_.release != nullptr) { + stream_.release(&stream_); + } + + std::memcpy(&stream_, stream, sizeof(ArrowArrayStream)); + stream->release = nullptr; + return ADBC_STATUS_OK; + } + + AdbcStatusCode ExecuteQuery(ArrowArrayStream* stream, int64_t* rows_affected, + AdbcError* error) { + if (stream != nullptr) { + std::memcpy(stream, &stream_, sizeof(ArrowArrayStream)); + stream_.release = nullptr; + } + + *rows_affected = -1; Review Comment: Still learning ADBC as I go, but the change from 0 to -1 here caused me to go look it up. I see -1 here is matching the spec so 👍 but I also noticed, > Pass NULL if the client does not want this information. Is that relevant here and, if so, should it be handled here and lots of other places? I see the C SQLite driver guards it with a null-check, ```c if (rows_affected) *rows_affected = row_count; ``` https://github.com/apache/arrow-adbc/blob/a9c4f55da8d227f160705b7f9a31838fc555ab20/c/driver/sqlite/sqlite.c/#L1412 ########## r/adbcdrivermanager/src/driver_test.cc: ########## @@ -0,0 +1,280 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#define R_NO_REMAP +#include <R.h> +#include <Rinternals.h> + +#include <cstring> + +#include "driver_base.h" + +#include <adbc.h> + +using adbc::r::Option; + +using VoidDriver = + adbc::r::Driver<adbc::r::DatabaseObjectBase, adbc::r::ConnectionObjectBase, + adbc::r::StatementObjectBase>; + +static AdbcStatusCode VoidDriverInitFunc(int version, void* raw_driver, + AdbcError* error) { + return VoidDriver::Init(version, raw_driver, error); +} + +extern "C" SEXP RAdbcVoidDriverInitFunc(void) { + SEXP xptr = + PROTECT(R_MakeExternalPtrFn((DL_FUNC)VoidDriverInitFunc, R_NilValue, R_NilValue)); + Rf_setAttrib(xptr, R_ClassSymbol, Rf_mkString("adbc_driver_init_func")); + UNPROTECT(1); + return xptr; +} + +class MonkeyDriverStatement : public adbc::r::StatementObjectBase { + public: + MonkeyDriverStatement() { stream_.release = nullptr; } + + ~MonkeyDriverStatement() { + if (stream_.release != nullptr) { + stream_.release(&stream_); Review Comment: Also still learning here, but does this destructor also need to set `stream_.release` to NULL after calling it? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
