Skip to content

Commit

Permalink
Add static nativeTypes and remove ugly workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Jul 16, 2020
1 parent 1ac91c1 commit b1c371a
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 199 deletions.
Expand Up @@ -536,15 +536,10 @@ Raises a QgsProviderConnectionException if any errors are encountered.
:raises :: py:class:`QgsProviderConnectionException`
%End

virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const throw( QgsProviderConnectionException );
virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const throw( QgsProviderConnectionException ) = 0;
%Docstring
Returns a list of native types supported by the connection.

.. note::

if the database does not contain any table, a temporary table will
be created, in that case the correct user permissions might be required.

.. versionadded:: 3.16

:raises :: py:class:`QgsProviderConnectionException`
Expand Down
11 changes: 11 additions & 0 deletions src/core/providers/ogr/qgsgeopackageproviderconnection.cpp
Expand Up @@ -387,3 +387,14 @@ QList<QVariantList> QgsGeoPackageProviderConnection::executeGdalSqlPrivate( cons
return results;
}


QList<QgsVectorDataProvider::NativeType> QgsGeoPackageProviderConnection::nativeTypes() const
{
QList<QgsVectorDataProvider::NativeType> types;
QgsVectorLayer vl { uri(), QStringLiteral( "temp_layer" ), QStringLiteral( "ogr" ) };
if ( ! vl.isValid() || ! vl.dataProvider() )
{
throw QgsProviderConnectionException( QObject::tr( "Error retrieving native types for %1: %2" ).arg( uri() ).arg( vl.dataProvider()->errors().join( '\n' ) ) );
}
return vl.dataProvider()->nativeTypes();
}
3 changes: 3 additions & 0 deletions src/core/providers/ogr/qgsgeopackageproviderconnection.h
Expand Up @@ -46,6 +46,7 @@ class QgsGeoPackageProviderConnection : public QgsAbstractDatabaseProviderConnec
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tables( const QString &schema = QString(),
const TableFlags &flags = nullptr ) const override;
QIcon icon() const override;
QList<QgsVectorDataProvider::NativeType> nativeTypes() const override;

private:

Expand All @@ -55,5 +56,7 @@ class QgsGeoPackageProviderConnection : public QgsAbstractDatabaseProviderConnec

};



///@endcond
#endif // QGSGEOPACKAGEPROVIDERCONNECTION_H
95 changes: 0 additions & 95 deletions src/core/qgsabstractdatabaseproviderconnection.cpp
Expand Up @@ -232,101 +232,6 @@ QgsAbstractDatabaseProviderConnection::TableProperty QgsAbstractDatabaseProvider
.arg( name, schema ) );
}

