1.QgsPostgresProviderMetadata类
class QgsPostgresProviderMetadata final: public QgsProviderMetadata
{};
(1) createProvider()
QgsDataProvider *QgsPostgresProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
return new QgsPostgresProvider( uri, options, flags );
}
createProvder()创建Provider实例,new了一个QgsPostgresProvider后返回。
(2) dataItemProviders()
QList< QgsDataItemProvider * > QgsPostgresProviderMetadata::dataItemProviders() const
{
QList<QgsDataItemProvider *> providers;
providers << new QgsPostgresDataItemProvider;
return providers;
}
dataItemProviders()返回QgsDataItemProvider列表,在创建一个QList后,往QList中加入了一个新new的QgsPostgresDataItemProvider对象,并将该QList返回。QgsPostgresDataItemProvider类与Qgis浏览器面板中PostGIS树节点构建相关。
(3) createEmptyLayer()
Qgis::VectorExportResult QgsPostgresProviderMetadata::createEmptyLayer(
const QString &uri,
const QgsFields &fields,
QgsWkbTypes::Type wkbType,
const QgsCoordinateReferenceSystem &srs,
bool overwrite,
QMap<int, int> &oldToNewAttrIdxMap,
QString &errorMessage,
const QMap<QString, QVariant> *options )
{
return QgsPostgresProvider::createEmptyLayer(
uri, fields, wkbType, srs, overwrite,
&oldToNewAttrIdxMap, &errorMessage, options
);
}
createEmptyLayer()创建空图层,由源码可知该函数只为接口,实际实现为QgsPostgresProvider::createEmptyLayer()。
(4) styleExists()
bool QgsPostgresProviderMetadata::styleExists( const QString &uri, const QString &styleId, QString &errorCause )
{
......
// 1)
if ( !tableExists( *conn, QStringLiteral( "layer_styles" ) ) )
{
return false;
}
// 2)
else if ( !columnExists( *conn, QStringLiteral( "layer_styles" ), QStringLiteral( "type" ) ) )
{
return false;
}
......
// 3)
const QString wkbTypeString = QgsPostgresConn::quotedValue( QgsWkbTypes::geometryDisplayString( QgsWkbTypes::geometryType( dsUri.wkbType() ) ) );
const QString checkQuery = QString( "SELECT styleName"
" FROM layer_styles"
" WHERE f_table_catalog=%1"
" AND f_table_schema=%2"
" AND f_table_name=%3"
" AND f_geometry_column=%4"
" AND (type=%5 OR type IS NULL)"
" AND styleName=%6" )
.arg( QgsPostgresConn::quotedValue( dsUri.database() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.table() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) )
.arg( wkbTypeString )
.arg( QgsPostgresConn::quotedValue( styleId.isEmpty() ? dsUri.table() : styleId ) );
......
}
styleExists()判断是否有样式表。
- 先通过tableExists()查询表是否存在,Sql语句为:SELECT EXISTS ( SELECT oid FROM pg_catalog.pg_class WHERE relname=“layer_styles” )。
- 如果layer_styles表存在,再通过columnExists()判断对应列是否存在,Sql语句为:SELECT COUNT(*) FROM information_schema.columns WHERE table_name= layer_styles and column_name= type
- 在表和列都存在后,从表中按过滤条件查询,判断是否有style数据,有返回true,否则false。
(5) saveStyle()
bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &qmlStyleIn, const QString &sldStyleIn,
const QString &styleName, const QString &styleDescription,
const QString &uiFileContent, bool useAsDefault, QString &errCause )
{
......
// 1)
if ( !tableExists( *conn, QStringLiteral( "layer_styles" ) ) )
{
QgsPostgresResult res( conn->PQexec( "CREATE TABLE layer_styles("
......
// 2)
if ( !columnExists( *conn, QStringLiteral( "layer_styles" ), QStringLiteral( "type" ) ) )
{
QgsPostgresResult res( conn->PQexec( "ALTER TABLE layer_styles ADD COLUMN type varchar NULL" ) );
......
// 3)
QString sql = QString( "INSERT INTO layer_styles("
......
// 4)
QString checkQuery = QString( "SELECT styleName"
" FROM layer_styles"......
QgsPostgresResult res( conn->PQexec( checkQuery ) );
if ( res.PQntuples() > 0 )
{
sql = QString( "UPDATE layer_styles"......
}
saveStyle()保存style。
- saveStyle首先通过tableExists()判断layer_styles表是否存在,如果不存在则创建。
- 然后通过columnExists()判断layer_styles表是否存在type列,如果不存在则ALERT TABLE添加该列。
- 构建INSERT语句,往layer_styles表添加一行数据。(构建sql语句并不执行)
- 通过SELECT语句判断是否已有该行数据,如果有则更改INSERT语句为UPDATE语句更新数据。
(6) loadStyle()
QString QgsPostgresProviderMetadata::loadStyle( const QString &uri, QString &errCause )
{
......
selectQmlQuery = QString( "SELECT styleQML"
" FROM layer_styles"......
......
}
loadStyle()从layer_styles表获取数据。
(7) listStyles()
int QgsPostgresProviderMetadata::listStyles( const QString &uri, QStringList &ids, QStringList &names,
QStringList &descriptions, QString &errCause )
{
......
QString selectRelatedQuery = QString( "SELECT id,styleName,description"
" FROM layer_styles"
" WHERE f_table_catalog=%1"
" AND f_table_schema=%2"
" AND f_table_name=%3"
" AND %4"
" AND (type=%5 OR type IS NULL)"
" ORDER BY useasdefault DESC, update_time DESC" )
.arg( QgsPostgresConn::quotedValue( dsUri.database() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.table() ) )
.arg( dsUri.geometryColumn().isEmpty() ? "f_geometry_column is NULL" :
QString( "f_geometry_column=%1" ).arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) ) )
.arg( wkbTypeString );
......
QString selectOthersQuery = QString( "SELECT id,styleName,description"
" FROM layer_styles"
" WHERE NOT (f_table_catalog=%1 AND f_table_schema=%2 AND f_table_name=%3 AND f_geometry_column=%4 AND type=%5)"
" ORDER BY update_time DESC" )
.arg( QgsPostgresConn::quotedValue( dsUri.database() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.table() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) )
.arg( wkbTypeString );
......
}
listStyles()列出layer_styles表的所有数据并将每行数据追加的形参ids, names, descriptions中。
(8) deleteStyleById()
bool QgsPostgresProviderMetadata::deleteStyleById( const QString &uri, const QString &styleId, QString &errCause )
{}
deleteStyleById()删除style行,Sql:DELETE FROM layer_styles WHERE id=%1
(9) getStyleById()
QString QgsPostgresProviderMetadata::getStyleById( const QString &uri, const QString &styleId, QString &errCause )
{}
getStyleById()根据id获取style,Sql:SELECT styleQml FROM layer_styles WHERE id=%1"
(10) createTransaction()
QgsTransaction *QgsPostgresProviderMetadata::createTransaction( const QString &connString )
{
return new QgsPostgresTransaction( connString );
}
createTransaction()返回new的QgsPostgresTransaction对象。QgsPostgresTransaction代表了一个事务去执行sql。
(11) connections()
QMap<QString, QgsAbstractProviderConnection *> QgsPostgresProviderMetadata::connections( bool cached )
{
return connectionsProtected<QgsPostgresProviderConnection, QgsPostgresConn>( cached );
}
connections()返回QgsProviderMetadata::connectionsProtected()的结果,connectionsProtected()是QgsProviderMetadata的内联函数,提供连接管理的统一功能。其返回的是QgsProviderMetadata的成员变量mProviderConnections
(12) createConnection()
QgsAbstractProviderConnection *QgsPostgresProviderMetadata::createConnection( const QString &uri, const QVariantMap &configuration )
{
return new QgsPostgresProviderConnection( uri, configuration );
}
createConnection()返回new的QgsPostgresProviderConnection对象。QgsPostgresProviderConnection提供数据库连接的一些接口。
(13) initProvider(
void QgsPostgresProviderMetadata::initProvider()
{
Q_ASSERT( !gPgProjectStorage );
gPgProjectStorage = new QgsPostgresProjectStorage;
QgsApplication::projectStorageRegistry()->registerProjectStorage( gPgProjectStorage ); // takes ownership
}
initProvider()可以做一些初始化工作,这里创建了一个QgsPostgresProjectStorage对象,并通过QgsApplication::projectStorageRegistry()进行注册,QgsPostgresProjectStorage将工程的一些数据储存在pg表中。
(14) cleanupProvider()
void QgsPostgresProviderMetadata::cleanupProvider()
{
QgsApplication::projectStorageRegistry()->unregisterProjectStorage( gPgProjectStorage ); // destroys the object
gPgProjectStorage = nullptr;
QgsPostgresConnPool::cleanupInstance();
}
cleanupProvider()同initProvider()相反,做一些回收工作。
(15) decodeUri()
QVariantMap QgsPostgresProviderMetadata::decodeUri( const QString &uri ) const
{
const QgsDataSourceUri dsUri { uri };
QVariantMap uriParts;
if ( ! dsUri.database().isEmpty() )
uriParts[ QStringLiteral( "dbname" ) ] = dsUri.database();
if ( ! dsUri.host().isEmpty() )
uriParts[ QStringLiteral( "host" ) ] = dsUri.host();
......
return uriParts;
}
decodeUri()解析uri字符串,可以自定义,这里使用了QgsDataSourceUri类进行解析,因为QgsPostgresProvider使用了QgsDataSourceUri的标准uri格式,参考uri: dbname='sdetest' host=127.0.0.1 port=5432 user='sde' password='123' table="sde"."testlayer" (shape)。
(16) encodeUri()
QString QgsPostgresProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
QgsDataSourceUri dsUri;
if ( parts.contains( QStringLiteral( "dbname" ) ) )
dsUri.setDatabase( parts.value( QStringLiteral( "dbname" ) ).toString() );
if ( parts.contains( QStringLiteral( "port" ) ) )
dsUri.setParam( QStringLiteral( "port" ), parts.value( QStringLiteral( "port" ) ).toString() );
......
return dsUri.uri(false);
}
encodeUri()将数据编码成uri字符串,同样使用QgsDataSourceUri类进行。
网友评论