Показать сообщение отдельно
Старый 13.08.2009, 13:37   #8  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от IKA Посмотреть сообщение
Тот есть ксли какие-то проверки железно должны происходить при вставке записи, то эти проверки лучше запихнуть в aosvalidate*? мне нужно проверить , что все поля-ссылки имеют значение , существующее уже в таблице, на которую они ссылаюся
Цитата:
Сообщение от IKA Посмотреть сообщение
А чем лучше пользоваться - sysconsitencycheck* или (перебирать поля и вызывать validateField)?
На мой взгляд, не надо приплетать сюда механизм проверки целостности - он совсем для других сценариев использования предназначен. Вообще, складывается впечатление, что у вас одна часть приложения "не доверяет" другой части, из-за чего вы хотите приделать проверки как можно "ближе" к таблицам. Обычно не доверяют лишь тому, что вводит пользователь, - для этого и пишутся многочисленные проверки на validateField(), во многом для этого же пишется validateWrite(), хотя в нем могут проверяться отнюдь не все поля, но дополнительно могут проверяться какие-то взаимосвязи между их значениями. А если запись создана из кода, то обычно считается, что данные в ее полях взяты не с потолка; в любом случае, вам никто не мешает вызвать из кода validateWrite(), а в него уже прописать все необходимые проверки. Опять же, затем вам может понадобиться работать с записями таблицы без дополнительных проверок (скажем, когда все данные уже проверены в другом месте, и нужно лишь быстро совершить какие-то групповые операции) - если "зашить" проверки слишком жестко, к примеру, в insert()/update(), то в таких сценариях они будут лишь попусту тормозить работу, в том числе таких предусмотренных в ядре средств, как insert_recordset, update_recordset, RecordInsertList.

Цитата:
Сообщение от ZVV Посмотреть сообщение
Цитата:
Сообщение от IKA Посмотреть сообщение
А чем лучше пользоваться - sysconsitencycheck* или (перебирать поля и вызывать validateField)?
Риторический вопрос?
SysConsistencyCheck.kernelCheckRecord()
В самом начале этого метода есть такая проверка:
X++:
if (! common.recId)
    return;
В связи с этим он не годится для проверок перед вставкой новой записи.

PS. Если есть острое желание проверять все поля подряд, то можно в Global завести метод наподобие такого:
X++:
static boolean DEV_validateAllRecordFields( Common  _common, 
                                            boolean _verbose = false, 
                                            boolean _stopOnFirstError = true
                                          )
{
    DictTable   dictTable;
    DictField   dictField;
    FieldId     fieldId;
    boolean     ret = true;
    ArrayIdx    i;

    boolean validateSingleField(FieldId _fieldExtId)
    {
        if (!_common.validateField(_fieldExtId))
        {
            if (_verbose)
                warning(strfmt(@"Ошибка в поле '%1' таблицы '%2' (значение '%3')",
                                fieldid2pname(dictTable.id(), _fieldExtId), 
                                dictTable.label(), 
                                _common.(fieldId)
                       ));
            return false;
        }
        return true;
    }    
    ;
    dictTable = new DictTable(_common.tableId);
    if (!dictTable)
        return false;
    fieldId = dictTable.fieldNext(0);
    while (fieldId && !isSysId(fieldId) )
    {
        dictField = new DictField(_common.tableId, fieldId);
        if (dictField.arraySize() > 1)
        {
            for (i = 1; i <= dictField.arraySize(); i++)
            {
                if (!validateSingleField(fieldId2Ext(fieldId, i)))
                {
                    ret = false;
                    if (_stopOnFirstError)
                        break;
                }
            }
        }
        else
        {
            if (!validateSingleField(fieldId2Ext(fieldId, i)))
            {
                ret = false;
                if (_stopOnFirstError)
                    break;
            }
        }
        fieldId = dictTable.fieldNext(fieldId);
    }
    return ret;
}

Последний раз редактировалось gl00mie; 13.08.2009 в 15:22. Причина: исправил пример кода
За это сообщение автора поблагодарили: Dron AKA andy (2), ZVV (2), IKA (1).