1 : /******************************************************************************
2 : * $Id: ogrsqlitedriver.cpp 16847 2009-04-25 15:36:18Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRSQLiteDriver class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_sqlite.h"
31 : #include "cpl_conv.h"
32 :
33 : CPL_CVSID("$Id: ogrsqlitedriver.cpp 16847 2009-04-25 15:36:18Z rouault $");
34 :
35 : /************************************************************************/
36 : /* ~OGRSQLiteDriver() */
37 : /************************************************************************/
38 :
39 96 : OGRSQLiteDriver::~OGRSQLiteDriver()
40 :
41 : {
42 96 : }
43 :
44 : /************************************************************************/
45 : /* GetName() */
46 : /************************************************************************/
47 :
48 1914 : const char *OGRSQLiteDriver::GetName()
49 :
50 : {
51 1914 : return "SQLite";
52 : }
53 :
54 : /************************************************************************/
55 : /* Open() */
56 : /************************************************************************/
57 :
58 121 : OGRDataSource *OGRSQLiteDriver::Open( const char * pszFilename,
59 : int bUpdate )
60 :
61 : {
62 : /* -------------------------------------------------------------------- */
63 : /* Verify that the target is a real file, and has an */
64 : /* appropriate magic string at the beginning. */
65 : /* -------------------------------------------------------------------- */
66 : FILE *fpDB;
67 : char szHeader[16];
68 :
69 121 : fpDB = VSIFOpen( pszFilename, "rb" );
70 121 : if( fpDB == NULL )
71 61 : return NULL;
72 :
73 60 : if( VSIFRead( szHeader, 1, 16, fpDB ) != 16 )
74 1 : memset( szHeader, 0, 16 );
75 :
76 60 : VSIFClose( fpDB );
77 :
78 60 : if( strncmp( szHeader, "SQLite format 3", 15 ) != 0 )
79 28 : return NULL;
80 :
81 : /* -------------------------------------------------------------------- */
82 : /* We think this is really an SQLite database, go ahead and try */
83 : /* and open it. */
84 : /* -------------------------------------------------------------------- */
85 : OGRSQLiteDataSource *poDS;
86 :
87 32 : poDS = new OGRSQLiteDataSource();
88 :
89 32 : if( !poDS->Open( pszFilename ) )
90 : {
91 0 : delete poDS;
92 0 : return NULL;
93 : }
94 : else
95 32 : return poDS;
96 : }
97 :
98 : /************************************************************************/
99 : /* CreateDataSource() */
100 : /************************************************************************/
101 :
102 19 : OGRDataSource *OGRSQLiteDriver::CreateDataSource( const char * pszName,
103 : char **papszOptions )
104 :
105 : {
106 : /* -------------------------------------------------------------------- */
107 : /* First, ensure there isn't any such file yet. */
108 : /* -------------------------------------------------------------------- */
109 : VSIStatBuf sStatBuf;
110 :
111 19 : if( VSIStat( pszName, &sStatBuf ) == 0 )
112 : {
113 : CPLError( CE_Failure, CPLE_AppDefined,
114 : "It seems a file system object called '%s' already exists.",
115 0 : pszName );
116 :
117 0 : return NULL;
118 : }
119 :
120 : /* -------------------------------------------------------------------- */
121 : /* Create the database file. */
122 : /* -------------------------------------------------------------------- */
123 : sqlite3 *hDB;
124 : int rc;
125 :
126 19 : hDB = NULL;
127 19 : rc = sqlite3_open( pszName, &hDB );
128 19 : if( rc != SQLITE_OK )
129 : {
130 : CPLError( CE_Failure, CPLE_OpenFailed,
131 : "sqlite3_open(%s) failed: %s",
132 0 : pszName, sqlite3_errmsg( hDB ) );
133 0 : return NULL;
134 : }
135 :
136 : /* -------------------------------------------------------------------- */
137 : /* Create the SpatiaLite metadata tables. */
138 : /* -------------------------------------------------------------------- */
139 19 : if ( CSLFetchBoolean( papszOptions, "SPATIALITE", FALSE ) )
140 : {
141 17 : CPLString osCommand;
142 17 : char *pszErrMsg = NULL;
143 :
144 : osCommand =
145 : "CREATE TABLE geometry_columns ("
146 : " f_table_name VARCHAR, "
147 : " f_geometry_column VARCHAR, "
148 : " type VARCHAR, "
149 : " coord_dimension INTEGER, "
150 : " srid INTEGER,"
151 17 : " spatial_index_enabled INTEGER )";
152 17 : rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
153 17 : if( rc != SQLITE_OK )
154 : {
155 : CPLError( CE_Failure, CPLE_AppDefined,
156 : "Unable to create table geometry_columns: %s",
157 0 : pszErrMsg );
158 0 : sqlite3_free( pszErrMsg );
159 0 : return NULL;
160 : }
161 :
162 : osCommand =
163 : "CREATE TABLE spatial_ref_sys ("
164 : " srid INTEGER UNIQUE,"
165 : " auth_name VARCHAR,"
166 : " auth_srid INTEGER,"
167 : " ref_sys_name VARCHAR,"
168 17 : " proj4text VARCHAR )";
169 17 : rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
170 17 : if( rc != SQLITE_OK )
171 : {
172 : CPLError( CE_Failure, CPLE_AppDefined,
173 : "Unable to create table spatial_ref_sys: %s",
174 0 : pszErrMsg );
175 0 : sqlite3_free( pszErrMsg );
176 0 : return NULL;
177 0 : }
178 : }
179 :
180 : /* -------------------------------------------------------------------- */
181 : /* Create the geometry_columns and spatial_ref_sys metadata tables. */
182 : /* -------------------------------------------------------------------- */
183 2 : else if( CSLFetchBoolean( papszOptions, "METADATA", TRUE ) )
184 : {
185 2 : CPLString osCommand;
186 2 : char *pszErrMsg = NULL;
187 :
188 : osCommand =
189 : "CREATE TABLE geometry_columns ("
190 : " f_table_name VARCHAR, "
191 : " f_geometry_column VARCHAR, "
192 : " geometry_type INTEGER, "
193 : " coord_dimension INTEGER, "
194 : " srid INTEGER,"
195 2 : " geometry_format VARCHAR )";
196 2 : rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
197 2 : if( rc != SQLITE_OK )
198 : {
199 : CPLError( CE_Failure, CPLE_AppDefined,
200 : "Unable to create table geometry_columns: %s",
201 0 : pszErrMsg );
202 0 : sqlite3_free( pszErrMsg );
203 0 : return NULL;
204 : }
205 :
206 : osCommand =
207 : "CREATE TABLE spatial_ref_sys ("
208 : " srid INTEGER UNIQUE,"
209 : " auth_name TEXT,"
210 : " auth_srid TEXT,"
211 2 : " srtext TEXT)";
212 2 : rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
213 2 : if( rc != SQLITE_OK )
214 : {
215 : CPLError( CE_Failure, CPLE_AppDefined,
216 : "Unable to create table spatial_ref_sys: %s",
217 0 : pszErrMsg );
218 0 : sqlite3_free( pszErrMsg );
219 0 : return NULL;
220 0 : }
221 : }
222 : else
223 : {
224 : /* -------------------------------------------------------------------- */
225 : /* Close the DB file so we can reopen it normally. */
226 : /* -------------------------------------------------------------------- */
227 0 : sqlite3_close( hDB );
228 :
229 : OGRSQLiteDataSource *poDS;
230 0 : poDS = new OGRSQLiteDataSource();
231 :
232 0 : if( !poDS->Open( pszName ) )
233 : {
234 0 : delete poDS;
235 0 : return NULL;
236 : }
237 : else
238 0 : return poDS;
239 : }
240 :
241 : /* -------------------------------------------------------------------- */
242 : /* Close the DB file so we can reopen it normally. */
243 : /* -------------------------------------------------------------------- */
244 19 : sqlite3_close( hDB );
245 :
246 19 : return Open( pszName, TRUE );
247 : }
248 :
249 : /************************************************************************/
250 : /* TestCapability() */
251 : /************************************************************************/
252 :
253 0 : int OGRSQLiteDriver::TestCapability( const char * pszCap )
254 :
255 : {
256 0 : if( EQUAL(pszCap,ODrCCreateDataSource) )
257 0 : return TRUE;
258 : else
259 0 : return FALSE;
260 : }
261 :
262 : /************************************************************************/
263 : /* RegisterOGRSQLite() */
264 : /************************************************************************/
265 :
266 64 : void RegisterOGRSQLite()
267 :
268 : {
269 64 : if (! GDAL_CHECK_VERSION("SQLite driver"))
270 0 : return;
271 64 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRSQLiteDriver );
272 : }
273 :
|