1 /******************************************************************************
2 *
3 * Project: OpenGIS Simple Features Reference Implementation
4 * Purpose: Implements OGRPGDriver class.
5 * Author: Frank Warmerdam, warmerdam@pobox.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2000, Frank Warmerdam
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "ogr_pg.h"
30 #include "cpl_conv.h"
31
32 CPL_CVSID("$Id: ogrpgdriver.cpp 1761acd90777d5bcc49eddbc13c193098f0ed40b 2020-10-01 12:12:00 +0200 Even Rouault $")
33
34 /************************************************************************/
35 /* Identify() */
36 /************************************************************************/
37
OGRPGDriverIdentify(GDALOpenInfo * poOpenInfo)38 static int OGRPGDriverIdentify( GDALOpenInfo* poOpenInfo )
39 {
40 if( !STARTS_WITH_CI(poOpenInfo->pszFilename, "PGB:") &&
41 !STARTS_WITH_CI(poOpenInfo->pszFilename, "PG:") )
42 return FALSE;
43 return TRUE;
44 }
45
46 /************************************************************************/
47 /* Open() */
48 /************************************************************************/
49
OGRPGDriverOpen(GDALOpenInfo * poOpenInfo)50 static GDALDataset *OGRPGDriverOpen( GDALOpenInfo* poOpenInfo )
51
52 {
53 if( !OGRPGDriverIdentify(poOpenInfo) )
54 return nullptr;
55
56 OGRPGDataSource *poDS = new OGRPGDataSource();
57
58 if( !poDS->Open( poOpenInfo->pszFilename,
59 poOpenInfo->eAccess == GA_Update, TRUE,
60 poOpenInfo->papszOpenOptions ) )
61 {
62 delete poDS;
63 return nullptr;
64 }
65 else
66 return poDS;
67 }
68
69 /************************************************************************/
70 /* CreateDataSource() */
71 /************************************************************************/
72
OGRPGDriverCreate(const char * pszName,CPL_UNUSED int nBands,CPL_UNUSED int nXSize,CPL_UNUSED int nYSize,CPL_UNUSED GDALDataType eDT,char ** papszOptions)73 static GDALDataset *OGRPGDriverCreate( const char * pszName,
74 CPL_UNUSED int nBands,
75 CPL_UNUSED int nXSize,
76 CPL_UNUSED int nYSize,
77 CPL_UNUSED GDALDataType eDT,
78 char **papszOptions )
79
80 {
81 OGRPGDataSource *poDS = new OGRPGDataSource();
82
83 if( !poDS->Open( pszName, TRUE, TRUE, papszOptions ) )
84 {
85 delete poDS;
86 CPLError( CE_Failure, CPLE_AppDefined,
87 "PostgreSQL driver doesn't currently support database creation.\n"
88 "Please create database with the `createdb' command." );
89 return nullptr;
90 }
91
92 return poDS;
93 }
94
95 /************************************************************************/
96 /* RegisterOGRPG() */
97 /************************************************************************/
98
RegisterOGRPG()99 void RegisterOGRPG()
100
101 {
102 if (! GDAL_CHECK_VERSION("PG driver"))
103 return;
104
105 if( GDALGetDriverByName( "PostgreSQL" ) != nullptr )
106 return;
107
108 GDALDriver* poDriver = new GDALDriver();
109
110 poDriver->SetDescription( "PostgreSQL" );
111 poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "PostgreSQL/PostGIS" );
112 poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
113 poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drivers/vector/pg.html" );
114 poDriver->SetMetadataItem( GDAL_DMD_CONNECTION_PREFIX, "PG:" );
115
116 poDriver->SetMetadataItem( GDAL_DMD_OPENOPTIONLIST,
117 "<OpenOptionList>"
118 " <Option name='DBNAME' type='string' description='Database name'/>"
119 " <Option name='PORT' type='int' description='Port'/>"
120 " <Option name='USER' type='string' description='User name'/>"
121 " <Option name='PASSWORD' type='string' description='Password'/>"
122 " <Option name='HOST' type='string' description='Server hostname'/>"
123 " <Option name='SERVICE' type='string' description='Service name'/>"
124 " <Option name='ACTIVE_SCHEMA' type='string' description='Active schema'/>"
125 " <Option name='SCHEMAS' type='string' description='Restricted sets of schemas to explore (comma separated)'/>"
126 " <Option name='TABLES' type='string' description='Restricted set of tables to list (comma separated)'/>"
127 " <Option name='LIST_ALL_TABLES' type='boolean' description='Whether all tables, including non-spatial ones, should be listed' default='NO'/>"
128 " <Option name='PRELUDE_STATEMENTS' type='string' description='SQL statement(s) to send on the PostgreSQL client connection before any other ones'/>"
129 " <Option name='CLOSING_STATEMENTS' type='string' description='SQL statements() to send on the PostgreSQL client connection after any other ones'/>"
130 "</OpenOptionList>");
131
132 poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
133 "<CreationOptionList/>");
134
135 poDriver->SetMetadataItem( GDAL_DS_LAYER_CREATIONOPTIONLIST,
136 "<LayerCreationOptionList>"
137 " <Option name='GEOM_TYPE' type='string-select' description='Format of geometry columns' default='geometry'>"
138 " <Value>geometry</Value>"
139 " <Value>geography</Value>"
140 " <Value>BYTEA</Value>"
141 " <Value>OID</Value>"
142 " </Option>"
143 " <Option name='OVERWRITE' type='boolean' description='Whether to overwrite an existing table with the layer name to be created' default='NO'/>"
144 " <Option name='LAUNDER' type='boolean' description='Whether layer and field names will be laundered' default='YES'/>"
145 " <Option name='PRECISION' type='boolean' description='Whether fields created should keep the width and precision' default='YES'/>"
146 " <Option name='DIM' type='string' description='Set to 2 to force the geometries to be 2D, 3 to be 2.5D, XYM or XYZM'/>"
147 " <Option name='GEOMETRY_NAME' type='string' description='Name of geometry column. Defaults to wkb_geometry for GEOM_TYPE=geometry or the_geog for GEOM_TYPE=geography'/>"
148 " <Option name='SCHEMA' type='string' description='Name of schema into which to create the new table'/>"
149 " <Option name='SPATIAL_INDEX' type='string-select' description='Type of spatial index to create' default='GIST'>"
150 " <Value>NONE</Value>"
151 " <Value>GIST</Value>"
152 " <Value>SPGIST</Value>"
153 " <Value>BRIN</Value>"
154 " </Option>"
155 " <Option name='TEMPORARY' type='boolean' description='Whether to a temporary table instead of a permanent one' default='NO'/>"
156 " <Option name='UNLOGGED' type='boolean' description='Whether to create the table as a unlogged one' default='NO'/>"
157 " <Option name='NONE_AS_UNKNOWN' type='boolean' description='Whether to force non-spatial layers to be created as spatial tables' default='NO'/>"
158 " <Option name='FID' type='string' description='Name of the FID column to create' default='ogc_fid'/>"
159 " <Option name='FID64' type='boolean' description='Whether to create the FID column with BIGSERIAL type to handle 64bit wide ids' default='NO'/>"
160 " <Option name='EXTRACT_SCHEMA_FROM_LAYER_NAME' type='boolean' description='Whether a dot in a layer name should be considered as the separator for the schema and table name' default='YES'/>"
161 " <Option name='COLUMN_TYPES' type='string' description='A list of strings of format field_name=pg_field_type (separated by comma) to force the PG column type of fields to be created'/>"
162 " <Option name='DESCRIPTION' type='string' description='Description string to put in the pg_description system table'/>"
163 "</LayerCreationOptionList>");
164
165 poDriver->SetMetadataItem( GDAL_DMD_CREATIONFIELDDATATYPES,
166 "Integer Integer64 Real String Date DateTime "
167 "Time IntegerList Integer64List RealList "
168 "StringList Binary" );
169 poDriver->SetMetadataItem( GDAL_DMD_CREATIONFIELDDATASUBTYPES, "Boolean Int16 Float32" );
170 poDriver->SetMetadataItem( GDAL_DCAP_NOTNULL_FIELDS, "YES" );
171 poDriver->SetMetadataItem( GDAL_DCAP_DEFAULT_FIELDS, "YES" );
172 poDriver->SetMetadataItem( GDAL_DCAP_UNIQUE_FIELDS, "YES" );
173 poDriver->SetMetadataItem( GDAL_DCAP_NOTNULL_GEOMFIELDS, "YES" );
174
175 poDriver->pfnOpen = OGRPGDriverOpen;
176 poDriver->pfnIdentify = OGRPGDriverIdentify;
177 poDriver->pfnCreate = OGRPGDriverCreate;
178
179 GetGDALDriverManager()->RegisterDriver( poDriver );
180 }
181