LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/sqlite - ogrsqlitedriver.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 134 149 89.9 %
Date: 2024-04-29 12:21:24 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRSQLiteDriver class.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  *
       9             :  * Contributor: Alessandro Furieri, a.furieri@lqt.it
      10             :  * Portions of this module properly supporting SpatiaLite DB creation
      11             :  * Developed for Faunalia ( http://www.faunalia.it) with funding from
      12             :  * Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED AMBIENTALE
      13             :  *
      14             :  ******************************************************************************
      15             :  * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
      16             :  * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
      17             :  *
      18             :  * Permission is hereby granted, free of charge, to any person obtaining a
      19             :  * copy of this software and associated documentation files (the "Software"),
      20             :  * to deal in the Software without restriction, including without limitation
      21             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      22             :  * and/or sell copies of the Software, and to permit persons to whom the
      23             :  * Software is furnished to do so, subject to the following conditions:
      24             :  *
      25             :  * The above copyright notice and this permission notice shall be included
      26             :  * in all copies or substantial portions of the Software.
      27             :  *
      28             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      29             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      30             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      31             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      32             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      33             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      34             :  * DEALINGS IN THE SOFTWARE.
      35             :  ****************************************************************************/
      36             : 
      37             : #include "cpl_port.h"
      38             : #include "ogr_sqlite.h"
      39             : 
      40             : #include <cstring>
      41             : #include <string>
      42             : 
      43             : #include "cpl_conv.h"
      44             : #include "cpl_error.h"
      45             : #include "cpl_string.h"
      46             : #include "cpl_vsi.h"
      47             : #include "gdal.h"
      48             : #include "gdal_priv.h"
      49             : #include "ogr_core.h"
      50             : #include "sqlite3.h"
      51             : 
      52             : /************************************************************************/
      53             : /*                     OGRSQLiteDriverIdentify()                        */
      54             : /************************************************************************/
      55             : 
      56       44036 : static int OGRSQLiteDriverIdentify(GDALOpenInfo *poOpenInfo)
      57             : 
      58             : {
      59       44036 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SQLITE:"))
      60             :     {
      61         152 :         return TRUE;
      62             :     }
      63             : 
      64       87767 :     CPLString osExt(CPLGetExtension(poOpenInfo->pszFilename));
      65       43883 :     if (EQUAL(osExt, "gpkg") && GDALGetDriverByName("GPKG") != nullptr)
      66             :     {
      67        1294 :         return FALSE;
      68             :     }
      69       42589 :     if (EQUAL(osExt, "mbtiles") && GDALGetDriverByName("MBTILES") != nullptr)
      70             :     {
      71         261 :         if (CSLCount(poOpenInfo->papszAllowedDrivers) == 1 &&
      72          74 :             EQUAL(poOpenInfo->papszAllowedDrivers[0], "SQLite"))
      73             :         {
      74          74 :             return TRUE;
      75             :         }
      76         113 :         return FALSE;
      77             :     }
      78             : 
      79       42405 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, "VirtualShape:") &&
      80           2 :         EQUAL(osExt, "shp"))
      81             :     {
      82           2 :         return TRUE;
      83             :     }
      84             : 
      85             : #ifdef HAVE_RASTERLITE2
      86             :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, "RASTERLITE2:"))
      87             :         return poOpenInfo->nOpenFlags & GDAL_OF_RASTER;
      88             : #endif
      89             : 
      90       42401 :     if (EQUAL(poOpenInfo->pszFilename, ":memory:"))
      91          62 :         return TRUE;
      92             : 
      93             : #ifdef SQLITE_OPEN_URI
      94             :     // This code enables support for named memory databases in SQLite.
      95             :     // Named memory databases use file name format
      96             :     //   file:name?mode=memory&cache=shared
      97             :     // SQLITE_USE_URI is checked only to enable backward compatibility, in case
      98             :     // we accidentally hijacked some other format.
      99       42341 :     if (STARTS_WITH(poOpenInfo->pszFilename, "file:") &&
     100           2 :         CPLTestBool(CPLGetConfigOption("SQLITE_USE_URI", "YES")))
     101             :     {
     102           2 :         char *queryparams = strchr(poOpenInfo->pszFilename, '?');
     103           2 :         if (queryparams)
     104             :         {
     105           2 :             if (strstr(queryparams, "mode=memory") != nullptr)
     106           2 :                 return TRUE;
     107             :         }
     108             :     }
     109             : #endif
     110             : 
     111             :     /* -------------------------------------------------------------------- */
     112             :     /*      Verify that the target is a real file, and has an               */
     113             :     /*      appropriate magic string at the beginning.                      */
     114             :     /* -------------------------------------------------------------------- */
     115       42337 :     if (poOpenInfo->nHeaderBytes < 100)
     116       39477 :         return FALSE;
     117             : 
     118             : #ifdef ENABLE_SQL_SQLITE_FORMAT
     119        2860 :     if (STARTS_WITH((const char *)poOpenInfo->pabyHeader, "-- SQL SQLITE"))
     120             :     {
     121           2 :         return TRUE;
     122             :     }
     123        2858 :     if (STARTS_WITH((const char *)poOpenInfo->pabyHeader, "-- SQL RASTERLITE"))
     124             :     {
     125           2 :         return -1;
     126             :     }
     127        2856 :     if (STARTS_WITH((const char *)poOpenInfo->pabyHeader, "-- SQL MBTILES"))
     128             :     {
     129           0 :         if (GDALGetDriverByName("MBTILES") != nullptr)
     130           0 :             return FALSE;
     131           0 :         if (poOpenInfo->eAccess == GA_Update)
     132           0 :             return FALSE;
     133           0 :         return -1;
     134             :     }
     135             : #endif
     136             : 
     137        2856 :     if (!STARTS_WITH((const char *)poOpenInfo->pabyHeader, "SQLite format 3"))
     138        2322 :         return FALSE;
     139             : 
     140             :     // In case we are opening /vsizip/foo.zip with a .gpkg inside
     141        1600 :     if ((memcmp(poOpenInfo->pabyHeader + 68, "GP10", 4) == 0 ||
     142         533 :          memcmp(poOpenInfo->pabyHeader + 68, "GP11", 4) == 0 ||
     143        1076 :          memcmp(poOpenInfo->pabyHeader + 68, "GPKG", 4) == 0) &&
     144          10 :         GDALGetDriverByName("GPKG") != nullptr)
     145             :     {
     146           9 :         return FALSE;
     147             :     }
     148             : 
     149             :     // Could be a Rasterlite or MBTiles file as well
     150         524 :     return -1;
     151             : }
     152             : 
     153             : /************************************************************************/
     154             : /*                                Open()                                */
     155             : /************************************************************************/
     156             : 
     157         399 : static GDALDataset *OGRSQLiteDriverOpen(GDALOpenInfo *poOpenInfo)
     158             : 
     159             : {
     160         399 :     if (OGRSQLiteDriverIdentify(poOpenInfo) == FALSE)
     161           0 :         return nullptr;
     162             : 
     163             :     /* -------------------------------------------------------------------- */
     164             :     /*      Check VirtualShape:xxx.shp syntax                               */
     165             :     /* -------------------------------------------------------------------- */
     166         399 :     int nLen = (int)strlen(poOpenInfo->pszFilename);
     167         399 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, "VirtualShape:") && nLen > 4 &&
     168           1 :         EQUAL(poOpenInfo->pszFilename + nLen - 4, ".SHP"))
     169             :     {
     170           1 :         OGRSQLiteDataSource *poDS = new OGRSQLiteDataSource();
     171             : 
     172           1 :         char **papszOptions = CSLAddString(nullptr, "SPATIALITE=YES");
     173           1 :         int nRet = poDS->Create(":memory:", papszOptions);
     174           1 :         poDS->SetDescription(poOpenInfo->pszFilename);
     175           1 :         CSLDestroy(papszOptions);
     176           1 :         if (!nRet)
     177             :         {
     178           0 :             delete poDS;
     179           0 :             return nullptr;
     180             :         }
     181             : 
     182             :         char *pszSQLiteFilename =
     183           1 :             CPLStrdup(poOpenInfo->pszFilename + strlen("VirtualShape:"));
     184           1 :         GDALDataset *poSQLiteDS = (GDALDataset *)GDALOpenEx(
     185             :             pszSQLiteFilename, GDAL_OF_VECTOR, nullptr, nullptr, nullptr);
     186           1 :         if (poSQLiteDS == nullptr)
     187             :         {
     188           0 :             CPLFree(pszSQLiteFilename);
     189           0 :             delete poDS;
     190           0 :             return nullptr;
     191             :         }
     192           1 :         delete poSQLiteDS;
     193             : 
     194           1 :         char *pszLastDot = strrchr(pszSQLiteFilename, '.');
     195           1 :         if (pszLastDot)
     196           1 :             *pszLastDot = '\0';
     197             : 
     198           1 :         const char *pszTableName = CPLGetBasename(pszSQLiteFilename);
     199             : 
     200           1 :         char *pszSQL = CPLStrdup(CPLSPrintf(
     201             :             "CREATE VIRTUAL TABLE %s USING VirtualShape(%s, CP1252, -1)",
     202             :             pszTableName, pszSQLiteFilename));
     203           1 :         poDS->ExecuteSQL(pszSQL, nullptr, nullptr);
     204           1 :         CPLFree(pszSQL);
     205           1 :         CPLFree(pszSQLiteFilename);
     206           1 :         poDS->DisableUpdate();
     207           1 :         return poDS;
     208             :     }
     209             : 
     210             :     /* -------------------------------------------------------------------- */
     211             :     /*      We think this is really an SQLite database, go ahead and try    */
     212             :     /*      and open it.                                                    */
     213             :     /* -------------------------------------------------------------------- */
     214         398 :     OGRSQLiteDataSource *poDS = new OGRSQLiteDataSource();
     215             : 
     216         398 :     if (!poDS->Open(poOpenInfo))
     217             :     {
     218           1 :         delete poDS;
     219           1 :         return nullptr;
     220             :     }
     221             :     else
     222         397 :         return poDS;
     223             : }
     224             : 
     225             : /************************************************************************/
     226             : /*                               Create()                               */
     227             : /************************************************************************/
     228             : 
     229         225 : static GDALDataset *OGRSQLiteDriverCreate(const char *pszName, int nBands,
     230             :                                           CPL_UNUSED int nXSize,
     231             :                                           CPL_UNUSED int nYSize,
     232             :                                           CPL_UNUSED GDALDataType eDT,
     233             :                                           char **papszOptions)
     234             : {
     235         225 :     if (nBands != 0)
     236             :     {
     237           0 :         CPLError(CE_Failure, CPLE_NotSupported,
     238             :                  "Raster creation through Create() interface is not supported. "
     239             :                  "Only CreateCopy() is supported");
     240           0 :         return nullptr;
     241             :     }
     242             : 
     243             :     /* -------------------------------------------------------------------- */
     244             :     /*      First, ensure there isn't any such file yet.                    */
     245             :     /* -------------------------------------------------------------------- */
     246             :     VSIStatBufL sStatBuf;
     247             : 
     248         225 :     if (VSIStatL(pszName, &sStatBuf) == 0)
     249             :     {
     250           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     251             :                  "It seems a file system object called '%s' already exists.",
     252             :                  pszName);
     253             : 
     254           0 :         return nullptr;
     255             :     }
     256             : 
     257             :     /* -------------------------------------------------------------------- */
     258             :     /*      Try to create datasource.                                       */
     259             :     /* -------------------------------------------------------------------- */
     260         225 :     OGRSQLiteDataSource *poDS = new OGRSQLiteDataSource();
     261             : 
     262         225 :     if (!poDS->Create(pszName, papszOptions))
     263             :     {
     264           5 :         delete poDS;
     265           5 :         return nullptr;
     266             :     }
     267             : 
     268         220 :     return poDS;
     269             : }
     270             : 
     271             : /************************************************************************/
     272             : /*                             Delete()                                 */
     273             : /************************************************************************/
     274             : 
     275          86 : static CPLErr OGRSQLiteDriverDelete(const char *pszName)
     276             : {
     277          86 :     if (VSIUnlink(pszName) == 0)
     278          64 :         return CE_None;
     279             :     else
     280          22 :         return CE_Failure;
     281             : }
     282             : 
     283             : /************************************************************************/
     284             : /*                         RegisterOGRSQLite()                          */
     285             : /************************************************************************/
     286             : 
     287        1512 : void RegisterOGRSQLite()
     288             : 
     289             : {
     290        1512 :     if (!GDAL_CHECK_VERSION("SQLite driver"))
     291         295 :         return;
     292             : 
     293        1512 :     if (GDALGetDriverByName("SQLite") != nullptr)
     294         295 :         return;
     295             : 
     296        1217 :     GDALDriver *poDriver = new GDALDriver();
     297             : 
     298        1217 :     poDriver->SetDescription("SQLite");
     299        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     300        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     301        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_DELETE_LAYER, "YES");
     302        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     303        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_DELETE_FIELD, "YES");
     304        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_REORDER_FIELDS, "YES");
     305        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_CURVE_GEOMETRIES, "YES");
     306        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_MEASURED_GEOMETRIES, "YES");
     307        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
     308        1217 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "SQLITE OGRSQL");
     309             : 
     310             : #ifdef HAVE_RASTERLITE2
     311             :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     312             :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     313             :                               "SQLite / Spatialite / RasterLite2");
     314             : #else
     315        1217 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "SQLite / Spatialite");
     316             : #endif
     317        1217 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/sqlite.html");
     318        1217 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "sqlite db");
     319             : 
     320        1217 :     poDriver->SetMetadataItem(
     321             :         GDAL_DMD_OPENOPTIONLIST,
     322             :         "<OpenOptionList>"
     323             :         "  <Option name='LIST_ALL_TABLES' type='boolean' description='Whether "
     324             :         "all tables, including non-spatial ones, should be listed' "
     325             :         "default='NO'/>"
     326             :         "  <Option name='LIST_VIRTUAL_OGR' type='boolean' description='Whether "
     327             :         "VirtualOGR virtual tables should be listed. Should only be enabled on "
     328             :         "trusted datasources to avoid potential safety issues' default='NO'/>"
     329             :         "  <Option name='PRELUDE_STATEMENTS' type='string' description='SQL "
     330             :         "statement(s) to send on the SQLite connection before any other ones'/>"
     331             : #ifdef HAVE_RASTERLITE2
     332             :         "  <Option name='1BIT_AS_8BIT' type='boolean' scope='raster' "
     333             :         "description='Whether to promote 1-bit monochrome raster as 8-bit, so "
     334             :         "as to have higher quality overviews' default='YES'/>"
     335             : #endif
     336        1217 :         "</OpenOptionList>");
     337             : 
     338             :     CPLString osCreationOptions(
     339             :         "<CreationOptionList>"
     340             : #ifdef HAVE_SPATIALITE
     341             :         "  <Option name='SPATIALITE' type='boolean' description='Whether to "
     342             :         "create a Spatialite database' default='NO'/>"
     343             : #endif
     344             :         "  <Option name='METADATA' type='boolean' description='Whether to "
     345             :         "create the geometry_columns and spatial_ref_sys tables' "
     346             :         "default='YES'/>"
     347             :         "  <Option name='INIT_WITH_EPSG' type='boolean' description='Whether "
     348             :         "to insert the content of the EPSG CSV files into the spatial_ref_sys "
     349             :         "table ' default='NO'/>"
     350             : #ifdef HAVE_RASTERLITE2
     351             :         "  <Option name='APPEND_SUBDATASET' scope='raster' type='boolean' "
     352             :         "description='Whether to add the raster to the existing file' "
     353             :         "default='NO'/>"
     354             :         "  <Option name='COVERAGE' scope='raster' type='string' "
     355             :         "description='Coverage name'/>"
     356             :         "  <Option name='SECTION' scope='raster' type='string' "
     357             :         "description='Section name'/>"
     358             :         "  <Option name='COMPRESS' scope='raster' type='string-select' "
     359             :         "description='Raster compression' default='NONE'>"
     360             :         "    <Value>NONE</Value>"
     361             : #endif
     362        2434 :     );
     363             : #ifdef HAVE_RASTERLITE2
     364             :     if (rl2_is_supported_codec(RL2_COMPRESSION_DEFLATE))
     365             :         osCreationOptions += "    <Value>DEFLATE</Value>";
     366             :     if (rl2_is_supported_codec(RL2_COMPRESSION_LZMA))
     367             :         osCreationOptions += "    <Value>LZMA</Value>";
     368             :     if (rl2_is_supported_codec(RL2_COMPRESSION_PNG))
     369             :         osCreationOptions += "    <Value>PNG</Value>";
     370             :     if (rl2_is_supported_codec(RL2_COMPRESSION_CCITTFAX4))
     371             :         osCreationOptions += "    <Value>CCITTFAX4</Value>";
     372             :     if (rl2_is_supported_codec(RL2_COMPRESSION_JPEG))
     373             :         osCreationOptions += "    <Value>JPEG</Value>";
     374             :     if (rl2_is_supported_codec(RL2_COMPRESSION_LOSSY_WEBP))
     375             :         osCreationOptions += "    <Value>WEBP</Value>";
     376             :     if (rl2_is_supported_codec(RL2_COMPRESSION_LOSSY_JP2))
     377             :         osCreationOptions += "    <Value>JPEG2000</Value>";
     378             : #endif
     379             :     osCreationOptions +=
     380             : #ifdef HAVE_RASTERLITE2
     381             :         "  </Option>"
     382             :         "  <Option name='QUALITY' scope='raster' type='int' description='Image "
     383             :         "quality for JPEG, WEBP and JPEG2000 compressions'/>"
     384             :         "  <Option name='PIXEL_TYPE' scope='raster' type='string-select' "
     385             :         "description='Raster pixel type. Determines photometric "
     386             :         "interpretation'>"
     387             :         "    <Value>MONOCHROME</Value>"
     388             :         "    <Value>PALETTE</Value>"
     389             :         "    <Value>GRAYSCALE</Value>"
     390             :         "    <Value>RGB</Value>"
     391             :         "    <Value>MULTIBAND</Value>"
     392             :         "    <Value>DATAGRID</Value>"
     393             :         "  </Option>"
     394             :         "  <Option name='BLOCKXSIZE' scope='raster' type='int' "
     395             :         "description='Block width' default='512'/>"
     396             :         "  <Option name='BLOCKYSIZE' scope='raster' type='int' "
     397             :         "description='Block height' default='512'/>"
     398             :         "  <Option name='NBITS' scope='raster' type='int' description='Force "
     399             :         "bit width. 1, 2 or 4 are supported'/>"
     400             :         "  <Option name='PYRAMIDIZE' scope='raster' type='boolean' "
     401             :         "description='Whether to automatically build relevant "
     402             :         "pyramids/overviews' default='NO'/>"
     403             : #endif
     404        1217 :         "</CreationOptionList>";
     405             : 
     406        1217 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONOPTIONLIST, osCreationOptions);
     407             : 
     408        1217 :     poDriver->SetMetadataItem(
     409             :         GDAL_DS_LAYER_CREATIONOPTIONLIST,
     410             :         "<LayerCreationOptionList>"
     411             :         "  <Option name='FORMAT' type='string-select' description='Format of "
     412             :         "geometry columns'>"
     413             :         "    <Value>WKB</Value>"
     414             :         "    <Value>WKT</Value>"
     415             : #ifdef HAVE_SPATIALITE
     416             :         "    <Value>SPATIALITE</Value>"
     417             : #endif
     418             :         "  </Option>"
     419             :         "  <Option name='GEOMETRY_NAME' type='string' description='Name of "
     420             :         "geometry column. Defaults to WKT_GEOMETRY for FORMAT=WKT or GEOMETRY "
     421             :         "otherwise'/>"
     422             :         "  <Option name='LAUNDER' type='boolean' description='Whether layer "
     423             :         "and field names will be laundered' default='YES'/>"
     424             : #ifdef HAVE_SPATIALITE
     425             :         "  <Option name='SPATIAL_INDEX' type='boolean' description='Whether to "
     426             :         "create a spatial index for Spatialite databases' default='YES'/>"
     427             :         "  <Option name='COMPRESS_GEOM' type='boolean' description='Whether to "
     428             :         "use compressed format of Spatialite geometries' default='NO'/>"
     429             : #endif
     430             :         "  <Option name='SRID' type='int' description='Forced SRID of the "
     431             :         "layer'/>"
     432             :         "  <Option name='COMPRESS_COLUMNS' type='string' "
     433             :         "description='=column_name1[,column_name2, ...].  list of (String) "
     434             :         "columns that must be compressed with ZLib DEFLATE algorithm'/>"
     435             :         "  <Option name='OVERWRITE' type='boolean' description='Whether to "
     436             :         "overwrite an existing table with the layer name to be created' "
     437             :         "default='NO'/>"
     438             :         "  <Option name='FID' type='string' description='Name of the FID "
     439             :         "column to create' default='OGC_FID'/>"
     440             : #if SQLITE_VERSION_NUMBER >= 3037000
     441             :         "  <Option name='STRICT' type='boolean' description='Whether to create "
     442             :         "the table in STRICT mode (only compatible of readers with sqlite >= "
     443             :         "3.37)' default='NO'/>"
     444             : #endif
     445        1217 :         "</LayerCreationOptionList>");
     446             : 
     447        1217 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     448             :                               "Integer Integer64 Real String Date DateTime "
     449             :                               "Time Binary IntegerList Integer64List "
     450        1217 :                               "RealList StringList");
     451        1217 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATASUBTYPES,
     452        1217 :                               "Boolean Int16 Float32");
     453        1217 :     poDriver->SetMetadataItem(GDAL_DMD_CREATION_FIELD_DEFN_FLAGS,
     454        1217 :                               "WidthPrecision Nullable Default Unique");
     455        1217 :     poDriver->SetMetadataItem(
     456             :         GDAL_DMD_ALTER_FIELD_DEFN_FLAGS,
     457        1217 :         "Name Type WidthPrecision Nullable Default Unique");
     458             : 
     459             : #ifdef HAVE_RASTERLITE2
     460             :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES,
     461             :                               "Byte Int8 UInt16 Int16 UInt32 Int32 Float32 "
     462             :                               "Float64");
     463             : #endif
     464        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_NOTNULL_FIELDS, "YES");
     465        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_DEFAULT_FIELDS, "YES");
     466        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_UNIQUE_FIELDS, "YES");
     467        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_NOTNULL_GEOMFIELDS, "YES");
     468        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     469        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES");
     470        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_RELATIONSHIPS, "YES");
     471        1217 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_RELATIONSHIP, "YES");
     472        1217 :     poDriver->SetMetadataItem(GDAL_DMD_RELATIONSHIP_FLAGS,
     473        1217 :                               "OneToMany Association Composite");
     474        1217 :     poDriver->SetMetadataItem(GDAL_DMD_RELATIONSHIP_RELATED_TABLE_TYPES,
     475        1217 :                               "features");
     476             : 
     477             : #ifdef ENABLE_SQL_SQLITE_FORMAT
     478        1217 :     poDriver->SetMetadataItem("ENABLE_SQL_SQLITE_FORMAT", "YES");
     479             : #endif
     480             : #ifdef SQLITE_HAS_COLUMN_METADATA
     481        1217 :     poDriver->SetMetadataItem("SQLITE_HAS_COLUMN_METADATA", "YES");
     482             : #endif
     483             : 
     484        1217 :     poDriver->pfnOpen = OGRSQLiteDriverOpen;
     485        1217 :     poDriver->pfnIdentify = OGRSQLiteDriverIdentify;
     486        1217 :     poDriver->pfnCreate = OGRSQLiteDriverCreate;
     487             : #ifdef HAVE_RASTERLITE2
     488             :     poDriver->pfnCreateCopy = OGRSQLiteDriverCreateCopy;
     489             : #endif
     490        1217 :     poDriver->pfnDelete = OGRSQLiteDriverDelete;
     491        1217 :     poDriver->pfnUnloadDriver = OGRSQLiteDriverUnload;
     492             : 
     493        1217 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     494             : }

Generated by: LCOV version 1.14