Skip to content

Commit 11f28fc

Browse files
committed
[GRASS] create new table on add column if it does not exist
1 parent e0eaebc commit 11f28fc

File tree

2 files changed

+136
-63
lines changed

2 files changed

+136
-63
lines changed

src/providers/grass/qgsgrassvectormaplayer.cpp

Lines changed: 131 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,12 @@ void QgsGrassVectorMapLayer::executeSql( const QString &sql, QString &error )
523523
}
524524

525525
db_free_string( &dbstr ); //if ( index < 0 || index > )
526-
QgsField field;
527526
return;
528527
}
529528

530-
void QgsGrassVectorMapLayer::createTable( const QString &key, const QString &columns, QString &error )
529+
void QgsGrassVectorMapLayer::createTable( const QgsFields &fields, QString &error )
531530
{
532-
QgsDebugMsg( QString( "key = %1" ).arg( key ) );
533-
534-
// TODO: use QgsGrass::createTable
531+
QgsDebugMsg( QString( "fields.size() = %1" ).arg( fields.size() ) );
535532

536533
// Read attributes
537534
if ( mFieldInfo )
@@ -565,95 +562,139 @@ void QgsGrassVectorMapLayer::createTable( const QString &key, const QString &col
565562
mDriver = openDriver( error );
566563
if ( !error.isEmpty() )
567564
{
565+
QgsDebugMsg( error );
566+
mFieldInfo = 0;
568567
return;
569568
}
570569

571570
QgsDebugMsg( "Database opened -> create table" );
572571

573-
dbString dbstr;
574-
db_init_string( &dbstr );
575-
576-
QString query = QString( "CREATE TABLE %1 ( %2 )" ).arg( mFieldInfo->table ).arg( columns );
577-
db_set_string( &dbstr, query.toLatin1().data() );
578-
579-
QgsDebugMsg( QString( "query: %1" ).arg( db_get_string( &dbstr ) ) );
580-
581-
int ret = db_execute_immediate( mDriver, &dbstr );
582-
if ( ret != DB_OK )
572+
QgsFields catFields;
573+
catFields.append( QgsField( mFieldInfo->key, QVariant::Int, "integer" ) );
574+
for ( int i = 0; i < fields.size(); i++ )
583575
{
584-
error = QString::fromLatin1( db_get_error_msg() );
585-
QgsDebugMsg( error );
576+
catFields.append( fields[i] );
586577
}
587578

588-
db_free_string( &dbstr );
579+
try
580+
{
581+
QgsGrass::createTable( mDriver, mFieldInfo->table, catFields );
589582

590-
if ( !error.isEmpty() )
583+
}
584+
catch ( QgsGrass::Exception &e )
591585
{
586+
error = QString( e.what() );
587+
QgsDebugMsg( error );
588+
db_close_database_shutdown_driver( mDriver );
589+
mFieldInfo = 0;
592590
return;
593591
}
594592

595-
ret = Vect_map_add_dblink( mMap->map(), mField, 0, mFieldInfo->table, key.toLatin1().data(),
596-
mFieldInfo->database, mFieldInfo->driver );
597-
598-
if ( ret == -1 )
593+
if ( mFieldInfo )
599594
{
600-
QgsDebugMsg( "Error: Cannot add dblink" );
601-
error = tr( "Cannot create link to the table. The table was created!" );
595+
int ret = Vect_map_add_dblink( mMap->map(), mField, 0, mFieldInfo->table, mFieldInfo->key,
596+
mFieldInfo->database, mFieldInfo->driver );
597+
598+
if ( ret == -1 )
599+
{
600+
error = tr( "Cannot create link to the table." );
601+
QgsDebugMsg( error );
602+
// delete created table
603+
QString query = QString( "DROP TABLE %1" ).arg( mFieldInfo->table );
604+
QString dropError;
605+
executeSql( query, dropError );
606+
if ( !dropError.isEmpty() )
607+
{
608+
QgsDebugMsg( dropError );
609+
error += " " + tr( "Created table %1 could not be deleted" ).arg( mFieldInfo->table ) + " " + dropError;
610+
QgsDebugMsg( error );
611+
}
612+
db_close_database_shutdown_driver( mDriver );
613+
mFieldInfo = 0;
614+
}
602615
}
603616

604-
return;
617+
if ( mFieldInfo )
618+
{
619+
for ( int i = 0; i < fields.size(); i++ )
620+
{
621+
mTableFields.append( fields[i] );
622+
mAttributeFields.append( fields[i] );
623+
}
624+
insertCats( error );
625+
if ( !error.isEmpty() )
626+
{
627+
QgsDebugMsg( error );
628+
}
629+
}
630+
QgsDebugMsg( "Table successfully created" );
605631
}
606632

607633
void QgsGrassVectorMapLayer::addColumn( const QgsField &field, QString &error )
608634
{
609635
QgsDebugMsg( QString( "field.name() = %1 field.type() = %2" ).arg( field.name() ).arg( field.type() ) );
610636

611-
QString type = field.typeName();
612-
if ( type == "varchar" )
637+
if ( !mFieldInfo ) // table does not exist yet
613638
{
614-
if ( field.length() > 0 )
639+
// create new table
640+
QgsFields fields;
641+
fields.append( field );
642+
createTable( fields, error );
643+
if ( !error.isEmpty() )
615644
{
616-
type = QString( "%1(%2)" ).arg( type ).arg( field.length() );
645+
QgsDebugMsg( error );
646+
return;
617647
}
618648
}
619-
QString query = QString( "ALTER TABLE %1 ADD COLUMN %2 %3" ).arg( mFieldInfo->table ).arg( field.name() ).arg( type );
620-
executeSql( query, error );
621-
622-
if ( error.isEmpty() )
649+
else // the table alread exists
623650
{
624-
mTableFields.append( field );
651+
QString type = field.typeName();
652+
if ( type == "varchar" )
653+
{
654+
if ( field.length() > 0 )
655+
{
656+
type = QString( "%1(%2)" ).arg( type ).arg( field.length() );
657+
}
658+
}
659+
QString query = QString( "ALTER TABLE %1 ADD COLUMN %2 %3" ).arg( mFieldInfo->table ).arg( field.name() ).arg( type );
660+
executeSql( query, error );
625661

626-
int index = mAttributeFields.indexFromName( field.name() );
627-
if ( index != -1 )
662+
if ( error.isEmpty() )
628663
{
629-
// the column is already in attributes (delete column undo)
630-
QgsDebugMsg( "insert old values" );
631-
QStringList errors;
632-
Q_FOREACH ( int cat, mAttributes.keys() )
664+
mTableFields.append( field );
665+
666+
int index = mAttributeFields.indexFromName( field.name() );
667+
if ( index != -1 )
633668
{
634-
QVariant value = mAttributes.value( cat ).value( index );
635-
QString valueString = quotedValue( value );
636-
QString query = QString( "UPDATE %1 SET %2 = %3" ).arg( mFieldInfo->table ).arg( field.name() ).arg( valueString );
637-
QString err;
638-
executeSql( query, err );
639-
if ( !err.isEmpty() )
669+
// the column is already in attributes (delete column undo)
670+
QgsDebugMsg( "insert old values" );
671+
QStringList errors;
672+
Q_FOREACH ( int cat, mAttributes.keys() )
640673
{
641-
errors << err;
642-
}
643-
if ( errors.size() > 5 )
644-
{
645-
error = tr( "Errors updating restored column, update interrupted" ) + " : " + errors.join( "; " );
646-
break;
674+
QVariant value = mAttributes.value( cat ).value( index );
675+
QString valueString = quotedValue( value );
676+
QString query = QString( "UPDATE %1 SET %2 = %3" ).arg( mFieldInfo->table ).arg( field.name() ).arg( valueString );
677+
QString err;
678+
executeSql( query, err );
679+
if ( !err.isEmpty() )
680+
{
681+
errors << err;
682+
}
683+
if ( errors.size() > 5 )
684+
{
685+
error = tr( "Errors updating restored column, update interrupted" ) + " : " + errors.join( "; " );
686+
break;
687+
}
647688
}
648689
}
649-
}
650-
else
651-
{
652-
// really new column
653-
mAttributeFields.append( field );
654-
Q_FOREACH ( int cat, mAttributes.keys() )
690+
else
655691
{
656-
mAttributes[cat].append( QVariant() );
692+
// really new column
693+
mAttributeFields.append( field );
694+
Q_FOREACH ( int cat, mAttributes.keys() )
695+
{
696+
mAttributes[cat].append( QVariant() );
697+
}
657698
}
658699
}
659700
}
@@ -718,12 +759,42 @@ void QgsGrassVectorMapLayer::deleteColumn( const QgsField &field, QString &error
718759
}
719760
}
720761

762+
void QgsGrassVectorMapLayer::insertCats( QString &error )
763+
{
764+
int cidxIndex = Vect_cidx_get_field_index( map()->map(), mField );
765+
if ( cidxIndex >= 0 ) // cats attached to lines already exist
766+
{
767+
int nCats = Vect_cidx_get_num_cats_by_index( map()->map(), cidxIndex );
768+
QgsDebugMsg( QString( "nCats = %1" ).arg( nCats ) );
769+
for ( int i = 0; i < nCats; i++ )
770+
{
771+
int cat;
772+
Vect_cidx_get_cat_by_index( map()->map(), cidxIndex, i, &cat, 0, 0 );
773+
insertAttributes( cat, error );
774+
if ( !error.isEmpty() )
775+
{
776+
QgsDebugMsg( error );
777+
break;
778+
}
779+
}
780+
}
781+
}
782+
721783
void QgsGrassVectorMapLayer::insertAttributes( int cat, QString &error )
722784
{
723785
QgsDebugMsg( QString( "mField = %1 cat = %2" ).arg( mField ).arg( cat ) );
724786

725787
QString query = QString( "INSERT INTO %1 ( %2 ) VALUES ( %3 )" ).arg( mFieldInfo->table ).arg( mFieldInfo->key ).arg( cat );
726788
executeSql( query, error );
789+
if ( error.isEmpty() )
790+
{
791+
QList<QVariant> values;
792+
for ( int i = 0; i < mAttributeFields.size(); i++ )
793+
{
794+
values << QVariant();
795+
}
796+
mAttributes[cat] = values;
797+
}
727798
}
728799

729800
void QgsGrassVectorMapLayer::deleteAttribute( int cat, QString &error )

src/providers/grass/qgsgrassvectormaplayer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
112112
void isOrphan( int cat, int &orphan, QString &error );
113113

114114
/** Create table and link vector to this table
115-
* @param columns SQL definition for columns, e.g. cat integer, label varchar(10)
116-
* @return empty string or error message
115+
* @param fields fields to be created without cat (id) field
117116
*/
118-
void createTable( const QString &key, const QString &columns, QString &error );
117+
void createTable( const QgsFields &fields, QString &error );
119118

120119
/** Add column to table
121120
* @param field
@@ -124,6 +123,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
124123

125124
void deleteColumn( const QgsField &field, QString &error );
126125

126+
/** Insert records for all existing categories to the table */
127+
void insertCats( QString &error );
128+
127129
// update fields to real state
128130
void updateFields();
129131

0 commit comments

Comments
 (0)