@@ -1966,36 +1966,70 @@ 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
+ QMutexLocker locker ( mutex );
1986
+
1987
+ QByteArray sql = QByteArray ( " SELECT CreateSpatialIndex(" + quotedIdentifier ( layerName ) + " ,"
1988
+ + quotedIdentifier ( OGR_L_GetGeometryColumn ( layer ) ) + " ) " ); // quote the layer name so spaces are handled
1989
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( sql );
1990
+ return true ;
1991
+ }
1992
+ return false ;
1993
+ }
1977
1994
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 ();
1995
+ QString createIndexName ( QString tableName, QString field )
1996
+ {
1997
+ QRegularExpression safeExp ( QStringLiteral ( " [^a-zA-Z0-9]" ) );
1998
+ tableName.replace ( safeExp, QStringLiteral ( " _" ) );
1999
+ field.replace ( safeExp, QStringLiteral ( " _" ) );
2000
+ return tableName + " _" + field + " _idx" ;
1982
2001
}
1983
2002
1984
2003
bool QgsOgrProvider::createAttributeIndex ( int field )
1985
2004
{
2005
+ if ( field < 0 || field >= mAttributeFields .count () )
2006
+ return false ;
2007
+
1986
2008
if ( !doInitialActionsForEdition () )
1987
2009
return false ;
1988
2010
1989
2011
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 );
2012
+ if ( mGDALDriverName == QLatin1String ( " GPKG" ) ||
2013
+ mGDALDriverName == QLatin1String ( " SQLite" ) )
2014
+ {
2015
+ QString indexName = createIndexName ( mOgrOrigLayer ->name (), fields ().at ( field ).name () );
2016
+ QByteArray createSql = " CREATE INDEX IF NOT EXISTS " + textEncoding ()->fromUnicode ( indexName ) + " ON " + quotedLayerName + " (" + textEncoding ()->fromUnicode ( fields ().at ( field ).name () ) + " )" ;
2017
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( createSql );
2018
+ return true ;
2019
+ }
2020
+ else
2021
+ {
2022
+ QByteArray dropSql = " DROP INDEX ON " + quotedLayerName;
2023
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( dropSql );
2024
+ QByteArray createSql = " CREATE INDEX ON " + quotedLayerName + " USING " + textEncoding ()->fromUnicode ( fields ().at ( field ).name () );
2025
+ mOgrOrigLayer ->ExecuteSQLNoReturn ( createSql );
1994
2026
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 ();
2027
+ QFileInfo fi ( mFilePath ); // to get the base name
2028
+ // find out, if the .idm/.ind file is there
2029
+ QString idmFile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .idm" ) );
2030
+ QString indFile ( fi.path ().append ( ' /' ).append ( fi.completeBaseName () ).append ( " .ind" ) );
2031
+ return QFile::exists ( idmFile ) || QFile::exists ( indFile );
2032
+ }
1999
2033
}
2000
2034
2001
2035
bool QgsOgrProvider::deleteFeatures ( const QgsFeatureIds &id )
@@ -2241,6 +2275,12 @@ void QgsOgrProvider::computeCapabilities()
2241
2275
ability &= ~( AddAttributes | DeleteFeatures );
2242
2276
}
2243
2277
}
2278
+ else if ( mGDALDriverName == QLatin1String ( " GPKG" ) ||
2279
+ mGDALDriverName == QLatin1String ( " SQLite" ) )
2280
+ {
2281
+ ability |= CreateSpatialIndex;
2282
+ ability |= CreateAttributeIndex;
2283
+ }
2244
2284
2245
2285
/* Curve geometries are available in some drivers starting with GDAL 2.0 */
2246
2286
if ( mOgrLayer ->TestCapability ( " CurveGeometries" ) )
0 commit comments