@@ -1966,36 +1966,74 @@ bool QgsOgrProvider::createSpatialIndex()
1966
1966
if ( !doInitialActionsForEdition () )
1967
1967
return false ;
1968
1968
1969
- if ( mGDALDriverName != QLatin1String ( " ESRI Shapefile" ) )
1970
- return false ;
1971
-
1972
1969
QByteArray layerName = mOgrOrigLayer ->name ();
1970
+ if ( mGDALDriverName == QLatin1String ( " ESRI Shapefile" ) )
1971
+ {
1972
+ QByteArray sql = QByteArray ( " CREATE SPATIAL INDEX ON " ) + quotedIdentifier ( layerName ); // quote the layer name so spaces are handled
1973
+ QgsDebugMsg ( QString ( " SQL: %1" ).arg ( QString::fromUtf8 ( sql ) ) );
1974
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( sql );
1973
1975
1974
- QByteArray sql = QByteArray ( " CREATE SPATIAL INDEX ON " ) + quotedIdentifier ( layerName ); // quote the layer name so spaces are handled
1975
- QgsDebugMsg ( QString ( " SQL: %1" ).arg ( QString::fromUtf8 ( sql ) ) );
1976
- mOgrOrigLayer ->ExecuteSQLNoReturn ( sql );
1976
+ QFileInfo fi ( mFilePath ); // to get the base name
1977
+ // find out, if the .qix file is there
1978
+ return QFileInfo::exists ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .qix" ) );
1979
+ }
1980
+ else if ( mGDALDriverName == QLatin1String ( " GPKG" ) ||
1981
+ mGDALDriverName == QLatin1String ( " SQLite" ) )
1982
+ {
1983
+ QMutex *mutex = nullptr ;
1984
+ OGRLayerH layer = mOgrOrigLayer ->getHandleAndMutex ( mutex );
1985
+ QByteArray sql = QByteArray ( " SELECT CreateSpatialIndex(" + quotedIdentifier ( layerName ) + " ,"
1986
+ + quotedIdentifier ( OGR_L_GetGeometryColumn ( layer ) ) + " ) " ); // quote the layer name so spaces are handled
1987
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( sql );
1988
+ return true ;
1989
+ }
1990
+ return false ;
1991
+ }
1977
1992
1978
- QFileInfo fi ( mFilePath ); // to get the base name
1979
- // find out, if the .qix file is there
1980
- QFile indexfile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .qix" ) );
1981
- return indexfile.exists ();
1993
+ QString createIndexName ( QString tableName, QString field )
1994
+ {
1995
+ QRegularExpression safeExp ( QStringLiteral ( " [^a-zA-Z0-9]" ) );
1996
+ tableName.replace ( safeExp, QStringLiteral ( " _" ) );
1997
+ field.replace ( safeExp, QStringLiteral ( " _" ) );
1998
+ return tableName + " _" + field + " _idx" ;
1982
1999
}
1983
2000
1984
2001
bool QgsOgrProvider::createAttributeIndex ( int field )
1985
2002
{
2003
+ if ( field < 0 || field >= mAttributeFields .count () )
2004
+ return false ;
2005
+
1986
2006
if ( !doInitialActionsForEdition () )
1987
2007
return false ;
1988
2008
1989
2009
QByteArray quotedLayerName = quotedIdentifier ( mOgrOrigLayer ->name () );
1990
- QByteArray dropSql = " DROP INDEX ON " + quotedLayerName;
1991
- mOgrOrigLayer ->ExecuteSQLNoReturn ( dropSql );
1992
- QByteArray createSql = " CREATE INDEX ON " + quotedLayerName + " USING " + textEncoding ()->fromUnicode ( fields ().at ( field ).name () );
1993
- mOgrOrigLayer ->ExecuteSQLNoReturn ( createSql );
2010
+ if ( mGDALDriverName == QLatin1String ( " GPKG" ) ||
2011
+ mGDALDriverName == QLatin1String ( " SQLite" ) )
2012
+ {
2013
+ if ( field == 0 && mFirstFieldIsFid )
2014
+ {
2015
+ // already an index on this field, no need to re-created
2016
+ return false ;
2017
+ }
2018
+
2019
+ QString indexName = createIndexName ( mOgrOrigLayer ->name (), fields ().at ( field ).name () );
2020
+ QByteArray createSql = " CREATE INDEX IF NOT EXISTS " + textEncoding ()->fromUnicode ( indexName ) + " ON " + quotedLayerName + " (" + textEncoding ()->fromUnicode ( fields ().at ( field ).name () ) + " )" ;
2021
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( createSql );
2022
+ return true ;
2023
+ }
2024
+ else
2025
+ {
2026
+ QByteArray dropSql = " DROP INDEX ON " + quotedLayerName;
2027
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( dropSql );
2028
+ QByteArray createSql = " CREATE INDEX ON " + quotedLayerName + " USING " + textEncoding ()->fromUnicode ( fields ().at ( field ).name () );
2029
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( createSql );
1994
2030
1995
- QFileInfo fi ( mFilePath ); // to get the base name
1996
- // find out, if the .idm file is there
1997
- QFile indexfile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .idm" ) );
1998
- return indexfile.exists ();
2031
+ QFileInfo fi ( mFilePath ); // to get the base name
2032
+ // find out, if the .idm/.ind file is there
2033
+ QString idmFile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .idm" ) );
2034
+ QString indFile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .ind" ) );
2035
+ return QFile::exists ( idmFile ) || QFile::exists ( indFile );
2036
+ }
1999
2037
}
2000
2038
2001
2039
bool QgsOgrProvider::deleteFeatures ( const QgsFeatureIds &id )
@@ -2241,6 +2279,12 @@ void QgsOgrProvider::computeCapabilities()
2241
2279
ability &= ~( AddAttributes | DeleteFeatures );
2242
2280
}
2243
2281
}
2282
+ else if ( mGDALDriverName == QLatin1String ( " GPKG" ) ||
2283
+ mGDALDriverName == QLatin1String ( " SQLite" ) )
2284
+ {
2285
+ ability |= CreateSpatialIndex;
2286
+ ability |= CreateAttributeIndex;
2287
+ }
2244
2288
2245
2289
/* Curve geometries are available in some drivers starting with GDAL 2.0 */
2246
2290
if ( mOgrLayer ->TestCapability ( " CurveGeometries" ) )
0 commit comments