QList<QgsVectorDataProvider::NativeType> QgsAbstractDatabaseProviderConnection::nativeTypes() const
{
QList<QgsVectorDataProvider::NativeType> types;
static QAtomicInt tempTableNumber { 0 };
const int temporaryTableNumber = tempTableNumber++;
QString schemaName;
QString tableName;
QString temporarySchemaName;
QString temporaryTableName;
QStringList schemaList;

// Search for schemas
if ( mCapabilities.testFlag( QgsAbstractDatabaseProviderConnection::Capability::Schemas ) )
{
schemaList = schemas();
if ( schemaList.isEmpty() )
{
// Try to create one
temporarySchemaName = QStringLiteral( "qgis_temporary_schema_%1" ).arg( temporaryTableNumber );
try
{
createSchema( temporarySchemaName );
QgsDebugMsgLevel( QStringLiteral( "Temporary schema created: %1" ).arg( temporarySchemaName ), 2 );
schemaList.push_back( temporarySchemaName );
schemaName = temporarySchemaName;
}
catch ( QgsProviderConnectionException &ex )
{
throw QgsProviderConnectionException( QObject::tr( "Could not find an existing schema and could not create temporary schema '%1' for connection: %2" ).arg( schemaName, ex.what() ) );
}
}
}
else
{
schemaList.push_back( QStringLiteral( "dummy_schema" ) );
schemaName = schemaList.first();
}

// Search for tables
for ( const auto &sch : qgis::as_const( schemaList ) )
{
const auto tableList { tables( sch, { QgsAbstractDatabaseProviderConnection::TableFlag::Vector | QgsAbstractDatabaseProviderConnection::TableFlag::Aspatial } ) };
if ( !tableList.isEmpty() )
{
schemaName = sch;
tableName = tableList.first().tableName();
break;
}
}

if ( schemaName.isEmpty() )
{
schemaName = schemaList.first();
}

// Create a temporary table
if ( tableName.isEmpty() )
{
temporaryTableName = QStringLiteral( "qgis_temporary_table_%1" ).arg( temporaryTableNumber );
try
{
createVectorTable( schemaName, temporaryTableName, QgsFields(), QgsWkbTypes::NoGeometry, QgsCoordinateReferenceSystem(), false, {} );
QgsDebugMsgLevel( QStringLiteral( "Temporary table created: %1" ).arg( tableName ), 2 );
tableName = temporaryTableName;
}
catch ( QgsProviderConnectionException &ex )
{
if ( ! temporarySchemaName.isEmpty() )
{
dropSchema( temporarySchemaName, true );
}
throw QgsProviderConnectionException( QObject::tr( "Could not find an existing table and could not create temporary table '%1' for connection: %2" ).arg( temporaryTableName, ex.what() ) );
}
}

QgsVectorLayer::LayerOptions options {false, false };
options.skipCrsValidation = true;
QgsVectorLayer vl { tableUri( schemaName, tableName ), QStringLiteral( "temp_layer" ), providerKey(), options };
if ( vl.isValid() )
{
types = vl.dataProvider()->nativeTypes();
}

// Cleanup
if ( !temporarySchemaName.isEmpty() )
{
dropSchema( temporarySchemaName, true );
}
else if ( ! temporaryTableName.isEmpty() )
{
dropVectorTable( schemaName, tableName );
}
return types;
}

QList<QgsAbstractDatabaseProviderConnection::TableProperty> QgsAbstractDatabaseProviderConnection::tablesInt( const QString &schema, const int flags ) const
{
return tables( schema, static_cast<QgsAbstractDatabaseProviderConnection::TableFlags>( flags ) );
Expand Down
4 changes: 1 addition & 3 deletions src/core/qgsabstractdatabaseproviderconnection.h
Expand Up @@ -557,12 +557,10 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv

/**
* Returns a list of native types supported by the connection.
* \note if the database does not contain any table, a temporary table will
* be created, in that case the correct user permissions might be required.
* \since QGIS 3.16
* \throws QgsProviderConnectionException
*/
virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const SIP_THROW( QgsProviderConnectionException );
virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const SIP_THROW( QgsProviderConnectionException ) = 0;

/**
* Returns the provider key
Expand Down
30 changes: 30 additions & 0 deletions src/providers/mssql/qgsmssqlconnection.cpp
Expand Up @@ -423,6 +423,36 @@ QStringList QgsMssqlConnection::connectionList()
return settings.childGroups();
}

QList<QgsVectorDataProvider::NativeType> QgsMssqlConnection::nativeTypes()
{
return QList<QgsVectorDataProvider::NativeType>()
// integer types
<< QgsVectorDataProvider::NativeType( QObject::tr( "8 Bytes integer" ), QStringLiteral( "bigint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( QObject::tr( "4 Bytes integer" ), QStringLiteral( "int" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( QObject::tr( "2 Bytes integer" ), QStringLiteral( "smallint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( QObject::tr( "1 Bytes integer" ), QStringLiteral( "tinyint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 20, 0, 20 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 20, 0, 20 )

// floating point
<< QgsVectorDataProvider::NativeType( QObject::tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Decimal number (double)" ), QStringLiteral( "float" ), QVariant::Double )

// date/time types
<< QgsVectorDataProvider::NativeType( QObject::tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 )

// string types
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, limited variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, fixed length unicode (nchar)" ), QStringLiteral( "nchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, limited variable length unicode (nvarchar)" ), QStringLiteral( "nvarchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String )
<< QgsVectorDataProvider::NativeType( QObject::tr( "Text, unlimited length unicode (ntext)" ), QStringLiteral( "text" ), QVariant::String )
;
}

QString QgsMssqlConnection::dbConnectionName( const QString &name )
{
// Starting with Qt 5.11, sharing the same connection between threads is not allowed.
Expand Down
7 changes: 7 additions & 0 deletions src/providers/mssql/qgsmssqlconnection.h
Expand Up @@ -22,6 +22,7 @@
#include <QMutex>

#include "qgsdatasourceuri.h"
#include "qgsvectordataprovider.h"

class QString;
class QSqlDatabase;
Expand Down Expand Up @@ -163,6 +164,12 @@ class QgsMssqlConnection
*/
static QStringList connectionList();

/**
* Returns the list of native types
* \since QGIS 3.16
*/
static QList<QgsVectorDataProvider::NativeType> nativeTypes();


private:

Expand Down
27 changes: 1 addition & 26 deletions src/providers/mssql/qgsmssqlprovider.cpp
Expand Up @@ -149,32 +149,7 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
}

