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 "ogrsf_frmts.h" 14 : #include "ogradbcdrivercore.h" 15 : #include "gdal_adbc.h" 16 : 17 : /************************************************************************/ 18 : /* IsDuckDB() */ 19 : /************************************************************************/ 20 : 21 48443 : bool OGRADBCDriverIsDuckDB(const GDALOpenInfo *poOpenInfo) 22 : { 23 49371 : return poOpenInfo->nHeaderBytes >= 20 && 24 928 : memcmp(poOpenInfo->pabyHeader + 8, "DUCK\x40\0\0\0\0\0\0\0", 25 48443 : 4 + 8) == 0; 26 : } 27 : 28 : /************************************************************************/ 29 : /* IsSQLite3() */ 30 : /************************************************************************/ 31 : 32 48443 : bool OGRADBCDriverIsSQLite3(const GDALOpenInfo *poOpenInfo) 33 : { 34 48443 : constexpr const char *SQLITE3_SIGNATURE = "SQLite format 3"; 35 49017 : return poOpenInfo->nHeaderBytes >= 512 && 36 574 : memcmp(poOpenInfo->pabyHeader, SQLITE3_SIGNATURE, 37 48443 : strlen(SQLITE3_SIGNATURE)) == 0; 38 : } 39 : 40 : /************************************************************************/ 41 : /* IsParquet() */ 42 : /************************************************************************/ 43 : 44 48443 : bool OGRADBCDriverIsParquet(const GDALOpenInfo *poOpenInfo) 45 : { 46 48443 : constexpr const char *PARQUET_SIGNATURE = "PAR1"; 47 48443 : return poOpenInfo->nHeaderBytes >= 48 49430 : static_cast<int>(strlen(PARQUET_SIGNATURE)) && 49 987 : memcmp(poOpenInfo->pabyHeader, PARQUET_SIGNATURE, 50 48443 : strlen(PARQUET_SIGNATURE)) == 0; 51 : } 52 : 53 : /************************************************************************/ 54 : /* OGRADBCDriverIdentify() */ 55 : /************************************************************************/ 56 : 57 48443 : int OGRADBCDriverIdentify(GDALOpenInfo *poOpenInfo) 58 : { 59 145329 : return STARTS_WITH(poOpenInfo->pszFilename, "ADBC:") || 60 96886 : ((OGRADBCDriverIsDuckDB(poOpenInfo) || 61 48443 : (OGRADBCDriverIsSQLite3(poOpenInfo) && 62 40 : ((!poOpenInfo->IsExtensionEqualToCI("gpkg") && 63 2 : (GDALGetDriverByName("SQLite") == nullptr || 64 42 : poOpenInfo->IsSingleAllowedDriver("ADBC"))) || 65 40 : (poOpenInfo->IsExtensionEqualToCI("gpkg") && 66 38 : (GDALGetDriverByName("GPKG") == nullptr || 67 48481 : poOpenInfo->IsSingleAllowedDriver("ADBC"))))) || 68 48443 : OGRADBCDriverIsParquet(poOpenInfo)) 69 : #ifndef OGR_ADBC_HAS_DRIVER_MANAGER 70 0 : && GDALGetAdbcLoadDriverOverride() != nullptr 71 : #endif 72 0 : && !STARTS_WITH(poOpenInfo->pszFilename, "/vsi") && 73 48443 : !poOpenInfo->IsExtensionEqualToCI("mbtiles")); 74 : } 75 : 76 : /************************************************************************/ 77 : /* OGRADBCDriverSetCommonMetadata() */ 78 : /************************************************************************/ 79 : 80 1617 : void OGRADBCDriverSetCommonMetadata(GDALDriver *poDriver) 81 : { 82 1617 : poDriver->SetDescription(DRIVER_NAME); 83 1617 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 84 1617 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Arrow Database Connectivity"); 85 1617 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/adbc.html"); 86 : 87 1617 : poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "ADBC:"); 88 : 89 1617 : poDriver->SetMetadataItem( 90 : GDAL_DMD_OPENOPTIONLIST, 91 : "<OpenOptionList>" 92 : " <Option name='ADBC_DRIVER' type='string' description='ADBC driver " 93 : "name'/>" 94 : " <Option name='SQL' type='string' " 95 : "description='SQL statement from which to build layer'/>" 96 : " <Option name='ADBC_OPTION_*' type='string' " 97 : "description='Option to pass to AdbcDatabaseSetOption()'/>" 98 : " <Option name='PRELUDE_STATEMENTS' type='string' description='SQL " 99 : "statement(s) to send on the database connection before any other " 100 : "ones'/>" 101 1617 : "</OpenOptionList>"); 102 1617 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, 103 1617 : "NATIVE OGRSQL SQLITE"); 104 : #ifdef OGR_ADBC_HAS_DRIVER_MANAGER 105 : poDriver->SetMetadataItem("HAS_ADBC_DRIVER_MANAGER", "YES"); 106 : #endif 107 : 108 1617 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 109 1617 : poDriver->pfnIdentify = OGRADBCDriverIdentify; 110 1617 : } 111 : 112 : /************************************************************************/ 113 : /* DeclareDeferredOGRADBCPlugin() */ 114 : /************************************************************************/ 115 : 116 : #ifdef PLUGIN_FILENAME 117 1889 : void DeclareDeferredOGRADBCPlugin() 118 : { 119 1889 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 120 : { 121 282 : return; 122 : } 123 1607 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 124 : #ifdef PLUGIN_INSTALLATION_MESSAGE 125 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 126 : PLUGIN_INSTALLATION_MESSAGE); 127 : #endif 128 1607 : OGRADBCDriverSetCommonMetadata(poDriver); 129 1607 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 130 : } 131 : #endif