Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get everything building again #3

Merged
merged 1 commit into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ repos:
rev: v0.6.13
hooks:
- id: cmake-format
args: [--in-place, --config-files, .cmake-format]
args: [--in-place]
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,18 @@
[![License](http://img.shields.io/:license-Apache%202-blue.svg)](https://github.com/apache/arrow-adbc/blob/master/LICENSE.txt)

EXPERIMENTAL. Please see the [mailing list discussion](https://lists.apache.org/thread/gnz1kz2rj3rb8rh8qz7l0mv8lvzq254w).

## Building

The libraries here are all **individual** CMake projects.

```shell
$ mkdir -p build/driver_manager
$ cd build/driver_manager
$ cmake ../../adbc_driver_manager
$ make
```

Some of Arrow's build options are supported:

- `ARROW_BUILD_TESTS`: build the unit tests
4 changes: 4 additions & 0 deletions adbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
extern "C" {
#endif

// Extra guard for versions of Arrow without the canonical guard
#ifndef ARROW_FLAG_DICTIONARY_ORDERED

#ifndef ARROW_C_DATA_INTERFACE
#define ARROW_C_DATA_INTERFACE

Expand Down Expand Up @@ -108,6 +111,7 @@ struct ArrowArrayStream {
};

#endif // ARROW_C_STREAM_INTERFACE
#endif // ARROW_FLAG_DICTIONARY_ORDERED

#ifndef ADBC
#define ADBC
Expand Down
47 changes: 25 additions & 22 deletions adbc_driver_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,35 @@
# under the License.

cmake_minimum_required(VERSION 3.10)

set(ARROW_VERSION "9.0.0-SNAPSHOT")
set(ARROW_BASE_VERSION "9.0.0")
set(ARROW_VERSION_MAJOR "9")
set(ARROW_VERSION_MINOR "0")
set(ARROW_VERSION_PATCH "0")

math(EXPR ARROW_SO_VERSION "${ARROW_VERSION_MAJOR} * 100 + ${ARROW_VERSION_MINOR}")
set(ARROW_FULL_SO_VERSION "${ARROW_SO_VERSION}.${ARROW_VERSION_PATCH}.0")

project(adbc_driver_manager VERSION "${ARROW_BASE_VERSION}" LANGUAGES CXX)

# Common CMake utilities
get_filename_component(REPOSITORY_ROOT ${CMAKE_SOURCE_DIR} DIRECTORY)
get_filename_component(REPOSITORY_ROOT ".." ABSOLUTE)
message(STATUS "${REPOSITORY_ROOT}")
list(APPEND CMAKE_MODULE_PATH "${REPOSITORY_ROOT}/cmake_modules/")
include(AdbcDefines)
include(BuildUtils)
include(DefineOptions)

# Driver manager library
add_arrow_lib(adbc_driver_manager
SOURCES
adbc_driver_manager.cc)
include_directories(adbc_driver_manager SYSTEM
PRIVATE ${REPOSITORY_ROOT})

# Tests
project(adbc_driver_manager
VERSION "${ARROW_BASE_VERSION}"
LANGUAGES CXX)
add_arrow_lib(adbc_driver_manager SOURCES adbc_driver_manager.cc)
include_directories(SYSTEM ${REPOSITORY_ROOT})

if(ARROW_BUILD_TESTS)
find_package(Arrow REQUIRED)
if(ARROW_TEST_LINKAGE STREQUAL "shared")
set(TEST_LINK_LIBS adbc_driver_manager_shared arrow_shared)
else()
set(TEST_LINK_LIBS adbc_driver_manager_static arrow_static)
endif()

add_test_case(driver_manager_test
PREFIX
adbc
SOURCES
adbc_driver_manager_test.cc
EXTRA_LINK_LIBS
${TEST_LINK_LIBS})
endif()

validate_config()
config_summary_message()
194 changes: 127 additions & 67 deletions adbc_driver_manager/adbc_driver_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,89 +15,149 @@
// specific language governing permissions and limitations
// under the License.

// Test the driver, but using the driver manager's stubs instead of
// the function pointer table.

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "adbc/adbc.h"
#include "adbc/adbc_driver_manager.h"
#include "adbc/test_sqlite_internal.h"
#include "adbc/test_util.h"
#include "arrow/c/bridge.h"
#include "arrow/record_batch.h"
#include "arrow/testing/gtest_util.h"
#include "arrow/testing/matchers.h"
#include <arrow/c/bridge.h>
#include <arrow/record_batch.h>
#include <arrow/testing/matchers.h>

#include "adbc.h"
#include "adbc_driver_manager.h"
#include "drivers/test_util.h"

// Tests of the SQLite example driver, except using the driver manager

namespace adbc {

using arrow::PointeesEqual;

TEST(AdbcDriverManager, Basics) {
AdbcDatabase database;
AdbcConnection connection;
AdbcError error = {};

AdbcDriver driver;
ASSERT_NO_FATAL_FAILURE(InitSqlite(&driver));

{
AdbcDatabaseOptions options;
std::memset(&options, 0, sizeof(options));
options.driver = &driver;
ADBC_ASSERT_OK_WITH_ERROR(&driver, error,
AdbcDatabaseInit(&options, &database, &error));
class DriverManager : public ::testing::Test {
public:
void SetUp() override {
size_t initialized = 0;
ADBC_ASSERT_OK(
AdbcLoadDriver("Driver=libadbc_driver_sqlite.so;Entrypoint=AdbcSqliteDriverInit",
ADBC_VERSION_0_0_1, &driver, &initialized));
ASSERT_EQ(initialized, ADBC_VERSION_0_0_1);

AdbcDatabaseOptions db_options;
std::memset(&db_options, 0, sizeof(db_options));
db_options.driver = &driver;
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcDatabaseInit(&db_options, &database, &error));
ASSERT_NE(database.private_data, nullptr);
}

{
AdbcConnectionOptions options;
std::memset(&options, 0, sizeof(options));
options.database = &database;
ADBC_ASSERT_OK_WITH_ERROR(&driver, error,
AdbcConnectionInit(&options, &connection, &error));
AdbcConnectionOptions conn_options;
std::memset(&conn_options, 0, sizeof(conn_options));
conn_options.database = &database;
ADBC_ASSERT_OK_WITH_ERROR(error,
AdbcConnectionInit(&conn_options, &connection, &error));
ASSERT_NE(connection.private_data, nullptr);
}

{
std::string query = "SELECT 1";
AdbcStatement statement;
std::memset(&statement, 0, sizeof(statement));
ADBC_ASSERT_OK_WITH_ERROR(&driver, error,
AdbcStatementInit(&connection, &statement, &error));
ADBC_ASSERT_OK_WITH_ERROR(
&driver, error,
AdbcConnectionSqlExecute(&connection, query.c_str(), &statement, &error));

arrow::RecordBatchVector batches;
ArrowArrayStream stream;

ADBC_ASSERT_OK(AdbcStatementGetStream(&statement, &stream, &error));
ASSERT_OK_AND_ASSIGN(auto reader, arrow::ImportRecordBatchReader(&stream));

auto schema = reader->schema();
while (true) {
ASSERT_OK_AND_ASSIGN(auto batch, reader->Next());
if (!batch) break;
batches.push_back(std::move(batch));
}
ADBC_ASSERT_OK_WITH_ERROR(&driver, error, AdbcStatementRelease(&statement, &error));

arrow::AssertSchemaEqual(*schema,
*arrow::schema({arrow::field("1", arrow::int64())}));
EXPECT_THAT(batches,
::testing::UnorderedPointwise(
PointeesEqual(), {
arrow::RecordBatchFromJSON(schema, "[[1]]"),
}));
void TearDown() override {
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcConnectionRelease(&connection, &error));
ASSERT_EQ(connection.private_data, nullptr);

ADBC_ASSERT_OK_WITH_ERROR(error, AdbcDatabaseRelease(&database, &error));
ASSERT_EQ(database.private_data, nullptr);
}

ADBC_ASSERT_OK_WITH_ERROR(&driver, error, AdbcConnectionRelease(&connection, &error));
ASSERT_EQ(connection.private_data, nullptr);
protected:
AdbcDriver driver;
AdbcDatabase database;
AdbcConnection connection;
AdbcError error = {};
};

TEST_F(DriverManager, SqlExecute) {
std::string query = "SELECT 1";
AdbcStatement statement;
std::memset(&statement, 0, sizeof(statement));
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementInit(&connection, &statement, &error));
ADBC_ASSERT_OK_WITH_ERROR(
error, AdbcConnectionSqlExecute(&connection, query.c_str(), &statement, &error));

std::shared_ptr<arrow::Schema> schema;
arrow::RecordBatchVector batches;
ReadStatement(&statement, &schema, &batches);
ASSERT_SCHEMA_EQ(*schema, *arrow::schema({arrow::field("1", arrow::int64())}));
EXPECT_THAT(batches,
::testing::UnorderedPointwise(
PointeesEqual(), {
adbc::RecordBatchFromJSON(schema, "[[1]]"),
}));
}

TEST_F(DriverManager, SqlExecuteInvalid) {
GTEST_SKIP() << "AdbcError needs refactoring";

std::string query = "INVALID";
AdbcStatement statement;
std::memset(&statement, 0, sizeof(statement));
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementInit(&connection, &statement, &error));
ASSERT_NE(AdbcConnectionSqlExecute(&connection, query.c_str(), &statement, &error),
ADBC_STATUS_OK);
ADBC_ASSERT_ERROR_THAT(
error, ::testing::AllOf(::testing::HasSubstr("[SQLite3] sqlite3_prepare_v2:"),
::testing::HasSubstr("syntax error")));
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementRelease(&statement, &error));
}

TEST_F(DriverManager, SqlPrepare) {
std::string query = "SELECT 1";
AdbcStatement statement;
std::memset(&statement, 0, sizeof(statement));
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementInit(&connection, &statement, &error));
ADBC_ASSERT_OK_WITH_ERROR(
error, AdbcConnectionSqlPrepare(&connection, query.c_str(), &statement, &error));

ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementExecute(&statement, &error));

std::shared_ptr<arrow::Schema> schema;
arrow::RecordBatchVector batches;
ASSERT_NO_FATAL_FAILURE(ReadStatement(&statement, &schema, &batches));
ASSERT_SCHEMA_EQ(*schema, *arrow::schema({arrow::field("1", arrow::int64())}));
EXPECT_THAT(batches,
::testing::UnorderedPointwise(
PointeesEqual(), {
adbc::RecordBatchFromJSON(schema, "[[1]]"),
}));
}

ADBC_ASSERT_OK_WITH_ERROR(&driver, error, AdbcDatabaseRelease(&database, &error));
ASSERT_EQ(database.private_data, nullptr);
TEST_F(DriverManager, SqlPrepareMultipleParams) {
auto param_schema = arrow::schema(
{arrow::field("1", arrow::int64()), arrow::field("2", arrow::utf8())});
std::string query = "SELECT ?, ?";
AdbcStatement statement;
ArrowArray export_params;
ArrowSchema export_schema;
std::memset(&statement, 0, sizeof(statement));

ASSERT_OK(ExportRecordBatch(
*adbc::RecordBatchFromJSON(param_schema, R"([[1, "foo"], [2, "bar"]])"),
&export_params));
ASSERT_OK(ExportSchema(*param_schema, &export_schema));

ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementInit(&connection, &statement, &error));
ADBC_ASSERT_OK_WITH_ERROR(
error, AdbcConnectionSqlPrepare(&connection, query.c_str(), &statement, &error));

ADBC_ASSERT_OK_WITH_ERROR(
error, AdbcStatementBind(&statement, &export_params, &export_schema, &error));
ADBC_ASSERT_OK_WITH_ERROR(error, AdbcStatementExecute(&statement, &error));

std::shared_ptr<arrow::Schema> schema;
arrow::RecordBatchVector batches;
ASSERT_NO_FATAL_FAILURE(ReadStatement(&statement, &schema, &batches));
ASSERT_SCHEMA_EQ(*schema, *arrow::schema({arrow::field("?", arrow::int64()),
arrow::field("?", arrow::utf8())}));
EXPECT_THAT(batches, ::testing::UnorderedPointwise(
PointeesEqual(),
{
adbc::RecordBatchFromJSON(schema, R"([[1, "foo"], [2,
"bar"]])"),
}));
}

} // namespace adbc
41 changes: 41 additions & 0 deletions cmake_modules/AdbcDefines.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 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.

# Common definitions for the CMake projects in this repository.

enable_language(C)
include(DefineOptions)

set(ARROW_VERSION "9.0.0-SNAPSHOT")
set(ARROW_BASE_VERSION "9.0.0")
set(ARROW_VERSION_MAJOR "9")
set(ARROW_VERSION_MINOR "0")
set(ARROW_VERSION_PATCH "0")

math(EXPR ARROW_SO_VERSION "${ARROW_VERSION_MAJOR} * 100 + ${ARROW_VERSION_MINOR}")
set(ARROW_FULL_SO_VERSION "${ARROW_SO_VERSION}.${ARROW_VERSION_PATCH}.0")

if(ARROW_DEPENDENCY_SOURCE STREQUAL "CONDA")
message(STATUS "Adding \$CONDA_PREFIX to CMAKE_PREFIX_PATH")
list(APPEND CMAKE_PREFIX_PATH "$ENV{CONDA_PREFIX}")
endif()

if(ARROW_BUILD_TESTS)
add_custom_target(all-tests)
find_package(GTest)
set(ARROW_TEST_LINK_LIBS GTest::gtest_main GTest::gtest GTest::gmock)
endif()
Loading