GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey ) { GByte* ret = nullptr; switch( poFldDefn->GetType() ) { case OFTInteger: ret = poINDFile->BuildKey( iIndex, psKey->Integer ); break; case OFTInteger64: { if( !CPL_INT64_FITS_ON_INT32(psKey->Integer64) ) { CPLError(CE_Warning, CPLE_NotSupported, "64bit integer value passed to OGRMIAttrIndex::BuildKey()"); } ret = poINDFile->BuildKey( iIndex, static_cast<int>(psKey->Integer64) ); break; } case OFTReal: ret = poINDFile->BuildKey( iIndex, psKey->Real ); break; case OFTString: ret = poINDFile->BuildKey( iIndex, psKey->String ); break; default: CPLAssert( false ); break; } return ret; }
GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey ) { switch( poFldDefn->GetType() ) { case OFTInteger: return poINDFile->BuildKey( iIndex, psKey->Integer ); break; case OFTInteger64: { if( !CPL_INT64_FITS_ON_INT32(psKey->Integer64) ) { CPLError(CE_Warning, CPLE_NotSupported, "64bit integer value passed to OGRMIAttrIndex::BuildKey()"); } return poINDFile->BuildKey( iIndex, (int)psKey->Integer64 ); break; } case OFTReal: return poINDFile->BuildKey( iIndex, psKey->Real ); break; case OFTString: return poINDFile->BuildKey( iIndex, psKey->String ); break; default: CPLAssert( FALSE ); return NULL; } }
/********************************************************************** * SearchIndex() * * Search a TAB dataset's .IND file for pszVal in index nIndexNo **********************************************************************/ static int SearchIndex(const char *pszFname, int nIndexNo, const char *pszVal) { TABFile oTABFile; TABINDFile *poINDFile; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if (oTABFile.Open(pszFname, "rb") != 0) { printf("Failed to open %s as a TABFile.\n", pszFname); return -1; } /*--------------------------------------------------------------------- * Fetch IND file handle *--------------------------------------------------------------------*/ if ((poINDFile = oTABFile.GetINDFileRef()) == NULL) { printf("Dataset %s has no .IND file\n", pszFname); return -1; } /*--------------------------------------------------------------------- * Search the index. * For now we search only 'char' index types!!! *--------------------------------------------------------------------*/ GByte *pKey; int nRecordNo; pKey = poINDFile->BuildKey(nIndexNo, pszVal); nRecordNo = poINDFile->FindFirst(nIndexNo, pKey); if (nRecordNo < 1) { printf("Value '%s' not found in index #%d\n", pszVal, nIndexNo); } else { while(nRecordNo > 0) { printf("Record %d...\n", nRecordNo); nRecordNo = poINDFile->FindNext(nIndexNo, pKey); } } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ oTABFile.Close(); return 0; }
GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey ) { switch( poFldDefn->GetType() ) { case OFTInteger: return poINDFile->BuildKey( iIndex, psKey->Integer ); break; case OFTReal: return poINDFile->BuildKey( iIndex, psKey->Real ); break; case OFTString: return poINDFile->BuildKey( iIndex, psKey->String ); break; default: CPLAssert( FALSE ); return NULL; } }
/********************************************************************** * CreateIndex() * * Create index for specified field in an existing TAB dataset. **********************************************************************/ static int CreateIndex(const char *pszSrcFname, const char *pszField) { IMapInfoFile *poSrcFile = NULL; int nFeatureId, iField; TABFeature *poFeature; TABINDFile *poINDFile; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poSrcFile = IMapInfoFile::SmartOpen(pszSrcFname)) == NULL) { printf("Failed to open %s\n", pszSrcFname); return -1; } if (poSrcFile->GetFileClass() != TABFC_TABFile) { printf("Indexes cannot be added to this type of TAB datasets\n"); poSrcFile->Close(); delete poSrcFile; return -1; } /*--------------------------------------------------------------------- * Make sure field exists and is not already indexed *--------------------------------------------------------------------*/ OGRFeatureDefn *poDefn = poSrcFile->GetLayerDefn(); if ( poDefn == NULL || (iField = poDefn->GetFieldIndex(pszField)) == -1 || poSrcFile->IsFieldIndexed(iField)) { printf("Cannot create index: field '%s' not found or is already indexed.\n", pszField); poSrcFile->Close(); delete poSrcFile; return -1; } /*--------------------------------------------------------------------- * Things seem OK... open IND file for update * (Note that TABINDFile automagically adjusts file extension) *--------------------------------------------------------------------*/ poINDFile = new TABINDFile; if ( poINDFile->Open(pszSrcFname, "r+", TRUE) != 0 && poINDFile->Open(pszSrcFname, "w", TRUE) != 0) { printf("Unable to create IND file for %s.\n", pszSrcFname); delete poINDFile; poSrcFile->Close(); delete poSrcFile; return -1; } int nNewIndexNo = -1; OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField); TABFieldType eFieldType = poSrcFile->GetNativeFieldType(iField); if (poFieldDefn == NULL || (nNewIndexNo = poINDFile->CreateIndex(eFieldType, poFieldDefn->GetWidth()) ) < 1) { // Failed... an error has already been reported. delete poINDFile; poSrcFile->Close(); delete poSrcFile; return -1; } printf("Index number %d will be created for field %s...\n\n" "This program does not update the TAB header file (yet!) so you \n" "should edit %s and add 'Index %d' at the end of the definition \n" "of field %s.\n\n", nNewIndexNo, pszField, pszSrcFname, nNewIndexNo, pszField); /*--------------------------------------------------------------------- * Add index entries until we reach EOF *--------------------------------------------------------------------*/ nFeatureId = -1; while ( (nFeatureId = poSrcFile->GetNextFeatureId(nFeatureId)) != -1 ) { poFeature = poSrcFile->GetFeatureRef(nFeatureId); if (poFeature) { GByte *pKey = NULL; switch(eFieldType) { case TABFChar: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsString(iField)); break; case TABFInteger: case TABFSmallInt: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsInteger(iField)); break; case TABFDecimal: case TABFFloat: case TABFLogical: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsDouble(iField)); break; default: case TABFDate: CPLAssert(FALSE); // Unsupported for now. } if (poINDFile->AddEntry(nNewIndexNo, pKey, nFeatureId) != 0) return -1; } else break; // GetFeatureRef() failed: Abort the loop } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poINDFile->Close(); delete poINDFile; poSrcFile->Close(); delete poSrcFile; MITABFreeCoordSysTable(); return 0; }