//fill type names into sets
setNativeTypes( QList<NativeType>()
// integer types
<< QgsVectorDataProvider::NativeType( tr( "8 Bytes integer" ), QStringLiteral( "bigint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "4 Bytes integer" ), QStringLiteral( "int" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "2 Bytes integer" ), QStringLiteral( "smallint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "1 Bytes integer" ), QStringLiteral( "tinyint" ), QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 20, 0, 20 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 20, 0, 20 )

// floating point
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "float" ), QVariant::Double )

// date/time types
<< QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "datetime" ), QVariant::DateTime, -1, -1, -1, -1 )

// string types
<< QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, limited variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, fixed length unicode (nchar)" ), QStringLiteral( "nchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, limited variable length unicode (nvarchar)" ), QStringLiteral( "nvarchar" ), QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String )
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length unicode (ntext)" ), QStringLiteral( "text" ), QVariant::String )
);
setNativeTypes( QgsMssqlConnection::nativeTypes() );
}

QgsMssqlProvider::~QgsMssqlProvider()
Expand Down
5 changes: 5 additions & 0 deletions src/providers/mssql/qgsmssqlproviderconnection.cpp
Expand Up @@ -494,3 +494,8 @@ QIcon QgsMssqlProviderConnection::icon() const
return QgsApplication::getThemeIcon( QStringLiteral( "mIconMssql.svg" ) );
}


QList<QgsVectorDataProvider::NativeType> QgsMssqlProviderConnection::nativeTypes() const
{
return QgsMssqlConnection::nativeTypes();
}
4 changes: 4 additions & 0 deletions src/providers/mssql/qgsmssqlproviderconnection.h
Expand Up @@ -48,6 +48,7 @@ class QgsMssqlProviderConnection : public QgsAbstractDatabaseProviderConnection
void store( const QString &name ) const override;
void remove( const QString &name ) const override;
QIcon icon() const override;
QList<QgsVectorDataProvider::NativeType> nativeTypes() const override;

private:

Expand All @@ -57,6 +58,9 @@ class QgsMssqlProviderConnection : public QgsAbstractDatabaseProviderConnection
void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;

static const QStringList EXTRA_CONNECTION_PARAMETERS;

};



#endif // QGSMSSQLPROVIDERCONNECTION_H
52 changes: 52 additions & 0 deletions src/providers/postgres/qgspostgresconn.cpp
Expand Up @@ -1677,6 +1677,58 @@ QString QgsPostgresConn::fieldExpression( const QgsField &fld, QString expr )
}
}

QList<QgsVectorDataProvider::NativeType> QgsPostgresConn::nativeTypes()
{
QList<QgsVectorDataProvider::NativeType> types;

types // integer types
<< QgsVectorDataProvider::NativeType( tr( "Whole number (smallint - 16bit)" ), QStringLiteral( "int2" ), QVariant::Int, -1, -1, 0, 0 )
<< QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 32bit)" ), QStringLiteral( "int4" ), QVariant::Int, -1, -1, 0, 0 )
<< QgsVectorDataProvider::NativeType( tr( "Whole number (integer - 64bit)" ), QStringLiteral( "int8" ), QVariant::LongLong, -1, -1, 0, 0 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), QStringLiteral( "numeric" ), QVariant::Double, 1, 20, 0, 20 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), QStringLiteral( "decimal" ), QVariant::Double, 1, 20, 0, 20 )

