1 : /******************************************************************************
2 : * $Id: ogrgeomediatablelayer.cpp 21561 2011-01-23 12:22:58Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRGeomediaTableLayer class, access to an existing table.
6 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
10 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "cpl_conv.h"
32 : #include "ogr_geomedia.h"
33 :
34 : CPL_CVSID("$Id: ogrgeomediatablelayer.cpp 21561 2011-01-23 12:22:58Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRGeomediaTableLayer() */
38 : /************************************************************************/
39 :
40 0 : OGRGeomediaTableLayer::OGRGeomediaTableLayer( OGRGeomediaDataSource *poDSIn )
41 :
42 : {
43 0 : poDS = poDSIn;
44 0 : pszQuery = NULL;
45 0 : bUpdateAccess = TRUE;
46 0 : iNextShapeId = 0;
47 0 : nSRSId = -1;
48 0 : poFeatureDefn = NULL;
49 0 : }
50 :
51 : /************************************************************************/
52 : /* ~OGRGeomediaTableLayer() */
53 : /************************************************************************/
54 :
55 0 : OGRGeomediaTableLayer::~OGRGeomediaTableLayer()
56 :
57 : {
58 0 : CPLFree( pszQuery );
59 0 : ClearStatement();
60 0 : }
61 :
62 : /************************************************************************/
63 : /* Initialize() */
64 : /************************************************************************/
65 :
66 0 : CPLErr OGRGeomediaTableLayer::Initialize( const char *pszTableName,
67 : const char *pszGeomCol,
68 : OGRSpatialReference* poSRS )
69 :
70 :
71 : {
72 0 : CPLODBCSession *poSession = poDS->GetSession();
73 :
74 0 : CPLFree( pszGeomColumn );
75 0 : if( pszGeomCol == NULL )
76 0 : pszGeomColumn = NULL;
77 : else
78 0 : pszGeomColumn = CPLStrdup( pszGeomCol );
79 :
80 0 : CPLFree( pszFIDColumn );
81 0 : pszFIDColumn = NULL;
82 :
83 0 : this->poSRS = poSRS;
84 :
85 : /* -------------------------------------------------------------------- */
86 : /* Do we have a simple primary key? */
87 : /* -------------------------------------------------------------------- */
88 : {
89 0 : CPLODBCStatement oGetKey( poSession );
90 :
91 0 : if( oGetKey.GetPrimaryKeys( pszTableName ) && oGetKey.Fetch() )
92 : {
93 0 : pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 ));
94 :
95 0 : if( oGetKey.Fetch() ) // more than one field in key!
96 : {
97 0 : CPLFree( pszFIDColumn );
98 0 : pszFIDColumn = NULL;
99 : CPLDebug( "Geomedia", "%s: Compound primary key, ignoring.",
100 0 : pszTableName );
101 : }
102 : else
103 : CPLDebug( "Geomedia",
104 : "%s: Got primary key %s.",
105 0 : pszTableName, pszFIDColumn );
106 : }
107 : else
108 0 : CPLDebug( "Geomedia", "%s: no primary key", pszTableName );
109 : }
110 : /* -------------------------------------------------------------------- */
111 : /* Get the column definitions for this table. */
112 : /* -------------------------------------------------------------------- */
113 0 : CPLODBCStatement oGetCol( poSession );
114 : CPLErr eErr;
115 :
116 0 : if( !oGetCol.GetColumns( pszTableName ) )
117 : {
118 : CPLError( CE_Failure, CPLE_AppDefined,
119 : "GetColumns() failed on %s.\n%s",
120 0 : pszTableName, poSession->GetLastError() );
121 0 : return CE_Failure;
122 : }
123 :
124 0 : eErr = BuildFeatureDefn( pszTableName, &oGetCol );
125 0 : if( eErr != CE_None )
126 0 : return eErr;
127 :
128 0 : if( poFeatureDefn->GetFieldCount() == 0 )
129 : {
130 : CPLError( CE_Failure, CPLE_AppDefined,
131 : "No column definitions found for table '%s', layer not usable.",
132 0 : pszTableName );
133 0 : return CE_Failure;
134 : }
135 :
136 0 : return CE_None;
137 : }
138 :
139 : /************************************************************************/
140 : /* ClearStatement() */
141 : /************************************************************************/
142 :
143 0 : void OGRGeomediaTableLayer::ClearStatement()
144 :
145 : {
146 0 : if( poStmt != NULL )
147 : {
148 0 : delete poStmt;
149 0 : poStmt = NULL;
150 : }
151 0 : }
152 :
153 : /************************************************************************/
154 : /* GetStatement() */
155 : /************************************************************************/
156 :
157 0 : CPLODBCStatement *OGRGeomediaTableLayer::GetStatement()
158 :
159 : {
160 0 : if( poStmt == NULL )
161 0 : ResetStatement();
162 :
163 0 : return poStmt;
164 : }
165 :
166 : /************************************************************************/
167 : /* ResetStatement() */
168 : /************************************************************************/
169 :
170 0 : OGRErr OGRGeomediaTableLayer::ResetStatement()
171 :
172 : {
173 0 : ClearStatement();
174 :
175 0 : iNextShapeId = 0;
176 :
177 0 : poStmt = new CPLODBCStatement( poDS->GetSession() );
178 0 : poStmt->Append( "SELECT * FROM " );
179 0 : poStmt->Append( poFeatureDefn->GetName() );
180 0 : if( pszQuery != NULL )
181 0 : poStmt->Appendf( " WHERE %s", pszQuery );
182 :
183 0 : if( poStmt->ExecuteSQL() )
184 0 : return OGRERR_NONE;
185 : else
186 : {
187 0 : delete poStmt;
188 0 : poStmt = NULL;
189 0 : return OGRERR_FAILURE;
190 : }
191 : }
192 :
193 : /************************************************************************/
194 : /* ResetReading() */
195 : /************************************************************************/
196 :
197 0 : void OGRGeomediaTableLayer::ResetReading()
198 :
199 : {
200 0 : ClearStatement();
201 0 : OGRGeomediaLayer::ResetReading();
202 0 : }
203 :
204 : /************************************************************************/
205 : /* GetFeature() */
206 : /************************************************************************/
207 :
208 0 : OGRFeature *OGRGeomediaTableLayer::GetFeature( long nFeatureId )
209 :
210 : {
211 0 : if( pszFIDColumn == NULL )
212 0 : return OGRGeomediaLayer::GetFeature( nFeatureId );
213 :
214 0 : ClearStatement();
215 :
216 0 : iNextShapeId = nFeatureId;
217 :
218 0 : poStmt = new CPLODBCStatement( poDS->GetSession() );
219 0 : poStmt->Append( "SELECT * FROM " );
220 0 : poStmt->Append( poFeatureDefn->GetName() );
221 0 : poStmt->Appendf( " WHERE %s = %ld", pszFIDColumn, nFeatureId );
222 :
223 0 : if( !poStmt->ExecuteSQL() )
224 : {
225 0 : delete poStmt;
226 0 : poStmt = NULL;
227 0 : return NULL;
228 : }
229 :
230 0 : return GetNextRawFeature();
231 : }
232 :
233 : /************************************************************************/
234 : /* SetAttributeFilter() */
235 : /************************************************************************/
236 :
237 0 : OGRErr OGRGeomediaTableLayer::SetAttributeFilter( const char *pszQuery )
238 :
239 : {
240 0 : if( (pszQuery == NULL && this->pszQuery == NULL)
241 : || (pszQuery != NULL && this->pszQuery != NULL
242 : && EQUAL(pszQuery,this->pszQuery)) )
243 0 : return OGRERR_NONE;
244 :
245 0 : CPLFree( this->pszQuery );
246 0 : this->pszQuery = pszQuery ? CPLStrdup( pszQuery ) : NULL;
247 :
248 0 : ClearStatement();
249 :
250 0 : return OGRERR_NONE;
251 : }
252 :
253 :
254 : /************************************************************************/
255 : /* TestCapability() */
256 : /************************************************************************/
257 :
258 0 : int OGRGeomediaTableLayer::TestCapability( const char * pszCap )
259 :
260 : {
261 0 : if( EQUAL(pszCap,OLCRandomRead) )
262 0 : return TRUE;
263 :
264 0 : else if( EQUAL(pszCap,OLCFastFeatureCount) )
265 0 : return m_poFilterGeom == NULL;
266 :
267 0 : else if( EQUAL(pszCap,OLCFastSpatialFilter) )
268 0 : return FALSE;
269 :
270 : else
271 0 : return OGRGeomediaLayer::TestCapability( pszCap );
272 : }
273 :
274 : /************************************************************************/
275 : /* GetFeatureCount() */
276 : /* */
277 : /* If a spatial filter is in effect, we turn control over to */
278 : /* the generic counter. Otherwise we return the total count. */
279 : /* Eventually we should consider implementing a more efficient */
280 : /* way of counting features matching a spatial query. */
281 : /************************************************************************/
282 :
283 0 : int OGRGeomediaTableLayer::GetFeatureCount( int bForce )
284 :
285 : {
286 0 : if( m_poFilterGeom != NULL )
287 0 : return OGRGeomediaLayer::GetFeatureCount( bForce );
288 :
289 0 : CPLODBCStatement oStmt( poDS->GetSession() );
290 0 : oStmt.Append( "SELECT COUNT(*) FROM " );
291 0 : oStmt.Append( poFeatureDefn->GetName() );
292 :
293 0 : if( pszQuery != NULL )
294 0 : oStmt.Appendf( " WHERE %s", pszQuery );
295 :
296 0 : if( !oStmt.ExecuteSQL() || !oStmt.Fetch() )
297 : {
298 : CPLError( CE_Failure, CPLE_AppDefined,
299 : "GetFeatureCount() failed on query %s.\n%s",
300 0 : oStmt.GetCommand(), poDS->GetSession()->GetLastError() );
301 0 : return OGRGeomediaLayer::GetFeatureCount(bForce);
302 : }
303 :
304 0 : return atoi(oStmt.GetColData(0));
305 : }
|