Skip to content

Commit

Permalink
[FEATURE] Detect literal default values for spatialite provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 7, 2016
1 parent 1fea20d commit 0ae610c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
46 changes: 45 additions & 1 deletion src/providers/spatialite/qgsspatialiteprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ void QgsSpatiaLiteProvider::loadFieldsAbstractInterface( gaiaVectorLayerPtr lyr
mAttributeFields.clear();
mPrimaryKey.clear(); // cazzo cazzo cazzo
mPrimaryKeyAttrs.clear();
mDefaultValues.clear();

gaiaLayerAttributeFieldPtr fld = lyr->First;
if ( !fld )
Expand Down Expand Up @@ -729,6 +730,8 @@ void QgsSpatiaLiteProvider::loadFieldsAbstractInterface( gaiaVectorLayerPtr lyr
for ( int i = 1; i <= rows; i++ )
{
QString name = QString::fromUtf8( results[( i * columns ) + 1] );
insertDefaultValue( i - 1, QString::fromUtf8( results[( i * columns ) + 4] ) );

QString pk = results[( i * columns ) + 5];
QString type = results[( i * columns ) + 2];
type = type.toLower();
Expand Down Expand Up @@ -870,6 +873,37 @@ void QgsSpatiaLiteProvider::fetchConstraints()

}

void QgsSpatiaLiteProvider::insertDefaultValue( int fieldIndex, QString defaultVal )
{
if ( !defaultVal.isEmpty() )
{
QVariant defaultVariant;
switch ( mAttributeFields.at( fieldIndex ).type() )
{
case QVariant::LongLong:
defaultVariant = defaultVal.toLongLong();
break;

case QVariant::Double:
defaultVariant = defaultVal.toDouble();
break;

default:
{
if ( defaultVal.startsWith( '\'' ) )
defaultVal = defaultVal.remove( 0, 1 );
if ( defaultVal.endsWith( '\'' ) )
defaultVal.chop( 1 );
defaultVal.replace( "''", "'" );

defaultVariant = defaultVal;
break;
}
}
mDefaultValues.insert( fieldIndex, defaultVariant );
}
}

void QgsSpatiaLiteProvider::loadFields()
{
int ret;
Expand All @@ -884,6 +918,7 @@ void QgsSpatiaLiteProvider::loadFields()
QString sql;

mAttributeFields.clear();
mDefaultValues.clear();

if ( !mIsQuery )
{
Expand Down Expand Up @@ -921,6 +956,8 @@ void QgsSpatiaLiteProvider::loadFields()
const TypeSubType fieldType = getVariantType( type );
mAttributeFields.append( QgsField( name, fieldType.first, type, 0, 0, QString(), fieldType.second ) );
}

insertDefaultValue( i - 1, QString::fromUtf8( results[( i * columns ) + 4] ) );
}
}
sqlite3_free_table( results );
Expand Down Expand Up @@ -3820,8 +3857,10 @@ bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList & flist )
}
else if ( type == QVariant::String )
{
QString stringVal = v.toString();

// binding a TEXT value
QByteArray ba = v.toString().toUtf8();
QByteArray ba = stringVal.toUtf8();
sqlite3_bind_text( stmt, ++ia, ba.constData(), ba.size(), SQLITE_TRANSIENT );
}
else if ( type == QVariant::StringList || type == QVariant::List )
Expand Down Expand Up @@ -4229,6 +4268,11 @@ QgsVectorDataProvider::Capabilities QgsSpatiaLiteProvider::capabilities() const
return mEnabledCapabilities;
}

QVariant QgsSpatiaLiteProvider::defaultValue( int fieldId ) const
{
return mDefaultValues.value( fieldId, QVariant() );
}

void QgsSpatiaLiteProvider::closeDb()
{
// trying to close the SQLite DB
Expand Down
7 changes: 7 additions & 0 deletions src/providers/spatialite/qgsspatialiteprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
//! Returns a bitmask containing the supported capabilities
QgsVectorDataProvider::Capabilities capabilities() const override;

QVariant defaultValue( int fieldId ) const override;

/** The SpatiaLite provider does its own transforms so we return
* true for the following three functions to indicate that transforms
* should not be handled by the QgsCoordinateTransform object. See the
Expand Down Expand Up @@ -338,6 +340,9 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
//! Name of the geometry column in the table
QString mGeometryColumn;

//! Map of field index to default value
QMap<int, QVariant> mDefaultValues;

//! Name of the SpatialIndex table
QString mIndexTable;

Expand Down Expand Up @@ -448,6 +453,8 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider

void fetchConstraints();

void insertDefaultValue( int fieldIndex, QString defaultVal );

enum GEOS_3D
{
GEOS_3D_POINT = -2147483647,
Expand Down
14 changes: 14 additions & 0 deletions tests/src/python/test_provider_spatialite.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ def setUpClass(cls):
sql = "CREATE TABLE test_constraints(id INTEGER PRIMARY KEY, num INTEGER NOT NULL, desc TEXT UNIQUE, desc2 TEXT, num2 INTEGER NOT NULL UNIQUE)"
cur.execute(sql)

# simple table with defaults
sql = "CREATE TABLE test_defaults (id INTEGER NOT NULL PRIMARY KEY, name TEXT DEFAULT 'qgis ''is good', number INTEGER DEFAULT 5, number2 REAL DEFAULT 5.7, no_default REAL)"
cur.execute(sql)

cur.execute("COMMIT")
con.close()

Expand Down Expand Up @@ -461,6 +465,16 @@ def XXXXXtestLocking(self):

self.assertTrue(vl.commitChanges())

def testDefaultValues(self):

l = QgsVectorLayer("dbname=%s table='test_defaults' key='id'" % self.dbname, "test_defaults", "spatialite")
self.assertTrue(l.isValid())

self.assertEqual(l.dataProvider().defaultValue(1), "qgis 'is good")
self.assertEqual(l.dataProvider().defaultValue(2), 5)
self.assertEqual(l.dataProvider().defaultValue(3), 5.7)
self.assertFalse(l.dataProvider().defaultValue(4))


if __name__ == '__main__':
unittest.main()

0 comments on commit 0ae610c

Please sign in to comment.