Skip to content

Commit

Permalink
Add QgsOracleProviderConnection
Browse files Browse the repository at this point in the history
  • Loading branch information
troopa81 authored and nyalldawson committed Jan 29, 2021
1 parent 249d681 commit 7b77243
Show file tree
Hide file tree
Showing 8 changed files with 360 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/providers/oracle/CMakeLists.txt
Expand Up @@ -15,6 +15,7 @@ set(ORACLE_SRCS
qgsoracleconnpool.cpp
qgsoracleexpressioncompiler.cpp
qgsoracletransaction.cpp
qgsoracleproviderconnection.cpp
)

if (WITH_GUI)
Expand Down
23 changes: 23 additions & 0 deletions src/providers/oracle/qgsoracleconn.cpp
Expand Up @@ -963,4 +963,27 @@ QString QgsOracleConn::currentUser()
return mCurrentUser;
}

QList<QgsVectorDataProvider::NativeType> QgsOracleConn::nativeTypes()
{
return QList<QgsVectorDataProvider::NativeType>()
// integer types
<< QgsVectorDataProvider::NativeType( tr( "Whole number" ), "number(10,0)", QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "Whole big number" ), "number(20,0)", QVariant::LongLong )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), "number", QVariant::Double, 1, 38, 0, 38 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), "double precision", QVariant::Double )

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

// string types
<< QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), "CHAR", QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, limited variable length (varchar2)" ), "VARCHAR2", QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (long)" ), "LONG", QVariant::String )

// date type
<< QgsVectorDataProvider::NativeType( tr( "Date" ), "DATE", QVariant::Date, 38, 38, 0, 0 )
<< QgsVectorDataProvider::NativeType( tr( "Date & Time" ), "TIMESTAMP(6)", QVariant::DateTime, 38, 38, 6, 6 );
}

// vim: sw=2 :
7 changes: 7 additions & 0 deletions src/providers/oracle/qgsoracleconn.h
Expand Up @@ -30,6 +30,7 @@
#include "qgis.h"
#include "qgslogger.h"
#include "qgsdatasourceuri.h"
#include "qgsvectordataprovider.h"

#include <QSqlDatabase>
#include <QSqlQuery>
Expand Down Expand Up @@ -184,6 +185,12 @@ class QgsOracleConn : public QObject
*/
int version();

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

static const int sGeomTypeSelectLimit;

static QgsWkbTypes::Type wkbTypeFromDatabase( int gtype );
Expand Down
50 changes: 30 additions & 20 deletions src/providers/oracle/qgsoracleprovider.cpp
Expand Up @@ -36,6 +36,7 @@
#include "qgsoraclefeatureiterator.h"
#include "qgsoracleconnpool.h"
#include "qgsoracletransaction.h"
#include "qgsoracleproviderconnection.h"

#ifdef HAVE_GUI
#include "qgsoraclesourceselect.h"
Expand Down Expand Up @@ -167,26 +168,7 @@ QgsOracleProvider::QgsOracleProvider( QString const &uri, const ProviderOptions
}

//fill type names into sets
setNativeTypes( QList<NativeType>()
// integer types
<< QgsVectorDataProvider::NativeType( tr( "Whole number" ), "number(10,0)", QVariant::Int )
<< QgsVectorDataProvider::NativeType( tr( "Whole big number" ), "number(20,0)", QVariant::LongLong )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (numeric)" ), "number", QVariant::Double, 1, 38, 0, 38 )
<< QgsVectorDataProvider::NativeType( tr( "Decimal number (decimal)" ), "double precision", QVariant::Double )

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

// string types
<< QgsVectorDataProvider::NativeType( tr( "Text, fixed length (char)" ), "CHAR", QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, limited variable length (varchar2)" ), "VARCHAR2", QVariant::String, 1, 255 )
<< QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (long)" ), "LONG", QVariant::String )

// date type
<< QgsVectorDataProvider::NativeType( tr( "Date" ), "DATE", QVariant::Date, 38, 38, 0, 0 )
<< QgsVectorDataProvider::NativeType( tr( "Date & Time" ), "TIMESTAMP(6)", QVariant::DateTime, 38, 38, 6, 6 )
);
setNativeTypes( connectionRO()->nativeTypes() );

QString key;
switch ( mPrimaryKeyType )
Expand Down Expand Up @@ -3884,6 +3866,9 @@ QVariantMap QgsOracleProviderMetadata::decodeUri( const QString &uri ) const
uriParts[ QStringLiteral( "checkPrimaryKeyUnicity" ) ] = dsUri.param( "checkPrimaryKeyUnicity" );
if ( ! dsUri.geometryColumn().isEmpty() )
uriParts[ QStringLiteral( "geometrycolumn" ) ] = dsUri.geometryColumn();
if ( ! dsUri.param( "dboptions" ).isEmpty() )
uriParts[ QStringLiteral( "dboptions" ) ] = dsUri.param( "dboptions" );

return uriParts;
}

