OGR_PG驱动源码-OGRPGDataSource

2022-09-19  本文已影响0人  NullUser

读取Layer

1.papoLayers被写入

OGRPGDataSource通过成员变量papoLayers保存Layer数组,该变量数据的写入分析如下:
该数组数据的新增仅在OGRPGDataSource::OpenTable()OGRPGDataSource::ICreateLayer()中实现。
OpenTable()OGRPGDataSource::GetLayerByName()OGRPGDataSource::LoadTables()中会被调用。
LoadTables()OGRPGDataSource::GetLayerCount()中被调用。
除开ICreateLayer()GetLayerByName()papoLayers被写入就只有一条调用线:GetLayerCount()->LoadTables()->OpenTable()。

2.OGRPGDataSource::LoadTables()

LoadTables()中,读取成员变量pszForcedTables,从中获取出需要读取的表名,多个表名由逗号分割,如下为LoadTables()部分源码:

    if( pszForcedTables )
    {
        char **papszTableList = CSLTokenizeString2( pszForcedTables, ",", 0 );

        for( int i = 0; i < CSLCount(papszTableList); i++ )
        {

pszForcedTablesOGRPGDataSource::Open()的时候被赋值,首先遍历传入的OpenOptions,取出设置的tables的值,如果OpenOptions中没有设置,则在DataSource接收的连接字符串中查找并取出该值(连接字符串示例:PG:dbname=db1 host=127.0.0.1 port=5432 user=u password=p tables=t1,t2),如下为Open()部分源码:

    std::string osForcedTables;
    for(const char* pszOpenOption: apszOpenOptions)
    {
        const char* pszVal = CSLFetchNameValue(papszOpenOptions, pszOpenOption);
        if( pszVal && strcmp(pszOpenOption, "active_schema") == 0 )
        {
            osActiveSchema = pszVal;
        }
        else if( pszVal && strcmp(pszOpenOption, "schemas") == 0 )
        {
            osSchemas = pszVal;
        }
        else if( pszVal && strcmp(pszOpenOption, "tables") == 0 )
        {
            osForcedTables = pszVal;
        }
        ......
    }
    ......
/* -------------------------------------------------------------------- */
/*      Determine if the connection string contains an optional         */
/*      TABLES portion. If so, parse it out. The expected               */
/*      connection string in this case will be, e.g.:                   */
/*                                                                      */
/*        'PG:dbname=warmerda user=warmerda tables=s1.t1,[s2.t2,...]    */
/*              - where sN is schema and tN is table name               */
/*      We must also strip this information from the connection         */
/*      string; PQconnectdb() does not like unknown directives          */
/* -------------------------------------------------------------------- */
    if( !osForcedTables.empty() ||
        (!bIsURI && ParseAndRemoveParam(pszConnectionNameNoPrefix, "tables", osForcedTables)) )
    {
        pszForcedTables = CPLStrdup(osForcedTables.c_str());
    }

继续回到LoadTables()部分,获取到表名后,构建PGTableEntry实体,追加到临时数组papsTables中,并设置SchemaName和TableName,每有一个table,则nTableCount自增1,源码如下:

                papsTables = static_cast<PGTableEntry**>(CPLRealloc(papsTables, sizeof(PGTableEntry*) * (nTableCount + 1)));
                papsTables[nTableCount] = static_cast<PGTableEntry*>(CPLCalloc(1, sizeof(PGTableEntry)));
                if (pszGeomColumnName)
                    OGRPGTableEntryAddGeomColumn(papsTables[nTableCount], pszGeomColumnName);

                if( nParts == 2 )
                {
                    papsTables[nTableCount]->pszSchemaName = CPLStrdup( papszQualifiedParts[0] );
                    papsTables[nTableCount]->pszTableName = CPLStrdup( papszQualifiedParts[1] );
                }
                else
                {
                    papsTables[nTableCount]->pszSchemaName = CPLStrdup( osActiveSchema.c_str());
                    papsTables[nTableCount]->pszTableName = CPLStrdup( papszQualifiedParts[0] );
                }
                nTableCount ++;

接下来会判断nTableCount的值,如果为0则代表没有从连接字符串中获取到指定表,则加载所有的表:

    if( nTableCount == 0 && bHavePostGIS && sPostGISVersion.nMajor >= 2 &&
        !bListAllTables &&
        /* Config option mostly for comparison/debugging/etc... */
        CPLTestBool(CPLGetConfigOption("PG_USE_POSTGIS2_OPTIM", "YES")) )
    {......}
    else if (nTableCount == 0)
    {......}

最后遍历加载到的所有表,调用OpenTable()写入papoLayers

/* -------------------------------------------------------------------- */
/*      Register the available tables.                                  */
/* -------------------------------------------------------------------- */
    for( int iRecord = 0; iRecord < nTableCount; iRecord++ )
    {
      ......
        OGRPGTableLayer* poLayer =
            OpenTable( osCurrentSchema, papsTables[iRecord]->pszTableName,
                       papsTables[iRecord]->pszSchemaName,
                       papsTables[iRecord]->pszDescription,
                       nullptr, bDSUpdate, FALSE );
      ......
    }
上一篇 下一篇

猜你喜欢

热点阅读