Skip to content

Commit

Permalink
Add GDALSetAdbcDriverInitFunc() and use it in OGR ADBC driver
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Oct 16, 2024
1 parent b9ef134 commit 8d86043
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 3 deletions.
3 changes: 3 additions & 0 deletions doc/source/api/vector_c_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ ogr_core.h and ogr_api.h: Vector C API

.. doxygenfile:: ogr_api.h
:project: api

.. doxygenfile:: gdal_adbc.h
:project: api
10 changes: 10 additions & 0 deletions doc/source/drivers/vector/adbc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ It returns for each table a OGR feature with the following fields (some
potentially unset or with an empty string): ``catalog_name``, ``schema_name``,
``table_name``, ``table_type``.

Custom driver entrypoint
------------------------

A custom driver entrypoint can be specified by applications by calling
:cpp:func:`GDALSetAdbcDriverInitFunc` (defined in header :file:`gdal_adbc.h`)
before using the driver. The specified init function will be used by the
GDAL ADBC driver as a way of specifying the ADBC driver for all calls in the
same thread. Setting both the init function and the ``ADBC_DRIVER`` open
option is not supported.

Examples
--------

Expand Down
2 changes: 2 additions & 0 deletions gcore/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# CMake4GDAL project is distributed under MIT license. See accompanying file LICENSE.txt.
add_library(
gcore OBJECT
gdal_adbc.cpp
gdalopeninfo.cpp
gdaldriver.cpp
gdaldrivermanager.cpp
Expand Down Expand Up @@ -194,6 +195,7 @@ target_public_header(
gdalgeorefpamdataset.h
gdal_mdreader.h
gdalsubdatasetinfo.h
gdal_adbc.h
)

set(GDAL_DATA_FILES
Expand Down
62 changes: 62 additions & 0 deletions gcore/gdal_adbc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/******************************************************************************
* Name: gdal_adbc.h
* Project: GDAL Core
* Purpose: GDAL Core ADBC related declarations.
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#include "cpl_port.h"

// Very minimal extract of adbc.h
#define ADBC

CPL_C_START

typedef uint8_t AdbcStatusCode;
struct AdbcError;
typedef AdbcStatusCode (*AdbcDriverInitFunc)(int version, void *driver,
struct AdbcError *error);

CPL_C_END

#include "gdal_adbc.h"

//! Thread local ADBC driver initialization function
static thread_local AdbcDriverInitFunc tlAdbcDriverInitFunc = nullptr;

/************************************************************************/
/* GDALSetAdbcDriverInitFunc() */
/************************************************************************/

/** Sets the ADBC driver initialization function that should be used during
* the next calls to the OGR ADBC driver.
*
* This is a thread-local setting.
*
* When set, it is honored by the OGR ADBC driver to pass the specified
* initialization function as the argument of
* AdbcDriverManagerDatabaseSetInitFunc()
*
* Setting it to NULL resets to the the default behaviour of the ADBC driver,
* which is to honor the ADBC_DRIVER open option.
*/
void GDALSetAdbcDriverInitFunc(AdbcDriverInitFunc init_func)
{
tlAdbcDriverInitFunc = init_func;
}

/************************************************************************/
/* GDALGetAdbcDriverInitFunc() */
/************************************************************************/

/** Gets the ADBC driver initialization function for the current thread.
*/
AdbcDriverInitFunc GDALGetAdbcDriverInitFunc()
{
return tlAdbcDriverInitFunc;
}
41 changes: 41 additions & 0 deletions gcore/gdal_adbc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/******************************************************************************
* Name: gdal_adbc.h
* Project: GDAL Core
* Purpose: GDAL Core ADBC related declarations.
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#ifndef GDAL_ADBC_H_INCLUDED
#define GDAL_ADBC_H_INCLUDED

/**
* \file gdal_adbc.h
*
* C GDAL entry points for Arrow Database Connectivity (ADBC)
*
* This header can only be used if the ADBC macro is defined, indicating that
* the abdc.h header has already been included before.
*
* \since GDAL 3.11
*/

#include "cpl_port.h"

#ifdef ADBC

CPL_C_START

void CPL_DLL GDALSetAdbcDriverInitFunc(AdbcDriverInitFunc init_func);

AdbcDriverInitFunc CPL_DLL GDALGetAdbcDriverInitFunc(void);

CPL_C_END

#endif

#endif
30 changes: 27 additions & 3 deletions ogr/ogrsf_frmts/adbc/ogradbcdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "ogr_mem.h"
#include "ogr_p.h"
#include "cpl_json.h"
#include "gdal_adbc.h"

/************************************************************************/
/* ~OGRADBCDataset() */
Expand Down Expand Up @@ -182,7 +183,28 @@ bool OGRADBCDataset::Open(const GDALOpenInfo *poOpenInfo)
const bool bIsParquet = OGRADBCDriverIsParquet(poOpenInfo) ||
EQUAL(CPLGetExtension(pszFilename), "parquet");
const bool bIsPostgreSQL = STARTS_WITH(pszFilename, "postgresql://");
if (!pszADBCDriverName)

AdbcDriverInitFunc pfnDriverInitFunc = GDALGetAdbcDriverInitFunc();
if (pfnDriverInitFunc && pszADBCDriverName)
{
CPLError(CE_Failure, CPLE_NotSupported,
"Both a AdbcDriverInitFunc and ADBC_DRIVER open option are "
"defined. This is not supported");
return false;
}

if (pfnDriverInitFunc)
{
if (AdbcDriverManagerDatabaseSetInitFunc(&m_database, pfnDriverInitFunc,
error) != ADBC_STATUS_OK)
{
CPLError(CE_Failure, CPLE_AppDefined,
"AdbcDriverManagerDatabaseSetInitFunc() failed: %s",
error.message());
return false;
}
}
else if (!pszADBCDriverName)
{
if (bIsDuckDB || bIsParquet)
{
Expand Down Expand Up @@ -210,15 +232,17 @@ bool OGRADBCDataset::Open(const GDALOpenInfo *poOpenInfo)
}
}

if (AdbcDatabaseSetOption(&m_database, "driver", pszADBCDriverName,
if (pszADBCDriverName &&
AdbcDatabaseSetOption(&m_database, "driver", pszADBCDriverName,
error) != ADBC_STATUS_OK)
{
CPLError(CE_Failure, CPLE_AppDefined,
"AdbcDatabaseSetOption() failed: %s", error.message());
return false;
}

if (bIsDuckDB || bIsParquet || strstr(pszADBCDriverName, "duckdb"))
if (pszADBCDriverName &&
(bIsDuckDB || bIsParquet || strstr(pszADBCDriverName, "duckdb")))
{
if (AdbcDatabaseSetOption(&m_database, "entrypoint", "duckdb_adbc_init",
error) != ADBC_STATUS_OK)
Expand Down

0 comments on commit 8d86043

Please sign in to comment.