Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implements OGRPGeoSelectLayer class, layer access to the results 5 : * of a SELECT statement executed via ExecuteSQL(). 6 : * Author: Frank Warmerdam, warmerdam@pobox.com 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2005, Frank Warmerdam 10 : * Copyright (c) 2010-2014, Even Rouault <even dot rouault at spatialys.com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #include "cpl_conv.h" 16 : #include "ogr_pgeo.h" 17 : 18 : /************************************************************************/ 19 : /* OGRPGeoSelectLayer() */ 20 : /************************************************************************/ 21 : 22 0 : OGRPGeoSelectLayer::OGRPGeoSelectLayer(OGRPGeoDataSource *poDSIn, 23 0 : CPLODBCStatement *poStmtIn) 24 0 : : pszBaseStatement(CPLStrdup(poStmtIn->GetCommand())) 25 : { 26 0 : poDS = poDSIn; 27 : 28 0 : iNextShapeId = 0; 29 0 : nSRSId = -1; 30 0 : poFeatureDefn = nullptr; 31 : 32 0 : poStmt = poStmtIn; 33 : 34 : // Just to make test_ogrsf happy, but would/could need be extended to 35 : // other cases. 36 0 : if (STARTS_WITH_CI(pszBaseStatement, "SELECT * FROM ")) 37 : { 38 : 39 : OGRLayer *poBaseLayer = 40 0 : poDSIn->GetLayerByName(pszBaseStatement + strlen("SELECT * FROM ")); 41 0 : if (poBaseLayer != nullptr) 42 : { 43 0 : poSRS = 44 0 : const_cast<OGRSpatialReference *>(poBaseLayer->GetSpatialRef()); 45 0 : if (poSRS != nullptr) 46 0 : poSRS->Reference(); 47 : } 48 : } 49 : 50 0 : BuildFeatureDefn("SELECT", poStmt); 51 0 : } 52 : 53 : /************************************************************************/ 54 : /* ~OGRPGeoSelectLayer() */ 55 : /************************************************************************/ 56 : 57 0 : OGRPGeoSelectLayer::~OGRPGeoSelectLayer() 58 : 59 : { 60 0 : ClearStatement(); 61 0 : CPLFree(pszBaseStatement); 62 0 : } 63 : 64 : /************************************************************************/ 65 : /* ClearStatement() */ 66 : /************************************************************************/ 67 : 68 0 : void OGRPGeoSelectLayer::ClearStatement() 69 : 70 : { 71 0 : if (poStmt != nullptr) 72 : { 73 0 : delete poStmt; 74 0 : poStmt = nullptr; 75 : } 76 0 : } 77 : 78 : /************************************************************************/ 79 : /* GetStatement() */ 80 : /************************************************************************/ 81 : 82 0 : CPLODBCStatement *OGRPGeoSelectLayer::GetStatement() 83 : 84 : { 85 0 : if (poStmt == nullptr) 86 0 : ResetStatement(); 87 : 88 0 : return poStmt; 89 : } 90 : 91 : /************************************************************************/ 92 : /* ResetStatement() */ 93 : /************************************************************************/ 94 : 95 0 : OGRErr OGRPGeoSelectLayer::ResetStatement() 96 : 97 : { 98 0 : ClearStatement(); 99 : 100 0 : iNextShapeId = 0; 101 : 102 0 : CPLDebug("ODBC", "Recreating statement."); 103 0 : poStmt = new CPLODBCStatement(poDS->GetSession(), m_nStatementFlags); 104 0 : poStmt->Append(pszBaseStatement); 105 : 106 0 : if (poStmt->ExecuteSQL()) 107 0 : return OGRERR_NONE; 108 : else 109 : { 110 0 : delete poStmt; 111 0 : poStmt = nullptr; 112 0 : return OGRERR_FAILURE; 113 : } 114 : } 115 : 116 : /************************************************************************/ 117 : /* ResetReading() */ 118 : /************************************************************************/ 119 : 120 0 : void OGRPGeoSelectLayer::ResetReading() 121 : 122 : { 123 0 : if (iNextShapeId != 0) 124 0 : ClearStatement(); 125 : 126 0 : OGRPGeoLayer::ResetReading(); 127 0 : } 128 : 129 : /************************************************************************/ 130 : /* GetFeature() */ 131 : /************************************************************************/ 132 : 133 0 : OGRFeature *OGRPGeoSelectLayer::GetFeature(GIntBig nFeatureId) 134 : 135 : { 136 0 : return OGRPGeoLayer::GetFeature(nFeatureId); 137 : } 138 : 139 : /************************************************************************/ 140 : /* TestCapability() */ 141 : /************************************************************************/ 142 : 143 0 : int OGRPGeoSelectLayer::TestCapability(const char *pszCap) const 144 : 145 : { 146 0 : return OGRPGeoLayer::TestCapability(pszCap); 147 : } 148 : 149 : /************************************************************************/ 150 : /* GetFeatureCount() */ 151 : /* */ 152 : /* If a spatial filter is in effect, we turn control over to */ 153 : /* the generic counter. Otherwise we return the total count. */ 154 : /* Eventually we should consider implementing a more efficient */ 155 : /* way of counting features matching a spatial query. */ 156 : /************************************************************************/ 157 : 158 0 : GIntBig OGRPGeoSelectLayer::GetFeatureCount(int bForce) 159 : 160 : { 161 0 : return OGRPGeoLayer::GetFeatureCount(bForce); 162 : }