Showing with 136 additions and 104 deletions.
  1. +7 −9 src/core/qgsvectorlayerimport.cpp
  2. +127 −95 src/providers/spatialite/qgsspatialiteprovider.cpp
  3. +2 −0 src/providers/spatialite/qgsspatialiteprovider.h
16 changes: 7 additions & 9 deletions src/core/qgsvectorlayerimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,21 @@ bool QgsVectorLayerImport::addFeature( QgsFeature& feat )
{
const QgsAttributeMap &attrs = feat.attributeMap();

QgsAttributeMap newAttrs;
QgsFeature newFeat;
newFeat.setGeometry( *feat.geometry() );

for ( QgsAttributeMap::const_iterator it = attrs.begin(); it != attrs.end(); it++ )
{
// add only mapped attributes (un-mapped ones are not present in the
// destination layer)
if ( mOldToNewAttrIdx.contains( it.key() ) )
{
QgsDebugMsgLevel( QString( "moving field from pos %1 to %2" ).arg( it.key() ).arg( mOldToNewAttrIdx.value( it.key() ) ), 3 );
newAttrs.insert( mOldToNewAttrIdx.value( it.key() ), *it );
}
else
{
QgsDebugMsgLevel( QString( "added attr pos %1" ).arg( it.key() ), 3 );
newAttrs.insert( it.key(), *it );
newFeat.addAttribute( mOldToNewAttrIdx.value( it.key() ), *it );
}
}
feat.setAttributeMap( newAttrs );

mFeatureBuffer.append( feat );
mFeatureBuffer.append( newFeat );

if ( mFeatureBuffer.count() >= FEATURE_BUFFER_SIZE )
{
Expand Down
222 changes: 127 additions & 95 deletions src/providers/spatialite/qgsspatialiteprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3262,35 +3262,43 @@ bool QgsSpatiaLiteProvider::prepareStatement(

QString primaryKey = !isQuery ? "ROWID" : quotedIdentifier( mPrimaryKey );

QString sql = QString( "SELECT %1" ).arg( primaryKey );
int colIdx = 1; // column 0 is primary key
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
try
{
const QgsField & fld = field( *it );
QString fieldname = quotedIdentifier( fld.name() );
const QString type = fld.typeName().toLower();
if ( type.contains( "geometry" ) || type.contains( "point" ) ||
type.contains( "line" ) || type.contains( "polygon" ) )
QString sql = QString( "SELECT %1" ).arg( primaryKey );
int colIdx = 1; // column 0 is primary key
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
{
fieldname = QString( "AsText(%1)" ).arg( fieldname );
const QgsField & fld = field( *it );
QString fieldname = quotedIdentifier( fld.name() );
const QString type = fld.typeName().toLower();
if ( type.contains( "geometry" ) || type.contains( "point" ) ||
type.contains( "line" ) || type.contains( "polygon" ) )
{
fieldname = QString( "AsText(%1)" ).arg( fieldname );
}
sql += "," + fieldname;
colIdx++;
}
sql += "," + fieldname;
colIdx++;
}
if ( fetchGeometry )
{
sql += QString( ", AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
mGeomColIdx = colIdx;
}
sql += QString( " FROM %1" ).arg( mQuery );
if ( fetchGeometry )
{
sql += QString( ", AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
mGeomColIdx = colIdx;
}
sql += QString( " FROM %1" ).arg( mQuery );

if ( !whereClause.isEmpty() )
sql += QString( " WHERE %1" ).arg( whereClause );
if ( !whereClause.isEmpty() )
sql += QString( " WHERE %1" ).arg( whereClause );

if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
{
// some error occurred
QgsMessageLog::logMessage( tr( "SQLite error: %2\nSQL: %1" ).arg( sql ).arg( sqlite3_errmsg( sqliteHandle ) ), tr( "SpatiaLite" ) );
return false;
}
}
catch ( SLFieldNotFound )
{
// some error occurred
QgsMessageLog::logMessage( tr( "SQLite error: %2\nSQL: %1" ).arg( sql ).arg( sqlite3_errmsg( sqliteHandle ) ), tr( "SpatiaLite" ) );
rewind();
return false;
}

Expand Down Expand Up @@ -3393,40 +3401,48 @@ QVariant QgsSpatiaLiteProvider::minimumValue( int index )
int columns;
char *errMsg = NULL;
QString minValue;
QString sql;

// get the field name
const QgsField & fld = field( index );
try
{
// get the field name
const QgsField & fld = field( index );

QString sql = QString( "SELECT Min(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );
sql = QString( "SELECT Min(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );

if ( !mSubsetString.isEmpty() )
{
sql += " WHERE ( " + mSubsetString + ")";
}
if ( !mSubsetString.isEmpty() )
{
sql += " WHERE ( " + mSubsetString + ")";
}

ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret != SQLITE_OK )
goto error;
if ( rows < 1 )
;
else
{
for ( i = 1; i <= rows; i++ )
ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret != SQLITE_OK )
goto error;
if ( rows < 1 )
;
else
{
for ( i = 1; i <= rows; i++ )
{
minValue = results[( i * columns ) + 0];
}
}
sqlite3_free_table( results );

if ( minValue.isEmpty() )
{
// NULL or not found
return QVariant( QString::null );
}
else
{
minValue = results[( i * columns ) + 0];
return convertValue( fld.type(), minValue );
}
}
sqlite3_free_table( results );

if ( minValue.isEmpty() )
catch ( SLFieldNotFound )
{
// NULL or not found
return QVariant( QString::null );
}
else
{
return convertValue( fld.type(), minValue );
}

error:
QgsMessageLog::logMessage( tr( "SQLite error: %2\nSQL: %1" ).arg( sql ).arg( errMsg ? errMsg : tr( "unknown cause" ) ), tr( "SpatiaLite" ) );
Expand All @@ -3448,39 +3464,47 @@ QVariant QgsSpatiaLiteProvider::maximumValue( int index )
int columns;
char *errMsg = NULL;
QString maxValue;
QString sql;

// get the field name
const QgsField & fld = field( index );
try
{
// get the field name
const QgsField & fld = field( index );

QString sql = QString( "SELECT Max(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );
sql = QString( "SELECT Max(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );

if ( !mSubsetString.isEmpty() )
{
sql += " WHERE ( " + mSubsetString + ")";
}
if ( !mSubsetString.isEmpty() )
{
sql += " WHERE ( " + mSubsetString + ")";
}

ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret != SQLITE_OK )
goto error;
if ( rows < 1 )
;
else
{
for ( i = 1; i <= rows; i++ )
ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret != SQLITE_OK )
goto error;
if ( rows < 1 )
;
else
{
maxValue = results[( i * columns ) + 0];
for ( i = 1; i <= rows; i++ )
{
maxValue = results[( i * columns ) + 0];
}
}
}
sqlite3_free_table( results );
sqlite3_free_table( results );

if ( maxValue.isEmpty() )
{
// NULL or not found
return QVariant( QString::null );
if ( maxValue.isEmpty() )
{
// NULL or not found
return QVariant( QString::null );
}
else
{
return convertValue( fld.type(), maxValue );
}
}
else
catch ( SLFieldNotFound )
{
return convertValue( fld.type(), maxValue );
return QVariant( QString::null );
}

error:
Expand Down Expand Up @@ -3910,34 +3934,41 @@ bool QgsSpatiaLiteProvider::changeAttributeValues( const QgsChangedAttributesMap
// cycle through the changed attributes of the feature
for ( QgsAttributeMap::const_iterator siter = attrs.begin(); siter != attrs.end(); ++siter )
{
QString fieldName = field( siter.key() ).name();
try
{
QString fieldName = field( siter.key() ).name();

if ( !first )
sql += ",";
else
first = false;
if ( !first )
sql += ",";
else
first = false;

QVariant::Type type = siter->type();
if ( siter->toString().isEmpty() )
{
// assuming to be a NULL value
type = QVariant::Invalid;
}
QVariant::Type type = siter->type();
if ( siter->toString().isEmpty() )
{
// assuming to be a NULL value
type = QVariant::Invalid;
}

if ( type == QVariant::Invalid )
{
// binding a NULL value
sql += QString( "%1=NULL" ).arg( quotedIdentifier( fieldName ) );
}
else if ( type == QVariant::Int || type == QVariant::Double )
{
// binding a NUMERIC value
sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( siter->toString() );
if ( type == QVariant::Invalid )
{
// binding a NULL value
sql += QString( "%1=NULL" ).arg( quotedIdentifier( fieldName ) );
}
else if ( type == QVariant::Int || type == QVariant::Double )
{
// binding a NUMERIC value
sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( siter->toString() );
}
else
{
// binding a TEXT value
sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( quotedValue( siter->toString() ) );
}
}
else
catch ( SLFieldNotFound )
{
// binding a TEXT value
sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( quotedValue( siter->toString() ) );
// Field was missing - shouldn't happen
}
}
sql += QString( " WHERE ROWID=%1" ).arg( fid );
Expand Down Expand Up @@ -4865,7 +4896,8 @@ const QgsField & QgsSpatiaLiteProvider::field( int index ) const

if ( it == attributeFields.constEnd() )
{
QgsDebugMsg( QString( "Field %1 not found." ).arg( index ) );
QgsLogger::warning( QString( "FAILURE: Field %1 not found." ).arg( index ) );
throw SLFieldNotFound();
}

return it.value();
Expand Down
2 changes: 2 additions & 0 deletions src/providers/spatialite/qgsspatialiteprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
GEOS_3D_GEOMETRYCOLLECTION = -2147483641,
};

struct SLFieldNotFound {}; //! Exception to throw

public:
static QString quotedIdentifier( QString id );
static QString quotedValue( QString value );
Expand Down