// floating point
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (real)" ), QStringLiteral( "real" ), QVariant::Double, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), QStringLiteral( "double precision" ), QVariant::Double, -1, -1, -1, -1 )

// string types
<< QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), QStringLiteral( "char" ), QVariant::String, 1, 255, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Text, limited variable length (varchar)" ), QStringLiteral( "varchar" ), QVariant::String, 1, 255, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), QStringLiteral( "text" ), QVariant::String, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Text, case-insensitive unlimited length (citext)" ), QStringLiteral( "citext" ), QVariant::String, -1, -1, -1, -1 )

// date type
<< QgsVectorDataProvider::NativeType( tr( "Date" ), QStringLiteral( "date" ), QVariant::Date, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Time" ), QStringLiteral( "time" ), QVariant::Time, -1, -1, -1, -1 )
<< QgsVectorDataProvider::NativeType( tr( "Date & Time" ), QStringLiteral( "timestamp without time zone" ), QVariant::DateTime, -1, -1, -1, -1 )

// complex types
<< QgsVectorDataProvider::NativeType( tr( "Map (hstore)" ), QStringLiteral( "hstore" ), QVariant::Map, -1, -1, -1, -1, QVariant::String )
<< QgsVectorDataProvider::NativeType( tr( "Array of number (integer - 32bit)" ), QStringLiteral( "int4[]" ), QVariant::List, -1, -1, -1, -1, QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "Array of number (integer - 64bit)" ), QStringLiteral( "int8[]" ), QVariant::List, -1, -1, -1, -1, QVariant::LongLong )
<< QgsVectorDataProvider::NativeType( tr( "Array of number (double)" ), QStringLiteral( "double precision[]" ), QVariant::List, -1, -1, -1, -1, QVariant::Double )
<< QgsVectorDataProvider::NativeType( tr( "Array of text" ), QStringLiteral( "text[]" ), QVariant::StringList, -1, -1, -1, -1, QVariant::String )

// boolean
<< QgsVectorDataProvider::NativeType( tr( "Boolean" ), QStringLiteral( "bool" ), QVariant::Bool, -1, -1, -1, -1 )

// binary (bytea)
<< QgsVectorDataProvider::NativeType( tr( "Binary object (bytea)" ), QStringLiteral( "bytea" ), QVariant::ByteArray, -1, -1, -1, -1 )
;

if ( pgVersion() >= 90200 )
{
types << QgsVectorDataProvider::NativeType( tr( "JSON (json)" ), QStringLiteral( "json" ), QVariant::Map, -1, -1, -1, -1, QVariant::String );

if ( pgVersion() >= 90400 )
{
types << QgsVectorDataProvider::NativeType( tr( "JSON (jsonb)" ), QStringLiteral( "jsonb" ), QVariant::Map, -1, -1, -1, -1, QVariant::String );
}
}
return types;
}

void QgsPostgresConn::deduceEndian()
{
QMutexLocker locker( &mLock );
Expand Down
7 changes: 7 additions & 0 deletions src/providers/postgres/qgspostgresconn.h
Expand Up @@ -28,6 +28,7 @@
#include "qgsdatasourceuri.h"
#include "qgswkbtypes.h"
#include "qgsconfig.h"
#include "qgsvectordataprovider.h"

extern "C"
{
Expand Down Expand Up @@ -345,6 +346,12 @@ class QgsPostgresConn : public QObject

QString connInfo() const { return mConnInfo; }

/**
* Returns a list of supported native types for this connection.
* \since QGIS 3.16
*/
QList<QgsVectorDataProvider::NativeType> nativeTypes();

/**
* Returns the underlying database.
*
Expand Down

0 comments on commit b1c371a

Please sign in to comment.