Показать сообщение отдельно
Старый 06.09.2006, 11:12   #7  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
А что если вот так исправить метод new в SysQueryRun. Какие минусы? Что не будет работать, если запрос через X++ - понятно. Что не будет, если получится много ExistJoin - понятно. Что еще? Есть что-нить глобально неправильное? Будет ли работать в простейших случаях?
X++:
public void new(anytype _p1)
{
    // custom RLS, OIP, 05.09.06 -->
    int                     i,j,k;
    QueryBuildRange         r;
    QueryBuilddatasource    ds;
    QueryBuilddatasource    childDS;
    QueryBuilddatasource    restrictDS;
    Query                   q;
    SysRecordLevelSecurity  RLSTable;
    Query                   restriction;
    userGroupId             groupId;
    userGroupList           groupList;
    // custom RLS, OIP, 05.09.06 <--
    if (_p1)
    {
        super (_p1);

        if (this.args() &&
            !this.args().caller() &&
            typeOf(_p1) == Types::Class &&
            !SysdictClass::isEqualOrSuperClass(classidget(_p1), classNum(Query)))
        {
            this.args().caller(_p1);
        }

        // custom RLS, OIP, 05.09.06 -->
        q = this.query();
        {
            for(i=1; i<= q.dataSourceCount(); i++)
            {
                ds = q.dataSourceNo(i);
                while select RLSTable
                    where RLSTable.tabId == ds.table()
                    join groupList
                    where   groupList.groupId == RLSTable.groupId &&
                            groupList.userId  == curUserId()
                {
                    if(RLSTable.restriction != conNull() &&
                       sysQuery::isPackedOk(RLSTable.restriction))
                    {
                        restriction = new QueryRun(RLSTable.restriction).query();
                        if(restriction.dataSourceCount()>1)
                        {
                            for(j=2;j<= restriction.dataSourceCount();j++)
                            {
                                restrictDS = restriction.dataSourceNo(j);
                                if (!SysQuery::tableOccurrence(q, restrictDS.table(), q.dataSourceCount()))
                                {
                                    childDS = ds.addDataSource(restrictDS.table());
                                    childDS.relations(true);
                                    childDS.joinMode(JoinMode::ExistsJoin);
                                    childDS.fetchMode(QueryFetchMode::One2One);
                                }
                                else
                                {
                                    childDS = q.dataSourceTable(restrictDS.table());
                                }
                                for(k=1;k<=restrictDS.rangeCount();k++)
                                {
                                    r = restrictDS.range(k);
                                    SysQuery::findOrCreateRange(childDs, r.field()).value(r.value());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // custom RLS, OIP, 05.09.06 <--

    loadLastUsedQuery   = true;
    saveQueryPrUser     = true;
    allowSave           = true;
    allowAddRange       = QueryAllowAdd::AllFields;
    allowAddSorting     = QueryAllowAdd::AllFields;
    showSorting         = true;
}
По-крайней мере все выглядит красиво.
если например настроил RLS на VendTable (в форме Запросы в РЛС приджойнил скажем RContractTable с критерием по Ответственному лицу равным "ИИИ" - у нас таких поставщиков 2) и везде, во всех формах на основе VendTable и отчетах только эти 2 поставщика отображаются. И даже лукап по поставщикам тоже только этих двух отображает.

PS Это пока самая первая версия кода. Там еще много чего можно исправлять. Поэтому интересует лишь возможность именно такого подхода.

Последний раз редактировалось oip; 06.09.2006 в 12:42.