OGRErr OGRGFTDataSource::DeleteLayer(int iLayer) { if (!bReadWrite) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return OGRERR_FAILURE; } if (osAccessToken.size() == 0) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in unauthenticated mode"); return OGRERR_FAILURE; } if( iLayer < 0 || iLayer >= nLayers ) { CPLError( CE_Failure, CPLE_AppDefined, "Layer %d not in legal range of 0 to %d.", iLayer, nLayers-1 ); return OGRERR_FAILURE; } CPLString osTableId = ((OGRGFTTableLayer*)papoLayers[iLayer])->GetTableId(); CPLString osLayerName = GetLayer(iLayer)->GetName(); /* -------------------------------------------------------------------- */ /* Blow away our OGR structures related to the layer. This is */ /* pretty dangerous if anything has a reference to this layer! */ /* -------------------------------------------------------------------- */ CPLDebug( "GFT", "DeleteLayer(%s)", osLayerName.c_str() ); delete papoLayers[iLayer]; memmove( papoLayers + iLayer, papoLayers + iLayer + 1, sizeof(void *) * (nLayers - iLayer - 1) ); nLayers--; /* -------------------------------------------------------------------- */ /* Remove from the database. */ /* -------------------------------------------------------------------- */ CPLString osSQL("DROP TABLE "); osSQL += osTableId; CPLHTTPResult* psResult = RunSQL( osSQL ); if (psResult == NULL || psResult->nStatus != 0) { CPLError(CE_Failure, CPLE_AppDefined, "Table deletion failed (1)"); CPLHTTPDestroyResult(psResult); return OGRERR_FAILURE; } CPLHTTPDestroyResult(psResult); return OGRERR_NONE; }
CPLHTTPResult * OGRGFTDataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL("POSTFIELDS=sql="); /* Do post escaping */ for(int i=0;pszUnescapedSQL[i] != 0;i++) { const int ch = ((unsigned char*)pszUnescapedSQL)[i]; if (ch != '&' && ch >= 32 && ch < 128) osSQL += (char)ch; else osSQL += CPLSPrintf("%%%02X", ch); } /* -------------------------------------------------------------------- */ /* Provide the API Key - used to rate limit access (see */ /* GFT_APIKEY config) */ /* -------------------------------------------------------------------- */ osSQL += "&key="; osSQL += osAPIKey; /* -------------------------------------------------------------------- */ /* Force old style CSV output from calls - maybe we want to */ /* migrate to JSON output at some point? */ /* -------------------------------------------------------------------- */ osSQL += "&alt=csv"; /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ char** papszOptions = CSLAddString(AddHTTPOptions(), osSQL); CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions); CSLDestroy(papszOptions); /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult && psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "GFT", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); psResult = NULL; } if (psResult && psResult->pszErrBuf != NULL) { CPLDebug( "GFT", "RunSQL Error Message:%s", psResult->pszErrBuf ); } else if (psResult && psResult->nStatus != 0) { CPLDebug( "GFT", "RunSQL Error Status:%d", psResult->nStatus ); } return psResult; }
OGRFeature * OGRGFTTableLayer::GetFeature( GIntBig nFID ) { GetLayerDefn(); CPLString osSQL("SELECT ROWID"); for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { osSQL += ","; const char* pszFieldName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); osSQL += EscapeAndQuote(pszFieldName); } if (bHiddenGeometryField) { osSQL += ","; osSQL += EscapeAndQuote(GetGeometryColumn()); } osSQL += " FROM "; osSQL += osTableId; osSQL += CPLSPrintf(" WHERE ROWID='" CPL_FRMT_GIB "'", nFID); CPLPushErrorHandler(CPLQuietErrorHandler); CPLHTTPResult * psResult = poDS->RunSQL(osSQL); CPLPopErrorHandler(); if (psResult == NULL) return NULL; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLHTTPDestroyResult(psResult); return NULL; } /* skip header line */ pszLine = OGRGFTGotoNextLine(pszLine); if (pszLine == NULL || pszLine[0] == 0) { CPLHTTPDestroyResult(psResult); return NULL; } int nLen = (int)strlen(pszLine); if (nLen > 0 && pszLine[nLen-1] == '\n') pszLine[nLen-1] = '\0'; OGRFeature* poFeature = BuildFeatureFromSQL(pszLine); CPLHTTPDestroyResult(psResult); return poFeature; }
GIntBig OGRGFTTableLayer::GetFeatureCount(CPL_UNUSED int bForce) { GetLayerDefn(); CPLString osSQL("SELECT COUNT() FROM "); osSQL += osTableId; if (osWHERE.size()) { osSQL += " "; osSQL += osWHERE; } CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) return 0; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || strncmp(pszLine, "count()", 7) != 0 || psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed"); CPLHTTPDestroyResult(psResult); return 0; } pszLine = OGRGFTGotoNextLine(pszLine); if (pszLine == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed"); CPLHTTPDestroyResult(psResult); return 0; } char* pszNextLine = OGRGFTGotoNextLine(pszLine); if (pszNextLine) pszNextLine[-1] = 0; int nFeatureCount = atoi(pszLine); CPLHTTPDestroyResult(psResult); return nFeatureCount; }
GIntBig OGRCARTODBTableLayer::GetFeatureCount(int bForce) { if( bDeferedCreation && RunDeferedCreationIfNecessary() != OGRERR_NONE ) return 0; FlushDeferedInsert(); GetLayerDefn(); CPLString osSQL(CPLSPrintf("SELECT COUNT(*) FROM %s", OGRCARTODBEscapeIdentifier(osName).c_str())); if( osWHERE.size() ) { osSQL += " WHERE "; osSQL += osWHERE; } json_object* poObj = poDS->RunSQL(osSQL); json_object* poRowObj = OGRCARTODBGetSingleRow(poObj); if( poRowObj == NULL ) { if( poObj != NULL ) json_object_put(poObj); return OGRCARTODBLayer::GetFeatureCount(bForce); } json_object* poCount = json_object_object_get(poRowObj, "count"); if( poCount == NULL || json_object_get_type(poCount) != json_type_int ) { json_object_put(poObj); return OGRCARTODBLayer::GetFeatureCount(bForce); } GIntBig nRet = (GIntBig)json_object_get_int64(poCount); json_object_put(poObj); return nRet; }
void OGRGFTTableLayer::CreateTableIfNecessary() { if (bHasTriedCreateTable || osTableId.size() != 0) return; bHasTriedCreateTable = TRUE; CPLString osSQL("CREATE TABLE '"); osSQL += osTableName; osSQL += "' ("; int i; /* If there are longitude and latitude fields, use the latitude */ /* field as the LOCATION field */ for(i=0;i<poFeatureDefn->GetFieldCount();i++) { const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") || EQUAL(pszName, "latdec")) iLatitudeField = i; else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") || EQUAL(pszName, "londec") || EQUAL(pszName, "long")) iLongitudeField = i; } if (iLatitudeField >= 0 && iLongitudeField >= 0) { iGeometryField = iLatitudeField; poFeatureDefn->SetGeomType( wkbPoint ); } /* If no longitude/latitude field exist, let's look at a column */ /* named 'geometry' and use it as the LOCATION column if the layer */ /* hasn't been created with a none geometry type */ else if (iGeometryField < 0 && eGTypeForCreation != wkbNone) { iGeometryField = poFeatureDefn->GetFieldIndex(GetDefaultGeometryColumnName()); poFeatureDefn->SetGeomType( eGTypeForCreation ); } /* The user doesn't want geometries, so don't create one */ else if (eGTypeForCreation == wkbNone) { poFeatureDefn->SetGeomType( eGTypeForCreation ); } for(i=0;i<poFeatureDefn->GetFieldCount();i++) { if (i > 0) osSQL += ", "; const char* pszFieldName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); osSQL += EscapeAndQuote(pszFieldName); osSQL += ": "; if (iGeometryField == i) { osSQL += "LOCATION"; } else { switch(poFeatureDefn->GetFieldDefn(i)->GetType()) { case OFTInteger: case OFTReal: osSQL += "NUMBER"; break; default: osSQL += "STRING"; } } } /* If there's not yet a geometry field and the user didn't forbid */ /* the creation of one, then let's add it to the CREATE TABLE, but */ /* DO NOT add it to the feature defn as a feature might already have */ /* been created with it, so it is not safe to alter it at that point. */ /* So we set the bHiddenGeometryField flag to be able to fetch/set this */ /* column but not try to get/set a related feature field */ if (iGeometryField < 0 && eGTypeForCreation != wkbNone) { if (i > 0) osSQL += ", "; osSQL += EscapeAndQuote(GetDefaultGeometryColumnName()); osSQL += ": LOCATION"; iGeometryField = poFeatureDefn->GetFieldCount(); bHiddenGeometryField = TRUE; } osSQL += ")"; CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed"); return; } char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || strncmp(pszLine, "tableid", 7) != 0 || psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed"); CPLHTTPDestroyResult(psResult); return; } pszLine = OGRGFTGotoNextLine(pszLine); if (pszLine == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed"); CPLHTTPDestroyResult(psResult); return; } char* pszNextLine = OGRGFTGotoNextLine(pszLine); if (pszNextLine) pszNextLine[-1] = 0; osTableId = pszLine; CPLDebug("GFT", "Table %s --> id = %s", osTableName.c_str(), osTableId.c_str()); CPLHTTPDestroyResult(psResult); }
int OGRGFTTableLayer::FetchNextRows() { aosRows.resize(0); CPLString osSQL("SELECT ROWID"); for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { osSQL += ","; if (i < (int)aosColumnInternalName.size()) osSQL += aosColumnInternalName[i]; else { const char* pszFieldName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); osSQL += EscapeAndQuote(pszFieldName); } } if (bHiddenGeometryField) { osSQL += ","; osSQL += EscapeAndQuote(GetGeometryColumn()); } osSQL += " FROM "; osSQL += osTableId; if (osWHERE.size()) { osSQL += " "; osSQL += osWHERE; } int nFeaturesToFetch = GetFeaturesToFetch(); if (nFeaturesToFetch > 0) osSQL += CPLSPrintf(" OFFSET %d LIMIT %d", nOffset, nFeaturesToFetch); CPLPushErrorHandler(CPLQuietErrorHandler); CPLHTTPResult * psResult = poDS->RunSQL(osSQL); CPLPopErrorHandler(); if (psResult == NULL) { bEOF = TRUE; return FALSE; } char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLDebug("GFT", "Error : %s", pszLine ? pszLine : psResult->pszErrBuf); CPLHTTPDestroyResult(psResult); bEOF = TRUE; return FALSE; } ParseCSVResponse(pszLine, aosRows); if (aosRows.size() > 0) aosRows.erase(aosRows.begin()); if (nFeaturesToFetch > 0) bEOF = (int)aosRows.size() < GetFeaturesToFetch(); else bEOF = TRUE; CPLHTTPDestroyResult(psResult); return TRUE; }
int OGRGFTTableLayer::FetchDescribe() { poFeatureDefn = new OGRFeatureDefn( osTableName ); poFeatureDefn->Reference(); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); const CPLString& osAuth = poDS->GetAccessToken(); std::vector<CPLString> aosHeaderAndFirstDataLine; if (osAuth.size()) { CPLString osSQL("DESCRIBE "); osSQL += osTableId; CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL || strncmp(pszLine, "column id,name,type", strlen("column id,name,type")) != 0) { CPLHTTPDestroyResult(psResult); return FALSE; } pszLine = OGRGFTGotoNextLine(pszLine); std::vector<CPLString> aosLines; ParseCSVResponse(pszLine, aosLines); for(int i=0;i<(int)aosLines.size();i++) { char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ','); if (CSLCount(papszTokens) == 3) { aosColumnInternalName.push_back(papszTokens[0]); //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]); OGRFieldType eType = OFTString; if (EQUAL(papszTokens[2], "number")) eType = OFTReal; else if (EQUAL(papszTokens[2], "datetime")) eType = OFTDateTime; if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0) { if (iGeometryField < 0) iGeometryField = poFeatureDefn->GetFieldCount(); else CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } CPLString osLaunderedColName(LaunderColName(papszTokens[1])); OGRFieldDefn oFieldDefn(osLaunderedColName, eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } CSLDestroy(papszTokens); } CPLHTTPDestroyResult(psResult); } else { /* http://code.google.com/intl/fr/apis/fusiontables/docs/developers_guide.html#Exploring states */ /* that DESCRIBE should work on public tables without authentication, but it is not true... */ CPLString osSQL("SELECT * FROM "); osSQL += osTableId; osSQL += " OFFSET 0 LIMIT 1"; CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLHTTPDestroyResult(psResult); return FALSE; } ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine); if (aosHeaderAndFirstDataLine.size() > 0) { char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ','); for(int i=0;papszTokens && papszTokens[i];i++) { CPLString osLaunderedColName(LaunderColName(papszTokens[i])); OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString); poFeatureDefn->AddFieldDefn(&oFieldDefn); } CSLDestroy(papszTokens); } CPLHTTPDestroyResult(psResult); } if (osGeomColumnName.size() > 0) { iGeometryField = poFeatureDefn->GetFieldIndex(osGeomColumnName); if (iGeometryField < 0) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find column called %s", osGeomColumnName.c_str()); } } for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") || EQUAL(pszName, "latdec")) iLatitudeField = i; else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") || EQUAL(pszName, "londec") || EQUAL(pszName, "long")) iLongitudeField = i; } if (iLatitudeField >= 0 && iLongitudeField >= 0) { if (iGeometryField < 0) iGeometryField = iLatitudeField; poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal); poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal); poFeatureDefn->SetGeomType( wkbPoint ); } else if (iGeometryField < 0 && osGeomColumnName.size() == 0) { iLatitudeField = iLongitudeField = -1; /* In the unauthentified case, we try to parse the first record to */ /* autodetect the geometry field */ OGRwkbGeometryType eType = wkbUnknown; if (aosHeaderAndFirstDataLine.size() == 2) { char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[1], ','); if (CSLCount(papszTokens) == poFeatureDefn->GetFieldCount()) { for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { const char* pszVal = papszTokens[i]; if (pszVal != NULL && (strncmp(pszVal, "<Point>", 7) == 0 || strncmp(pszVal, "<LineString>", 12) == 0 || strncmp(pszVal, "<Polygon>", 9) == 0 || strncmp(pszVal, "<MultiGeometry>", 15) == 0)) { if (iGeometryField < 0) { iGeometryField = i; } else { CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } } else if (pszVal) { /* http://www.google.com/fusiontables/DataSource?dsrcid=423292 */ char** papszTokens2 = CSLTokenizeString2(pszVal, " ,", 0); if (CSLCount(papszTokens2) == 2 && CPLGetValueType(papszTokens2[0]) == CPL_VALUE_REAL && CPLGetValueType(papszTokens2[1]) == CPL_VALUE_REAL && fabs(CPLAtof(papszTokens2[0])) <= 90 && fabs(CPLAtof(papszTokens2[1])) <= 180 ) { if (iGeometryField < 0) { iGeometryField = i; eType = wkbPoint; } else { CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } } CSLDestroy(papszTokens2); } } } CSLDestroy(papszTokens); } if (iGeometryField < 0) poFeatureDefn->SetGeomType( wkbNone ); else poFeatureDefn->SetGeomType( eType ); } SetGeomFieldName(); return TRUE; }
json_object* OGRCARTODBDataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL("POSTFIELDS=q="); /* Do post escaping */ for(int i=0;pszUnescapedSQL[i] != 0;i++) { const int ch = ((unsigned char*)pszUnescapedSQL)[i]; if (ch != '&' && ch >= 32 && ch < 128) osSQL += (char)ch; else osSQL += CPLSPrintf("%%%02X", ch); } /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( osAPIKey.size() ) { osSQL += "&api_key="; osSQL += osAPIKey; } /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ char** papszOptions = CSLAddString(AddHTTPOptions(), osSQL); CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions); CSLDestroy(papszOptions); /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult && psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "CARTODB", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); return NULL; } if (psResult && psResult->pszErrBuf != NULL) { CPLDebug( "CARTODB", "RunSQL Error Message:%s", psResult->pszErrBuf ); } else if (psResult && psResult->nStatus != 0) { CPLDebug( "CARTODB", "RunSQL Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == NULL ) { CPLHTTPDestroyResult(psResult); return NULL; } if( strlen((const char*)psResult->pabyData) < 1000 ) CPLDebug( "CARTODB", "RunSQL Response:%s", psResult->pabyData ); json_tokener* jstok = NULL; json_object* poObj = NULL; jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1); if( jstok->err != json_tokener_success) { CPLError( CE_Failure, CPLE_AppDefined, "JSON parsing error: %s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); return NULL; } json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); if( poObj != NULL ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = json_object_object_get(poObj, "error"); if( poError != NULL && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != NULL && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return NULL; } } } else { json_object_put(poObj); return NULL; } } return poObj; }
void OGROSMLayer::AddComputedAttribute(const char* pszName, OGRFieldType eType, const char* pszSQL) { if( poDS->hDBForComputedAttributes == NULL ) { int rc; #ifdef HAVE_SQLITE_VFS rc = sqlite3_open_v2( ":memory:", &(poDS->hDBForComputedAttributes), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL ); #else rc = sqlite3_open( ":memory:", &(poDS->hDBForComputedAttributes) ); #endif if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot open temporary sqlite DB" ); return; } } if( poFeatureDefn->GetFieldIndex(pszName) >= 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "A field with same name %s already exists", pszName ); return; } CPLString osSQL(pszSQL); std::vector<CPLString> aosAttrToBind; std::vector<int> anIndexToBind; size_t nStartSearch = 0; while(TRUE) { size_t nPos = osSQL.find("[", nStartSearch); if( nPos == std::string::npos ) break; nStartSearch = nPos + 1; if( nPos > 0 && osSQL[nPos-1] != '\\' ) { CPLString osAttr = osSQL.substr(nPos + 1); size_t nPos2 = osAttr.find("]"); if( nPos2 == std::string::npos ) break; osAttr.resize(nPos2); osSQL = osSQL.substr(0, nPos) + "?" + osSQL.substr(nPos + 1 + nPos2+1); aosAttrToBind.push_back(osAttr); anIndexToBind.push_back(poFeatureDefn->GetFieldIndex(osAttr)); } } while(TRUE) { size_t nPos = osSQL.find("\\"); if( nPos == std::string::npos || nPos == osSQL.size() - 1 ) break; osSQL = osSQL.substr(0, nPos) + osSQL.substr(nPos + 1); } CPLDebug("OSM", "SQL : \"%s\"", osSQL.c_str()); sqlite3_stmt *hStmt; int rc = sqlite3_prepare( poDS->hDBForComputedAttributes, osSQL, -1, &hStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "sqlite3_prepare() failed : %s", sqlite3_errmsg(poDS->hDBForComputedAttributes) ); return; } OGRFieldDefn oField(pszName, eType); poFeatureDefn->AddFieldDefn(&oField); oComputedAttributes.push_back(OGROSMComputedAttribute(pszName)); oComputedAttributes[oComputedAttributes.size()-1].eType = eType; oComputedAttributes[oComputedAttributes.size()-1].nIndex = poFeatureDefn->GetFieldCount() - 1; oComputedAttributes[oComputedAttributes.size()-1].osSQL = pszSQL; oComputedAttributes[oComputedAttributes.size()-1].hStmt = hStmt; oComputedAttributes[oComputedAttributes.size()-1].aosAttrToBind = aosAttrToBind; oComputedAttributes[oComputedAttributes.size()-1].anIndexToBind = anIndexToBind; }