Показать сообщение отдельно
Старый 08.08.2018, 07:47   #317  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
Аватар для TasmanianDevil
Злыдни
 
885 / 389 (14) ++++++
Регистрация: 24.01.2005
Адрес: Томск
Класс EventContextInformation, используемый при переходе со стандартного оповещения к источнику, метод canUseFindRecord(), имеющий встроенную булевскую функцию test().

В строке 50 шикарнейшим образом инициализируется объект QueryBuildDataSource для запроса - тупо добавлением нового источника данных, независимо от того был Query унаследован с переданного источника данных формы или сформирован с нуля (т.е. кол-во источников данных в любом случае увеличивается на 1). Затем этот запрос передается в 92-й строке в SysQuery для подсчета кол-ва записей. Как работает этот подсчет - можете глянуть, при количестве источников данных в запросе большим одного - идет обычный итерационный перебор всех записей на клиенте.

Имеющие в таблицах-источниках оповещений значительное кол-во записей скажут спасибо за чудесные минуты ожидание открытия соотв. формы.

P.S. И это, <censored>, слой SYP ...

X++:
///    method returns false. Otherwise, it returns true.
/// </remarks>
private boolean canUseFindRecord(
    FormDataSource          alertFds = formRun.dataSource(alertFormDsName)
    )
{
    tableId                 tableId,childTableId;
    List                    fds2Dynas;
    ListEnumerator          fdsLe;
    Map                     dynalinkMap;
    container               dynaPack;
    MapEnumerator           dynaMe;
    Query                   q;
    QueryBuildDataSource    qbds;
    List                    keyList;
    Map                     keyFields;
    DictIndex               di;

    // If changed remember to updated the Dev. doc!
    #define.maxRecsForFind(100)

    boolean test()
    {
        // If first then lookup overrules
        if (alertQbdsNo == 1 && ! this.canUseLookup())
            return false;

        if (! alertBuffer)
            return false;

        if(alertFds.query() != null)
        {
            q   = alertFds.query();
        }
        else
        {
            q   = new Query();
        }
        qbds    = q.addDataSource(alertBuffer.TableId);

        // Use packed dyna info to find dyna fields from alert buffer to parent
        if (conlen(packedDynas) > 1)
        {
            fds2Dynas   = List::create(packedDynas);
            fdsLe       = fds2Dynas.getEnumerator();
            fdsLe.moveNext();
            [tableId,childTableId,dynaPack]  = fdsLe.current();

            keyList     = new List(Types::Integer);
            dynalinkMap = Map::create(dynaPack);
            dynaMe      = dynalinkMap.getEnumerator();
            while (dynaMe.moveNext())
            {
                keyList.addEnd(dynaMe.currentKey());
            }
            keyFields = SysDictTable::mapFieldIds2Values(keyList,alertBuffer);

            // Add dyna's values as ranges
            SysQuery::addRangesFromKeyData(qbds,keyFields.pack());

            // Add filter query
            if (filterQuery)
                SysQuery::mergeRanges(q,filterQuery);
        }
        else
        {
            // When no dyna's only use filter
            if (filterQuery)
            {
                q = filterQuery;

                di = this.getPrimaryIndex();
                if (di.field(1) == fieldnum(Common,RecId))
                {
                    q.dataSourceTable(alertBuffer.TableId).addRange(di.field(1)).value(SysQuery::value(alertBuffer.(di.field(1))));
                }
            }
        }

        if (q && (SysQuery::countLoops(new QueryRun(q)) <= #maxRecsForFind))
        {
            return true;
        }

        return false;
    }

    if (canUseFindRecordCalled)
    {
        return canUseFindRecordValue;
    }

    canUseFindRecordValue  = test();
    canUseFindRecordCalled = true;

    return canUseFindRecordValue;
}
__________________
Мы летаем, кружимся, нагоняем ужасы ...

Последний раз редактировалось TasmanianDevil; 08.08.2018 в 08:03.