1 : /******************************************************************************
2 : * $Id: ogrsqlitedriver.cpp 23410 2011-11-21 22:00:11Z 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 23410 2011-11-21 22:00:11Z rouault $");
41 :
42 : /************************************************************************/
43 : /* ~OGRSQLiteDriver() */
44 : /************************************************************************/
45 :
46 214 : OGRSQLiteDriver::~OGRSQLiteDriver()
47 :
48 : {
49 214 : }
50 :
51 : /************************************************************************/
52 : /* GetName() */
53 : /************************************************************************/
54 :
55 14149 : const char *OGRSQLiteDriver::GetName()
56 :
57 : {
58 14149 : return "SQLite";
59 : }
60 :
61 : /************************************************************************/
62 : /* Open() */
63 : /************************************************************************/
64 :
65 445 : OGRDataSource *OGRSQLiteDriver::Open( const char * pszFilename,
66 : int bUpdate )
67 :
68 : {
69 :
70 : /* -------------------------------------------------------------------- */
71 : /* Check VirtualShape:xxx.shp syntax */
72 : /* -------------------------------------------------------------------- */
73 445 : int nLen = (int) strlen(pszFilename);
74 445 : 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 : char szHeader[16];
120 :
121 : #ifdef HAVE_SQLITE_VFS
122 : VSILFILE *fpDB;
123 444 : fpDB = VSIFOpenL( pszFilename, "rb" );
124 444 : if( fpDB == NULL )
125 173 : return NULL;
126 :
127 271 : if( VSIFReadL( szHeader, 1, 16, fpDB ) != 16 )
128 17 : memset( szHeader, 0, 16 );
129 :
130 271 : VSIFCloseL( fpDB );
131 : #else
132 : FILE *fpDB;
133 : fpDB = VSIFOpen( pszFilename, "rb" );
134 : if( fpDB == NULL )
135 : return NULL;
136 :
137 : if( VSIFRead( szHeader, 1, 16, fpDB ) != 16 )
138 : memset( szHeader, 0, 16 );
139 :
140 : VSIFClose( fpDB );
141 : #endif
142 :
143 271 : if( strncmp( szHeader, "SQLite format 3", 15 ) != 0 )
144 161 : return NULL;
145 :
146 : /* -------------------------------------------------------------------- */
147 : /* We think this is really an SQLite database, go ahead and try */
148 : /* and open it. */
149 : /* -------------------------------------------------------------------- */
150 : OGRSQLiteDataSource *poDS;
151 :
152 110 : poDS = new OGRSQLiteDataSource();
153 :
154 110 : if( !poDS->Open( pszFilename, bUpdate ) )
155 : {
156 0 : delete poDS;
157 0 : return NULL;
158 : }
159 : else
160 110 : return poDS;
161 : }
162 :
163 : /************************************************************************/
164 : /* CreateDataSource() */
165 : /************************************************************************/
166 :
167 83 : OGRDataSource *OGRSQLiteDriver::CreateDataSource( const char * pszName,
168 : char **papszOptions )
169 :
170 : {
171 : /* -------------------------------------------------------------------- */
172 : /* First, ensure there isn't any such file yet. */
173 : /* -------------------------------------------------------------------- */
174 : VSIStatBufL sStatBuf;
175 :
176 83 : if( VSIStatL( pszName, &sStatBuf ) == 0 )
177 : {
178 : CPLError( CE_Failure, CPLE_AppDefined,
179 : "It seems a file system object called '%s' already exists.",
180 0 : pszName );
181 :
182 0 : return NULL;
183 : }
184 :
185 : /* -------------------------------------------------------------------- */
186 : /* Try to create datasource. */
187 : /* -------------------------------------------------------------------- */
188 : OGRSQLiteDataSource *poDS;
189 :
190 83 : poDS = new OGRSQLiteDataSource();
191 :
192 83 : if( !poDS->Create( pszName, papszOptions ) )
193 : {
194 18 : delete poDS;
195 18 : return NULL;
196 : }
197 : else
198 65 : return poDS;
199 : }
200 :
201 : /************************************************************************/
202 : /* DeleteDataSource() */
203 : /************************************************************************/
204 :
205 4 : OGRErr OGRSQLiteDriver::DeleteDataSource( const char *pszName )
206 : {
207 4 : if (VSIUnlink( pszName ) == 0)
208 3 : return OGRERR_NONE;
209 : else
210 1 : return OGRERR_FAILURE;
211 : }
212 :
213 : /************************************************************************/
214 : /* TestCapability() */
215 : /************************************************************************/
216 :
217 3 : int OGRSQLiteDriver::TestCapability( const char * pszCap )
218 :
219 : {
220 3 : if( EQUAL(pszCap,ODrCCreateDataSource) )
221 3 : return TRUE;
222 0 : else if( EQUAL(pszCap,ODrCDeleteDataSource) )
223 0 : return TRUE;
224 : else
225 0 : return FALSE;
226 : }
227 :
228 : /************************************************************************/
229 : /* RegisterOGRSQLite() */
230 : /************************************************************************/
231 :
232 226 : void RegisterOGRSQLite()
233 :
234 : {
235 226 : if (! GDAL_CHECK_VERSION("SQLite driver"))
236 0 : return;
237 226 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( new OGRSQLiteDriver );
238 : }
239 :
|