[FEATURE] oracle provider: add support for renaming attributes

This commit is contained in:
Juergen E. Fischer 2016-06-02 11:38:02 +02:00
parent 006b581870
commit 6c878f9554
3 changed files with 157 additions and 43 deletions

View File

@ -750,9 +750,21 @@ void QgsFieldsProperties::attributesListCellChanged( int row, int column )
else if ( column == attrNameCol && mLayer && mLayer->isEditable() )
{
QTableWidgetItem *nameItem = mFieldsList->item( row, column );
if ( nameItem && !nameItem->text().isEmpty() )
if ( !nameItem ||
nameItem->text().isEmpty() ||
!mLayer->fields().exists( row ) ||
mLayer->fields().at( row ).name() == nameItem->text() )
return;
mLayer->beginEditCommand( tr( "Rename attribute" ) );
if ( mLayer->renameAttribute( row, nameItem->text() ) )
{
mLayer->renameAttribute( row, nameItem->text() );
mLayer->endEditCommand();
}
else
{
mLayer->destroyEditCommand();
QMessageBox::critical( this, tr( "Failed to rename field" ), tr( "Failed to rename field to '%1'. Is the field name unique?" ).arg( nameItem->text() ) );
}
}
}

View File

@ -764,6 +764,7 @@ bool QgsOracleProvider::hasSufficientPermsAndCapabilities()
| QgsVectorDataProvider::AddAttributes
| QgsVectorDataProvider::DeleteAttributes
| QgsVectorDataProvider::ChangeGeometries
| QgsVectorDataProvider::RenameAttributes
;
}
else if ( exec( qry, QString( "SELECT privilege FROM all_tab_privs WHERE table_schema=%1 AND table_name=%2 AND privilege IN ('DELETE','UPDATE','INSERT','ALTER TABLE')" )
@ -788,7 +789,7 @@ bool QgsOracleProvider::hasSufficientPermsAndCapabilities()
}
else if ( priv == "ALTER TABLE" )
{
mEnabledCapabilities |= QgsVectorDataProvider::AddAttributes | QgsVectorDataProvider::DeleteAttributes;
mEnabledCapabilities |= QgsVectorDataProvider::AddAttributes | QgsVectorDataProvider::DeleteAttributes | QgsVectorDataProvider::RenameAttributes;
}
}
@ -1006,6 +1007,9 @@ bool QgsOracleProvider::uniqueData( QString query, QString colName )
// Returns the minimum value of an attribute
QVariant QgsOracleProvider::minimumValue( int index )
{
if ( !mConnection )
return QVariant( QString::null );
try
{
// get the field name
@ -1044,6 +1048,9 @@ QVariant QgsOracleProvider::minimumValue( int index )
// Returns the list of unique values of an attribute
void QgsOracleProvider::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
{
if ( !mConnection )
return;
uniqueValues.clear();
try
@ -1090,6 +1097,9 @@ void QgsOracleProvider::uniqueValues( int index, QList<QVariant> &uniqueValues,
// Returns the maximum value of an attribute
QVariant QgsOracleProvider::maximumValue( int index )
{
if ( !mConnection )
return QVariant();
try
{
// get the field name
@ -1165,7 +1175,7 @@ bool QgsOracleProvider::addFeatures( QgsFeatureList &flist )
if ( flist.size() == 0 )
return true;
if ( mIsQuery )
if ( mIsQuery || !mConnection )
return false;
bool returnvalue = true;
@ -1414,7 +1424,7 @@ bool QgsOracleProvider::deleteFeatures( const QgsFeatureIds & id )
{
bool returnvalue = true;
if ( mIsQuery )
if ( mIsQuery || !mConnection )
return false;
QSqlDatabase db( *mConnection );
@ -1464,7 +1474,7 @@ bool QgsOracleProvider::addAttributes( const QList<QgsField> &attributes )
{
bool returnvalue = true;
if ( mIsQuery )
if ( mIsQuery || !mConnection )
return false;
QSqlDatabase db( *mConnection );
@ -1545,7 +1555,7 @@ bool QgsOracleProvider::deleteAttributes( const QgsAttributeIds& ids )
{
bool returnvalue = true;
if ( mIsQuery )
if ( mIsQuery || !mConnection )
return false;
QSqlDatabase db( *mConnection );
@ -1604,11 +1614,89 @@ bool QgsOracleProvider::deleteAttributes( const QgsAttributeIds& ids )
return returnvalue;
}
bool QgsOracleProvider::renameAttributes( const QgsFieldNameMap &renamedAttributes )
{
if ( mIsQuery || !mConnection )
return false;
QgsFieldNameMap::const_iterator renameIt = renamedAttributes.constBegin();
for ( ; renameIt != renamedAttributes.constEnd(); ++renameIt )
{
int fieldIndex = renameIt.key();
if ( fieldIndex < 0 || fieldIndex >= mAttributeFields.count() )
{
pushError( tr( "Invalid attribute index: %1" ).arg( fieldIndex ) );
return false;
}
if ( mAttributeFields.indexFromName( renameIt.value() ) >= 0 )
{
//field name already in use
pushError( tr( "Error renaming field %1: name '%2' already exists" ).arg( fieldIndex ).arg( renameIt.value() ) );
return false;
}
}
QSqlDatabase db( *mConnection );
bool returnvalue = true;
try
{
QSqlQuery qry( db );
if ( !db.transaction() )
{
throw OracleException( tr( "Could not start transaction" ), db );
}
qry.finish();
for ( renameIt = renamedAttributes.constBegin(); renameIt != renamedAttributes.constEnd(); ++renameIt )
{
QString src( mAttributeFields.at( renameIt.key() ).name() );
if ( !exec( qry, QString( "ALTER TABLE %1 RENAME COLUMN %2 TO %3" )
.arg( mQuery,
quotedIdentifier( src ),
quotedIdentifier( renameIt.value() ) ) ) )
{
throw OracleException( tr( "Renaming column %1 to %2 failed" )
.arg( quotedIdentifier( src ),
quotedIdentifier( renameIt.value() ) ),
qry );
}
}
if ( !db.commit() )
{
throw OracleException( tr( "Could not commit transaction" ), db );
}
}
catch ( OracleException &e )
{
pushError( tr( "Oracle error while renaming attributes: %1" ).arg( e.errorMessage() ) );
if ( !db.rollback() )
{
QgsMessageLog::logMessage( tr( "Could not rollback transaction" ), tr( "Oracle" ) );
}
returnvalue = false;
}
if ( !loadFields() )
{
QgsMessageLog::logMessage( tr( "Could not reload fields." ), tr( "Oracle" ) );
returnvalue = false;
}
return returnvalue;
}
bool QgsOracleProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map )
{
bool returnvalue = true;
if ( mIsQuery )
if ( mIsQuery || !mConnection )
return false;
if ( attr_map.isEmpty() )
@ -1897,7 +1985,7 @@ bool QgsOracleProvider::changeGeometryValues( const QgsGeometryMap &geometry_map
{
QgsDebugMsg( "entering." );
if ( mIsQuery || mGeometryColumn.isNull() )
if ( mIsQuery || mGeometryColumn.isNull() || !mConnection )
return false;
QSqlDatabase db( *mConnection );
@ -1963,6 +2051,9 @@ int QgsOracleProvider::capabilities() const
bool QgsOracleProvider::setSubsetString( const QString& theSQL, bool updateFeatureCount )
{
if ( !mConnection )
return false;
QString prevWhere = mSqlWhereClause;
mSqlWhereClause = theSQL.trimmed();
@ -2014,7 +2105,7 @@ bool QgsOracleProvider::setSubsetString( const QString& theSQL, bool updateFeatu
*/
long QgsOracleProvider::featureCount() const
{
if ( mFeaturesCounted >= 0 )
if ( mFeaturesCounted >= 0 || !mConnection )
return mFeaturesCounted;
// get total number of features
@ -2053,7 +2144,7 @@ long QgsOracleProvider::featureCount() const
QgsRectangle QgsOracleProvider::extent()
{
if ( mGeometryColumn.isNull() )
if ( mGeometryColumn.isNull() || !mConnection )
return QgsRectangle();
if ( mLayerExtent.isEmpty() )
@ -2321,6 +2412,9 @@ bool QgsOracleProvider::getGeometryDetails()
bool QgsOracleProvider::createSpatialIndex()
{
if ( !mConnection )
return false;
QSqlQuery qry( *mConnection );
if ( !crs().geographicFlag() )
@ -2844,6 +2938,9 @@ QgsCoordinateReferenceSystem QgsOracleProvider::crs()
{
QgsCoordinateReferenceSystem srs;
if ( !mConnection )
return srs;
QSqlQuery qry( *mConnection );
// apparently some EPSG codes don't have the auth_name setup in cs_srs
@ -3299,7 +3396,7 @@ QGISEXTERN QString loadStyle( const QString &uri, QString &errCause )
if ( !conn )
{
errCause = QObject::tr( "Could not connect to database" );
return false;
return QString::null;
}
QSqlQuery qry( *conn );

View File

@ -80,19 +80,19 @@ class QgsOracleProvider : public QgsVectorDataProvider
//! Destructor
virtual ~QgsOracleProvider();
virtual QgsAbstractFeatureSource* featureSource() const;
virtual QgsAbstractFeatureSource *featureSource() const override;
/**
* Returns the permanent storage type for this layer as a friendly name.
* Returns the permanent storage type for this layer as a friendly name.
*/
virtual QString storageType() const;
virtual QString storageType() const override;
/** Get the QgsCoordinateReferenceSystem for this layer
* @note Must be reimplemented by each provider.
* If the provider isn't capable of returning
* its projection an empty srs will be returned
*/
virtual QgsCoordinateReferenceSystem crs();
virtual QgsCoordinateReferenceSystem crs() override;
/** Get the feature type. This corresponds to
* WKBPoint,
@ -103,7 +103,7 @@ class QgsOracleProvider : public QgsVectorDataProvider
* WKBMultiPolygon
* as defined in qgis.h
*/
QGis::WkbType geometryType() const;
QGis::WkbType geometryType() const override;
/** Return the number of layers for the current data source
* @note Should this be subLayerCount() instead?
@ -113,7 +113,7 @@ class QgsOracleProvider : public QgsVectorDataProvider
/**
* Get the number of features in the layer
*/
long featureCount() const;
long featureCount() const override;
/**
* Get the number of fields in the layer
@ -133,11 +133,11 @@ class QgsOracleProvider : public QgsVectorDataProvider
/** Return the extent for this data layer
*/
virtual QgsRectangle extent();
virtual QgsRectangle extent() override;
/** Update the extent
*/
virtual void updateExtents();
virtual void updateExtents() override;
/** Determine the fields making up the primary key
*/
@ -147,13 +147,13 @@ class QgsOracleProvider : public QgsVectorDataProvider
* Get the field information for the layer
* @return vector of QgsField objects
*/
const QgsFields &fields() const;
const QgsFields &fields() const override;
/**
* Return a short comment for the data that this provider is
* providing access to (e.g. the comment for oracle table).
*/
QString dataComment() const;
QString dataComment() const override;
/** Reset the layer
*/
@ -161,53 +161,58 @@ class QgsOracleProvider : public QgsVectorDataProvider
/** Returns the minimum value of an attribute
* @param index the index of the attribute */
QVariant minimumValue( int index );
QVariant minimumValue( int index ) override;
/** Returns the maximum value of an attribute
* @param index the index of the attribute */
QVariant maximumValue( int index );
QVariant maximumValue( int index ) override;
/** Return the unique values of an attribute
* @param index the index of the attribute
* @param values reference to the list of unique values */
virtual void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
virtual void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 ) override;
/** Returns true if layer is valid
*/
bool isValid();
bool isValid() override;
QgsAttributeList pkAttributeIndexes() { return mPrimaryKeyAttrs; }
QgsAttributeList pkAttributeIndexes() override { return mPrimaryKeyAttrs; }
/** Returns the default value for field specified by @c fieldName */
QVariant defaultValue( QString fieldName, QString tableName = QString::null, QString schemaName = QString::null );
/** Returns the default value for field specified by @c fieldId */
QVariant defaultValue( int fieldId );
QVariant defaultValue( int fieldId ) override;
/** Adds a list of features
@return true in case of success and false in case of failure*/
bool addFeatures( QgsFeatureList & flist );
bool addFeatures( QgsFeatureList &flist ) override;
/** Deletes a list of features
@param id list of feature ids
@return true in case of success and false in case of failure*/
bool deleteFeatures( const QgsFeatureIds & id );
bool deleteFeatures( const QgsFeatureIds & id ) override;
/** Adds new attributes
@param name map with attribute name as key and type as value
@return true in case of success and false in case of failure*/
bool addAttributes( const QList<QgsField> &attributes );
bool addAttributes( const QList<QgsField> &attributes ) override;
/** Deletes existing attributes
@param names of the attributes to delete
@param ids ids of attributes to delete
@return true in case of success and false in case of failure*/
bool deleteAttributes( const QgsAttributeIds & name );
bool deleteAttributes( const QgsAttributeIds &ids ) override;
/** Renames existing attributes
@param renamedAttributes attributes to rename
@return true in case of success and false in case of failure*/
bool renameAttributes( const QgsFieldNameMap& renamedAttributes ) override;
/** Changes attribute values of existing features
@param attr_map a map containing the new attributes. The integer is the feature id,
the first QString is the attribute name and the second one is the new attribute value
@return true in case of success and false in case of failure*/
bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
/**
Changes geometries of existing features
@ -215,25 +220,25 @@ class QgsOracleProvider : public QgsVectorDataProvider
the second map parameter being the new geometries themselves
@return true in case of success and false in case of failure
*/
bool changeGeometryValues( const QgsGeometryMap & geometry_map );
bool changeGeometryValues( const QgsGeometryMap &geometry_map ) override;
/** Tries to create an spatial index file for faster access if only a subset of the features is required
@return true in case of success*/
bool createSpatialIndex();
bool createSpatialIndex() override;
//! Get the table name associated with this provider instance
QString getTableName();
/** Accessor for sql where clause used to limit dataset */
QString subsetString();
QString subsetString() override;
/** Mutator for sql where clause used to limit dataset size */
bool setSubsetString( const QString& theSQL, bool updateFeatureCount = true );
bool setSubsetString( const QString& theSQL, bool updateFeatureCount = true ) override;
virtual bool supportsSubsetString() { return true; }
virtual bool supportsSubsetString() override { return true; }
/** Returns a bitmask containing the supported capabilities*/
int capabilities() const;
int capabilities() const override;
/** Return a provider name
*
@ -249,7 +254,7 @@ class QgsOracleProvider : public QgsVectorDataProvider
* anything strange with regards to their name or description?
*
*/
QString name() const;
QString name() const override;
/** Return description
*
@ -262,12 +267,12 @@ class QgsOracleProvider : public QgsVectorDataProvider
* anything strange with regards to their name or description?
*
*/
QString description() const;
QString description() const override;
/**
* Query the provider for features specified in request.
*/
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() );
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override;
static bool exec( QSqlQuery &qry, QString sql );