Expand Down Expand Up @@ -3929,4 +3914,29 @@ QString QgsOracleProviderMetadata::encodeUri( const QVariantMap &parts ) const
return dsUri.uri( false );
}

QMap<QString, QgsAbstractProviderConnection *> QgsOracleProviderMetadata::connections( bool cached )
{
return connectionsProtected<QgsOracleProviderConnection, QgsOracleConn>( cached );
}

QgsAbstractProviderConnection *QgsOracleProviderMetadata::createConnection( const QString &uri, const QVariantMap &configuration )
{
return new QgsOracleProviderConnection( uri, configuration );
}

QgsAbstractProviderConnection *QgsOracleProviderMetadata::createConnection( const QString &name )
{
return new QgsOracleProviderConnection( name );
}

void QgsOracleProviderMetadata::deleteConnection( const QString &name )
{
deleteConnectionProtected<QgsOracleProviderConnection>( name );
}

void QgsOracleProviderMetadata::saveConnection( const QgsAbstractProviderConnection *conn, const QString &name )
{
saveConnectionProtected( conn, name );
}

// vim: set sw=2
5 changes: 5 additions & 0 deletions src/providers/oracle/qgsoracleprovider.h
Expand Up @@ -431,6 +431,11 @@ class QgsOracleProviderMetadata final: public QgsProviderMetadata
QList<QgsDataItemProvider *> dataItemProviders() const override;

QgsTransaction *createTransaction( const QString &connString ) override;
QMap<QString, QgsAbstractProviderConnection *> connections( bool cached = true ) override;
QgsAbstractProviderConnection *createConnection( const QString &name ) override;
QgsAbstractProviderConnection *createConnection( const QString &uri, const QVariantMap &configuration ) override;
void deleteConnection( const QString &name ) override;
void saveConnection( const QgsAbstractProviderConnection *createConnection, const QString &name ) override;

QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
Expand Down
143 changes: 143 additions & 0 deletions src/providers/oracle/qgsoracleproviderconnection.cpp
@@ -0,0 +1,143 @@
/***************************************************************************
qgsOracleproviderconnection.cpp - QgsOracleProviderConnection
---------------------
begin : 28.12.2020
copyright : (C) 2020 by Julien Cabieces
email : julien dot cabieces at oslandia dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsoracleproviderconnection.h"
#include "qgsoracleconn.h"
#include "qgsoracleconnpool.h"
#include "qgssettings.h"
#include "qgsoracleprovider.h"
#include "qgsexception.h"
#include "qgsapplication.h"

QgsOracleProviderConnection::QgsOracleProviderConnection( const QString &name )
: QgsAbstractDatabaseProviderConnection( name )
{
mProviderKey = QStringLiteral( "oracle" );
// Remove the sql and table empty parts
const QRegularExpression removePartsRe { R"raw(\s*sql=\s*|\s*table=""\s*)raw" };
setUri( QgsOracleConn::connUri( name ).uri().replace( removePartsRe, QString() ) );
setDefaultCapabilities();
}

QgsOracleProviderConnection::QgsOracleProviderConnection( const QString &uri, const QVariantMap &configuration ):
QgsAbstractDatabaseProviderConnection( QgsDataSourceUri( uri ).connectionInfo( false ), configuration )
{
mProviderKey = QStringLiteral( "oracle" );
setDefaultCapabilities();
}

void QgsOracleProviderConnection::setDefaultCapabilities()
{
// TODO: we might check at this point if the user actually has the privileges and return
// properly filtered capabilities instead of all of them
mCapabilities =
{
Capability::DropVectorTable,
Capability::DropRasterTable,
Capability::CreateVectorTable,
Capability::RenameSchema,
Capability::DropSchema,
Capability::CreateSchema,
Capability::RenameVectorTable,
Capability::RenameRasterTable,
Capability::Vacuum,
Capability::ExecuteSql,
Capability::SqlLayers,
//Capability::Transaction,
Capability::Tables,
Capability::Schemas,
Capability::Spatial,
Capability::TableExists,
Capability::CreateSpatialIndex,
Capability::SpatialIndexExists,
Capability::DeleteSpatialIndex,
Capability::DeleteField,
Capability::DeleteFieldCascade,
Capability::AddField
};
mGeometryColumnCapabilities =
{
GeometryColumnCapability::Z,
GeometryColumnCapability::M,
GeometryColumnCapability::SinglePart,
GeometryColumnCapability::Curves
};
}

void QgsOracleProviderConnection::store( const QString &name ) const
{
QString baseKey = QStringLiteral( "/Oracle/connections/" );
// delete the original entry first
remove( name );

QgsSettings settings;
settings.beginGroup( baseKey );
settings.beginGroup( name );

// From URI
const QgsDataSourceUri dsUri { uri() };
settings.setValue( "authcfg", dsUri.authConfigId() );
settings.setValue( "database", dsUri.database() );
settings.setValue( "username", dsUri.username() );
settings.setValue( "password", dsUri.password() );
settings.setValue( "dbworkspace", dsUri.param( "dbworkspace" ) );
settings.setValue( "estimatedMetadata", dsUri.useEstimatedMetadata() );
settings.setValue( "host", dsUri.host() );
settings.setValue( "includeGeoAttributes", dsUri.param( "includegeoattributes" ) );
settings.setValue( "port", dsUri.port() );
settings.setValue( "schema", dsUri.schema() );
settings.setValue( "dboptions", dsUri.param( "dboptions" ) );

// From configuration
static const QStringList configurationParameters
{
QStringLiteral( "allowGeometrylessTables" ),
QStringLiteral( "geometryColumnsOnly" ),
QStringLiteral( "onlyExistingTypes" ),
QStringLiteral( "savePassword" ),
QStringLiteral( "saveUsername" ),
QStringLiteral( "userTablesOnly" ),
};
for ( const auto &p : configurationParameters )
{
if ( configuration().contains( p ) )
{
settings.setValue( p, configuration().value( p ) );
}
}
settings.endGroup();
settings.endGroup();
}

void QgsOracleProviderConnection::remove( const QString &name ) const
{
QgsOracleConn::deleteConnection( name );
}

QList<QgsVectorDataProvider::NativeType> QgsOracleProviderConnection::nativeTypes() const
{
QList<QgsVectorDataProvider::NativeType> types;
QgsOracleConn *conn = QgsOracleConnPool::instance()->acquireConnection( QgsDataSourceUri{ uri() }.connectionInfo( false ) );
if ( conn )
{
types = conn->nativeTypes();
QgsOracleConnPool::instance()->releaseConnection( conn );
}
if ( types.isEmpty() )
{
throw QgsProviderConnectionException( QObject::tr( "Error retrieving native types for connection %1" ).arg( uri() ) );
}
return types;
}
41 changes: 41 additions & 0 deletions src/providers/oracle/qgsoracleproviderconnection.h
@@ -0,0 +1,41 @@
/***************************************************************************
qgsOracleproviderconnection.h - QgsOracleProviderConnection
---------------------
begin : 28.12.2020
copyright : (C) 2020 by Julien Cabieces
email : julien dot cabieces at oslandia dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSORACLEPROVIDERCONNECTION_H
#define QGSORACLEPROVIDERCONNECTION_H
#include "qgsabstractdatabaseproviderconnection.h"


class QgsOracleProviderConnection : public QgsAbstractDatabaseProviderConnection

{
public:

QgsOracleProviderConnection( const QString &name );
QgsOracleProviderConnection( const QString &uri, const QVariantMap &configuration );

// QgsAbstractProviderConnection interface

void store( const QString &name ) const override;
void remove( const QString &name ) const override;
QList<QgsVectorDataProvider::NativeType> nativeTypes() const override;

private:

void setDefaultCapabilities();
};


#endif // QGSORACLEPROVIDERCONNECTION_H

0 comments on commit 7b77243

Please sign in to comment.