LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/adbc - ogradbcdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 52 92.3 %
Date: 2025-10-01 17:07:58 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Arrow Database Connectivity driver
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdal_frmts.h"
      14             : #include "gdalplugindriverproxy.h"
      15             : 
      16             : #include "ogrsf_frmts.h"
      17             : #include "ogradbcdrivercore.h"
      18             : #include "gdal_adbc.h"
      19             : 
      20             : /************************************************************************/
      21             : /*                             IsDuckDB()                               */
      22             : /************************************************************************/
      23             : 
      24       18313 : bool OGRADBCDriverIsDuckDB(const GDALOpenInfo *poOpenInfo)
      25             : {
      26       18813 :     return poOpenInfo->nHeaderBytes >= 20 &&
      27         500 :            memcmp(poOpenInfo->pabyHeader + 8, "DUCK\x40\0\0\0\0\0\0\0",
      28       18313 :                   4 + 8) == 0;
      29             : }
      30             : 
      31             : /************************************************************************/
      32             : /*                             IsSQLite3()                              */
      33             : /************************************************************************/
      34             : 
      35       18306 : bool OGRADBCDriverIsSQLite3(const GDALOpenInfo *poOpenInfo)
      36             : {
      37       18306 :     constexpr const char *SQLITE3_SIGNATURE = "SQLite format 3";
      38       18670 :     return poOpenInfo->nHeaderBytes >= 512 &&
      39         364 :            memcmp(poOpenInfo->pabyHeader, SQLITE3_SIGNATURE,
      40       18306 :                   strlen(SQLITE3_SIGNATURE)) == 0;
      41             : }
      42             : 
      43             : /************************************************************************/
      44             : /*                             IsParquet()                              */
      45             : /************************************************************************/
      46             : 
      47       18313 : bool OGRADBCDriverIsParquet(const GDALOpenInfo *poOpenInfo)
      48             : {
      49       18313 :     constexpr const char *PARQUET_SIGNATURE = "PAR1";
      50       18313 :     return poOpenInfo->nHeaderBytes >=
      51       18838 :                static_cast<int>(strlen(PARQUET_SIGNATURE)) &&
      52         525 :            memcmp(poOpenInfo->pabyHeader, PARQUET_SIGNATURE,
      53       18313 :                   strlen(PARQUET_SIGNATURE)) == 0;
      54             : }
      55             : 
      56             : /************************************************************************/
      57             : /*                    OGRADBCDriverIdentify()                           */
      58             : /************************************************************************/
      59             : 
      60       50128 : int OGRADBCDriverIdentify(GDALOpenInfo *poOpenInfo)
      61             : {
      62       50128 :     if (STARTS_WITH(poOpenInfo->pszFilename, "ADBC:"))
      63           2 :         return true;
      64             : 
      65       50126 :     if (STARTS_WITH(poOpenInfo->pszFilename, "/vsi"))
      66       31814 :         return false;
      67             : 
      68       18312 :     if (OGRADBCDriverIsDuckDB(poOpenInfo) || OGRADBCDriverIsParquet(poOpenInfo))
      69             :     {
      70             : #ifdef OGR_ADBC_HAS_DRIVER_MANAGER
      71             :         return true;
      72             : #else
      73           0 :         const char *pszADBCDriverName =
      74             : #ifdef _WIN32
      75             :             "duckdb.dll"
      76             : #elif defined(__MACH__) && defined(__APPLE__)
      77             :             "libduckdb.dylib"
      78             : #else
      79             :             "libduckdb.so"
      80             : #endif
      81             :             ;
      82           0 :         return (GDALGetAdbcLoadDriverOverride() != nullptr ||
      83           0 :                 CPLGetSymbol(pszADBCDriverName, "duckdb_adbc_init") != nullptr);
      84             : #endif
      85             :     }
      86             :     else
      87             :     {
      88       36617 :         return !poOpenInfo->IsExtensionEqualToCI("mbtiles") &&
      89       18305 :                (OGRADBCDriverIsSQLite3(poOpenInfo) &&
      90           1 :                 ((!poOpenInfo->IsExtensionEqualToCI("gpkg") &&
      91           0 :                   (GDALGetDriverByName("SQLite") == nullptr ||
      92           1 :                    poOpenInfo->IsSingleAllowedDriver("ADBC"))) ||
      93           1 :                  (poOpenInfo->IsExtensionEqualToCI("gpkg") &&
      94           1 :                   (GDALGetDriverByName("GPKG") == nullptr ||
      95           1 :                    poOpenInfo->IsSingleAllowedDriver("ADBC")))))
      96             : #ifndef OGR_ADBC_HAS_DRIVER_MANAGER
      97       36617 :                && GDALGetAdbcLoadDriverOverride() != nullptr
      98             : #endif
      99             :             ;
     100             :     }
     101             : }
     102             : 
     103             : /************************************************************************/
     104             : /*                  OGRADBCDriverSetCommonMetadata()                    */
     105             : /************************************************************************/
     106             : 
     107        2104 : void OGRADBCDriverSetCommonMetadata(GDALDriver *poDriver)
     108             : {
     109        2104 :     poDriver->SetDescription(DRIVER_NAME);
     110        2104 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     111        2104 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Arrow Database Connectivity");
     112        2104 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/adbc.html");
     113             : 
     114        2104 :     poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "ADBC:");
     115             : 
     116        2104 :     poDriver->SetMetadataItem(
     117             :         GDAL_DMD_OPENOPTIONLIST,
     118             :         "<OpenOptionList>"
     119             :         "  <Option name='ADBC_DRIVER' type='string' description='ADBC driver "
     120             :         "name'/>"
     121             :         "  <Option name='SQL' type='string' "
     122             :         "description='SQL statement from which to build layer'/>"
     123             :         "  <Option name='ADBC_OPTION_*' type='string' "
     124             :         "description='Option to pass to AdbcDatabaseSetOption()'/>"
     125             :         "  <Option name='PRELUDE_STATEMENTS' type='string' description='SQL "
     126             :         "statement(s) to send on the database connection before any other "
     127             :         "ones'/>"
     128             : #ifdef OGR_ADBC_HAS_DRIVER_MANAGER
     129             :         "  <Option name='BIGQUERY_PROJECT_ID' type='string' "
     130             :         "description='Google Project ID'/>"
     131             :         "  <Option name='BIGQUERY_DATASET_ID' type='string' "
     132             :         "description='Google BigQuery dataset ID'/>"
     133             :         "  <Option name='BIGQUERY_JSON_CREDENTIAL_STRING' type='string' "
     134             :         "description='JSON string containing Google credentials'/>"
     135             :         "  <Option name='BIGQUERY_JSON_CREDENTIAL_FILE' type='string' "
     136             :         "description='Filename containing Google credentials'/>"
     137             : #endif
     138        2104 :         "</OpenOptionList>");
     139        2104 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS,
     140        2104 :                               "NATIVE OGRSQL SQLITE");
     141             : #ifdef OGR_ADBC_HAS_DRIVER_MANAGER
     142             :     poDriver->SetMetadataItem("HAS_ADBC_DRIVER_MANAGER", "YES");
     143             : 
     144             :     // For BigQuery
     145             :     poDriver->SetMetadataItem(
     146             :         GDAL_DS_LAYER_CREATIONOPTIONLIST,
     147             :         "<LayerCreationOptionList>"
     148             :         "<Option name='FID' type='string' "
     149             :         "description='Name of the FID column to create' default='ogc_fid'/>"
     150             :         "</LayerCreationOptionList>");
     151             :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     152             :     poDriver->SetMetadataItem(GDAL_DCAP_DELETE_LAYER, "YES");
     153             :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     154             :     poDriver->SetMetadataItem(
     155             :         GDAL_DMD_CREATIONFIELDDATATYPES,
     156             :         "Integer Integer64 Real String Date Time DateTime Binary StringList "
     157             :         "IntegerList Integer64List RealList");
     158             :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATASUBTYPES,
     159             :                               "Boolean JSON");
     160             :     poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES");
     161             :     poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS, "Features");
     162             : #endif
     163             : 
     164        2104 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     165        2104 :     poDriver->pfnIdentify = OGRADBCDriverIdentify;
     166        2104 : }
     167             : 
     168             : /************************************************************************/
     169             : /*                   DeclareDeferredOGRADBCPlugin()                     */
     170             : /************************************************************************/
     171             : 
     172             : #ifdef PLUGIN_FILENAME
     173        2033 : void DeclareDeferredOGRADBCPlugin()
     174             : {
     175        2033 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     176             :     {
     177         283 :         return;
     178             :     }
     179        1750 :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     180             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     181             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     182             :                               PLUGIN_INSTALLATION_MESSAGE);
     183             : #endif
     184        1750 :     OGRADBCDriverSetCommonMetadata(poDriver);
     185        1750 :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     186             : }
     187             : #endif

Generated by: LCOV version 1.14