1 : /******************************************************************************
2 : * $Id: ogrsqlitedriver.cpp 25409 2012-12-31 11:51:10Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRSQLiteDriver class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : *
10 : * Contributor: Alessandro Furieri, a.furieri@lqt.it
11 : * Portions of this module properly supporting SpatiaLite DB creation
12 : * Developed for Faunalia ( http://www.faunalia.it) with funding from
13 : * Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED AMBIENTALE
14 : *
15 : ******************************************************************************
16 : * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.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 "ogr_sqlite.h"
38 : #include "cpl_conv.h"
39 :
40 : CPL_CVSID("$Id: ogrsqlitedriver.cpp 25409 2012-12-31 11:51:10Z rouault $");
41 :
42 : /************************************************************************/
43 : /* ~OGRSQLiteDriver() */
44 : /************************************************************************/
45 :
46 223 : OGRSQLiteDriver::~OGRSQLiteDriver()
47 :
48 : {
49 223 : }
50 :
51 : /************************************************************************/
52 : /* GetName() */
53 : /************************************************************************/
54 :
55 15320 : const char *OGRSQLiteDriver::GetName()
56 :
57 : {
58 15320 : return "SQLite";
59 : }
60 :
61 : /************************************************************************/
62 : /* Open() */
63 : /************************************************************************/
64 :
65 556 : OGRDataSource *OGRSQLiteDriver::Open( const char * pszFilename,
66 : int bUpdate )
67 :
68 : {
69 :
70 : /* -------------------------------------------------------------------- */
71 : /* Check VirtualShape:xxx.shp syntax */
72 : /* -------------------------------------------------------------------- */
73 556 : int nLen = (int) strlen(pszFilename);
74 556 : if (EQUALN(pszFilename, "VirtualShape:", strlen( "VirtualShape:" )) &&
75 : nLen > 4 && EQUAL(pszFilename + nLen - 4, ".SHP"))
76 : {
77 : OGRSQLiteDataSource *poDS;
78 :
79 1 : poDS = new OGRSQLiteDataSource();
80 :
81 1 : char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES");
82 1 : int nRet = poDS->Create( ":memory:", papszOptions );
83 1 : poDS->SetName(pszFilename);
84 1 : CSLDestroy(papszOptions);
85 1 : if (!nRet)
86 : {
87 0 : delete poDS;
88 0 : return NULL;
89 : }
90 :
91 1 : char* pszShapeFilename = CPLStrdup(pszFilename + strlen( "VirtualShape:" ));
92 1 : OGRDataSource* poShapeDS = OGRSFDriverRegistrar::Open(pszShapeFilename);
93 1 : if (poShapeDS == NULL)
94 : {
95 0 : CPLFree(pszShapeFilename);
96 0 : delete poDS;
97 0 : return NULL;
98 : }
99 1 : delete poShapeDS;
100 :
101 1 : char* pszLastDot = strrchr(pszShapeFilename, '.');
102 1 : if (pszLastDot)
103 1 : *pszLastDot = '\0';
104 :
105 1 : const char* pszTableName = CPLGetBasename(pszShapeFilename);
106 :
107 : char* pszSQL = CPLStrdup(CPLSPrintf("CREATE VIRTUAL TABLE %s USING VirtualShape(%s, CP1252, -1)",
108 1 : pszTableName, pszShapeFilename));
109 1 : poDS->ExecuteSQL(pszSQL, NULL, NULL);
110 1 : CPLFree(pszSQL);
111 1 : CPLFree(pszShapeFilename);
112 1 : return poDS;
113 : }
114 :
115 : /* -------------------------------------------------------------------- */
116 : /* Verify that the target is a real file, and has an */
117 : /* appropriate magic string at the beginning. */
118 : /* -------------------------------------------------------------------- */
119 555 : if( !EQUAL(pszFilename, ":memory:") )
120 : {
121 : char szHeader[16];
122 :
123 : #ifdef HAVE_SQLITE_VFS
124 : VSILFILE *fpDB;
125 555 : fpDB = VSIFOpenL( pszFilename, "rb" );
126 555 : if( fpDB == NULL )
127 217 : return NULL;
128 :
129 338 : if( VSIFReadL( szHeader, 1, 16, fpDB ) != 16 )
130 23 : memset( szHeader, 0, 16 );
131 :
132 338 : VSIFCloseL( fpDB );
133 : #else
134 : FILE *fpDB;
135 : fpDB = VSIFOpen( pszFilename, "rb" );
136 : if( fpDB == NULL )
137 : return NULL;
138 :
139 : if( VSIFRead( szHeader, 1, 16, fpDB ) != 16 )
140 : memset( szHeader, 0, 16 );
141 :
142 : VSIFClose( fpDB );
143 : #endif
144 :
145 338 : if( strncmp( szHeader, "SQLite format 3", 15 ) != 0 )
146 168 : return NULL;
147 : }
148 :
149 : /* -------------------------------------------------------------------- */
150 : /* We think this is really an SQLite database, go ahead and try */
151 : /* and open it. */
152 : /* -------------------------------------------------------------------- */
153 : OGRSQLiteDataSource *poDS;
154 :
155 170 : poDS = new OGRSQLiteDataSource();
156 :
157 170 : if( !poDS->Open( pszFilename, bUpdate ) )
158 : {
159 0 : delete poDS;
160 0 : return NULL;
161 : }
162 : else
163 170 : return poDS;
164 : }
165 :
166 : /************************************************************************/
167 : /* CreateDataSource() */
168 : /************************************************************************/
169 :
170 95 : OGRDataSource *OGRSQLiteDriver::CreateDataSource( const char * pszName,
171 : char **papszOptions )
172 :
173 : {
174 : /* -------------------------------------------------------------------- */
175 : /* First, ensure there isn't any such file yet. */
176 : /* -------------------------------------------------------------------- */
177 : VSIStatBufL sStatBuf;
178 :
179 95 : if( VSIStatL( pszName, &sStatBuf ) == 0 )
180 : {
181 : CPLError( CE_Failure, CPLE_AppDefined,
182 : "It seems a file system object called '%s' already exists.",
183 0 : pszName );
184 :
185 0 : return NULL;
186 : }
187 :
188 : /* -------------------------------------------------------------------- */
189 : /* Try to create datasource. */
190 : /* -------------------------------------------------------------------- */
191 : OGRSQLiteDataSource *poDS;
192 :
193 95 : poDS = new OGRSQLiteDataSource();
194 :
195 95 : if( !poDS->Create( pszName, papszOptions ) )
196 : {
197 18 : delete poDS;
198 18 : return NULL;
199 : }
200 : else
201 77 : return poDS;
202 : }
203 :
204 : /************************************************************************/
205 : /* DeleteDataSource() */
206 : /************************************************************************/
207 :
208 4 : OGRErr OGRSQLiteDriver::DeleteDataSource( const char *pszName )
209 : {
210 4 : if (VSIUnlink( pszName ) == 0)
211 3 : return OGRERR_NONE;
212 : else
213 1 : return OGRERR_FAILURE;
214 : }
215 :
216 : /************************************************************************/
217 : /* TestCapability() */
218 : /************************************************************************/
219 :
220 4 : int OGRSQLiteDriver::TestCapability( const char * pszCap )
221 :
222 : {
223 4 : if( EQUAL(pszCap,ODrCCreateDataSource) )
224 4 : return TRUE;
225 0 : else if( EQUAL(pszCap,ODrCDeleteDataSource) )
226 0 : return TRUE;
227 : else
228 0 : return FALSE;
229 : }
230 :
231 : /************************************************************************/
232 : /* RegisterOGRSQLite() */
233 : /************************************************************************/
234 :
235 244 : void RegisterOGRSQLite()
236 :
237 : {
238 244 : if (! GDAL_CHECK_VERSION("SQLite driver"))
239 0 : return;
240 244 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRSQLiteDriver );
241 : }
242 :
|