• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Изменение документа в текущей базе или внешней?

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
Всем привет!

Интересует Ваше мнение на тему оптимизации.

Есть база под веб. 11 000 документов, штук 20 форм, штук 150 видов.
При загрузке веб-страницы запускается ls агент, который меняет значения в документе.

В базе выставлен параметр Optimize document table map

Итого вижу вот какие варианты решения (на уровне предположений)

1. Менять значение в самом документе. (плюс - не надо искать документ, минус - при сохранении документа пересчитываются виды, в которых он присутствует, даже если изменяемые поля не входят в формулу отбора видов, предполагаю, что если бы не Optimize document table map, вообще пересчитывались бы все виды)

2. Менять значение в связанном документе в этой базе, для этого хранить унид связанного документа в текущем документе и искать его по getdocumentbyunid (плюс - все в одной базе, минус - неизвестно, будут ли обновлятся какие то виды, если связанный документ не включен ни в один автообновляемый вид.

3. Менять значение документа в связанном документе в другой базе (вообще без автообновляемых видов) искать его по getdocumentbyunid (причем присваивать связанному документу унид равный униду оригинального документа)

4. Для каждого документа создать профильный связанный документ (минус - ограничение количества профильных доков, и в итоге глючит иногда, по моему наблюдению)

5. Создать запись на диске, в которую пихать/читать изменения

6. Для каждого дока создать запись на диске в которую пихать/читать изменения

7. Пихать/читать изменения через ини файл.

=========================================================

Сейчас думаю выбрать пункт 2 или 3, что Вы думаете об этом.


Прикладная задача примерно такая. Есть веб-раздел, для него надо сверху вида показывать 3 отдельных строки (на основе документов) из пула подобных строк, поочереди.

То есть как вариант решения, где то должно хранится значение указателя, который каждый раз меняется и указывает на очередные три записи.

Дополнительный вопрос. Правильно ли я предполагаю, что если переписать ls-агент на java-агент, то будет работать быстрее?
 

alexas1

Green Team
10.04.2014
1 202
225
BIT
36
минус - при сохранении документа пересчитываются виды
так, то оно так, но не весь вид целиком, а ток записи касающиеся этого дока и не одномоментно. А если индекс не считается в виде по формуле колонки, а просто берётся значение из дока, то это очень быстро.
5. Создать запись на диске, в которую пихать/читать изменения
прочесть из вида и записать в док быстрей, чем работать с FS
7. Пихать/читать изменения через ини файл.
- те же яйца, что и выше
искать его по getdocumentbyunid
- GetDocumentByKey быстрей (в большинстве случаев, поскольку вид, как правило, короче главной таблицы)
 

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
Хочется как то оптимизировать процессы.
Посмотрел сегодня загрузку сервера по процессорному времени

http задача - 102 часа
nupdate 3346 часов

что то думаю не так :)

И не совсем понятно, как проверить результаты оптимизации.
Пробую через профилирование агента и визуально отклик сайта через фаербаг - время загрузки.


так, то оно так, но не весь вид целиком, а ток записи касающиеся этого дока и не одномоментно. А если индекс не считается в виде по формуле колонки, а просто берётся значение из дока, то это очень быстро.

Боюсь, что обновления видов все и тормозят.

На всякий попробую перекомпактить базу, вдруг optimize document table map не сработал изначально.
 

alexas1

Green Team
10.04.2014
1 202
225
BIT
36
http задача - 102 часа
nupdate 3346 часов
такое соотношение говорит о том, что обновления видов практически всегда находятся за пределами времени работы ВЕБ юзера
около 3% в предположении равномерно распределённой во времени работы ВЕБ юзеров
даже полностью исключив обновление видов, работа юзеров ускорится на 3%
стоит ли бодаться? (это канеш, если сервер обслуживает ток одну эту базу)
 

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
по таймеру (из системы брать)

да, это мысль, спасибо.

такое соотношение говорит о том, что обновления видов практически всегда находятся за пределами времени работы ВЕБ юзера
около 3% в предположении равномерно распределённой во времени работы ВЕБ юзеров
даже полностью исключив обновление видов, работа юзеров ускорится на 3%
стоит ли бодаться? (это канеш, если сервер обслуживает ток одну эту базу)

Ну вся бодяга началась с того, что в фаербаге обратил внимание, что загрузка страницы с агентом занимала 450-900 мс, а с тем же агентом, который ничего не сохранял - 20-30 мс, причем сохранений было 4шт.
Изначально, как выяснилось я сделал по дебильному, прибавлял к номеру очереди +1 в трех документах и рефрешил вид, чтобы взять первые три. Вот этот рефреш видимо все и тормозил.
Сейчас изменил алгоритм на принцип указателя, никакие виды не рефрешатся, загрузка страницы уменьшилась до значения 90-130 мс. При этом вынес постоянные сохранения в другую базу вообще с одним видом без авторефреша. С одной стороны это неудобно, и база пока маленькая, непонятно как все себя поведет. Поэтому и мучения.

Причем на этом же серваке крутится пхп с mysql. Так там если сделать условно 20 запросов с апдэйтами - страничка грузится 10-20мс, а лотус один сэйв - 16мс. печаль какая - то.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
Так там если сделать условно 20 запросов с апдэйтами - страничка грузится 10-20мс, а лотус один сэйв - 16мс.
ну это не показатель... РСУБД, очевидно, будет быстрее
и агент - это очень "плохой" вариант работы с БД, как пример
 

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
В общем сделаю свои функции получения/сохранения документа и потестирую варианты для начала.
Спасибо за мысли.
[doublepost=1497972805,1497958430][/doublepost]Сделал тесты.
Сделал базу, в нее вставил 11 тыщ доков и 154 вида
Сделал агента, который
а) берет выборку 500 доков по форме и увеличивает в них счетчик на 1 optimize document table map галочка стоит
б) берет выборку 500 доков по форме и увеличивает в них счетчик на 1 при этом optimize document table map галочка не стоит
в) берет выборку 500 доков по форме и увеличивает в них счетчик на 1 при этом виды удалены

optimize document table map галочка не стоит

г) берет выборку 500 доков по форме, ищет в этой же базе связанные доки по униду и увеличивает в них счетчик на 1
д) берет выборку 500 доков по форме, ищет в другой базе (500 доков) связанные доки по униду (из вида и через getdocumentbyunid) и увеличивает в них счетчик на 1
е) берет выборку 500 доков по форме, ищет в другой базе (22500 доков) связанные доки по униду (из вида и через getdocumentbyunid) и увеличивает в них счетчик на 1

Резюме:
1. Часто изменяемый док должен иметь минимальное количество полей. Условно 500 сохранений связанного дока с 4 полями занимают в 8-10 раз меньше времени, чем сохранение основного дока с 180 полями.
2. Без галки optimize document table map скрипт отрабатывает немного быстрее.
3. GetDocumentByUNID работает быстрее всего.
4. Количество видов (2 или 150) на работу скрипта не влияют практически
5. Количество доков в базе *2 практически не влияют на скорость
6. Лазить во внешнюю базу - дополнительно тратися немного времени на ее открытие.

То есть галку optimize ставить не надо, сохранять/менять в отдельных доках с минимумом полей в текущей базе. Доки искать через getdocumentbyunid.

Пока пришел к этому. Тестил на локальной машине.

Думаю надо потестить сохранение на диске и в mysql
 
  • Нравится
Реакции: Vertigo

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
@Gandliar есть обновление полей дока без его полного сохранения!
метод patch, но его нужно активировать в настройках сервера, работает через XHR, пример кода в каментах
JavaScript:
function xhr() {
    var unid = gunid;
    console.log("gunid:" + unid);
    /*
     * require( [ "dojo/request/xhr" ], function(xhr) {
     * xhr("api/data/documents/unid/" + unid, { //data :
     * '{"date":{"data":"2016-07-01", "type":"datetime"}}', data :
     * '{"fc_vol_1":'+vol+'}', // {"data":"2013-02-20T12:18:18Z",
     * "type":"datetime"} method : "PATCH", handleAs : "json", headers : {
     * 'Content-Type' : 'application/json' } }).then( function(data) { // Do
     * something with the handled data console.log('successful');
     * alert("successful"); }, function(err) { // Handle the error condition
     * console.log('error'); alert("error"); }, function(evt) { // Handle a
     * progress event from the request if the // browser supports XHR2 }); });
     */
    /*
     * dojo.request.xhr("api/data/documents/unid/" + unid, { data :
     * '{"firstname":"Patched!"}', method : "PATCH", handleAs : "json", headers : {
     * 'Content-Type' : 'application/json' } }).then( function(data) {
     * console.log('successful'); }, function(err) { console.log('error'); });
     */
}
То есть галку optimize ставить не надо
у меня это приводило и к предупреждениям индексера и всяким глюкам - отказался ставить давно
3. GetDocumentByUNID работает быстрее всего.
достаточно очевидный факт, но есть зависимость от размера БД/вьюшки, на этом основан
[doublepost=1498038323,1498038085][/doublepost]еще есть метод StampAll , применение ограничено логикой, т.е. поменять поля в нескольких доках на одинаковое значение - его прямое назначение
[doublepost=1498039110][/doublepost]самое большое ускорение - не получать коллекции доков (по ключам), а использовать вьюшки по энтрисам (с анализом ColumnValues), и док получать по юниду (если надо обновить по рез-ту анализа)базовая либа для подобного анализа и обновления
Код:
%REM
*********************************************
    Library ViewUtilsBase
    Created Oct 18, 2016 by Mikhail Cholokov/CRUINTERNET
    Description: Comments for Library
%END REM
Option Public
Option Declare
'Use "CommonUI.lib"'Common.lib
Use "POI-Wrapper" 'POI-SAX->FileManager
Const CM_NAVTYPEMISMATCH={Несоответствие типов навигаторов:}

Const LIST_SEP={:}'const string separator
Const VAL_SEP={;}'multivalue separator
Const VER_SIGN={$}
Const VER_TMPL={ - ver:}
Const POSTFIX_SEP={$}
Const PREFIX_SEP={_}
Const KEY_SEP={|}
Const POS_SEP={.}
Const STR_SEP={ }
Const BLANK_TEMPL={<>}

'формы документов
Const TBL_TYPE={docTables}
Const FLD_TYPE={docFields}
Const FLD_TEMPL_TYPE={docFieldsTemplate}
Const DOCUMENT_TYPE={docFromPacket}
Const PACKET_TYPE={docPacket}
Const TEMPL_TYPE={docTemplate}
Const AVAIL_FORMS={"} & PACKET_TYPE & {":"} & TEMPL_TYPE & {"}

'documents fields
Const PREFIXES_FIELD={typeList}
Const PREFIXES_FLD=PREFIXES_FIELD

Const UNID_FLD={UID}'parent unid
Const NAME_FLD={name}
Const VALUE_FLD={value}
Const COMMENTS_FLD={comments}
Const UNIDDOC_FLD={unid}'current dod unid
Const DOCORDER_FLD={docorder}
Const ISTEMPLATE_FLD={istemplate}
Const SUFFIX_FLD={suffix} 'из формы docTables
Const PREFIX_FLD={prefix} 'из формы docTables
Const TYPECHOOSER_FLD={typeChooser} 'из формы docPacket

'fields view columns names view:FLD_VIEWNAME
Const UNID_COL={$} &UNID_FLD
Const DOCORDER_COL={$} &DOCORDER_FLD
Const CMNTS_NAME_COL={$comments_name}
Const VALUE_COL={$} &VALUE_FLD
Const CMNTS_TMPL_COL={$comments_tmpl}
Const NAME_COL={$} &NAME_FLD
Const COMMENTS_COL={$} &COMMENTS_FLD
Const MODIFIED_COL={$modified} 'for check update necessity
Const UNIDDOC_COL={$} &UNIDDOC_FLD
'Const AUTHOR_COL={$author}
'Const CREATED_COL={$created}
'Const UPDATEDBY_COL={$updatedby}

Const AGREEMENTS_LOOKUP={AgreementsFilterLookUp}'вью, ключ <UserName>+{|}+<name - название клиента>
Const AGREEMENTS_FILTER={AgreementsFilter}'вью, ключ <UserName>+{|}+<name - название клиента>
Const FIELDS_LOOKUP={FieldsSearch}'вью для получения полей по unid+{|}+<fieldName>
Const FIELDSFULL_LOOKUP={Fields}'вью для получения всех полей по unid
Const FIELDSPREFIX_LOOKUP={FieldsCategorized}'вью для получения всех полей по unid+{|}+<prefix fieldName>
Const DOCBYPREFIX_LOOKUP={DocFromPacketLookUpPrefix}'вью для получения документов в пакете unid+{|}+<prefix fieldName>
Const DOCS_LOOKUP={AgreementsUIDLookUp}''вью для получения документов в пакете по unid
Const TABLES_LOOKUP={TablesCategorized}

Const FLD_SEARCH_VIEWNAME=FIELDS_LOOKUP
Const TBL_CATEG_VIEWNAME=TABLES_LOOKUP
Const FLD_VIEWNAME=FIELDSFULL_LOOKUP
Const TBL_VIEWNAME={Tables}
Const UNIDFROM_VIEWNAME={UNIDFromLookup}'PacketUtils->CheckUpdate для проверки документов скопированных в др. БД
Const PACKETMOD_VIEWNAME={PacketModified}'пакеты по дате изменения - для архиврования
Const PACKETCHILDS_VIEWNAME={PacketChilds}'srearch docFromPacket by parent UNID - archivate
Const UID2Client_VIEWNAME={UID2ClientLookup}'search client name by packet UNID (for report)

'Const REF_COL=0 'column number for $REF in PACKETCHILDS_VIEWNAME
Const NAV_BUF=500

Private ses As NotesSession
%REM
*********************************************
    Class ViewNavBase
    Description: Comments for Class
%END REM
Class ViewNavBase As ErrorHandler
    Private AutoSave As Boolean
    Private logDoc As NotesDocument
    Private columns List As Integer
    Private db As NotesDatabase
    Private dbsource As NotesDatabase
    Private dbtarget As NotesDatabase
    Private view As NotesView
    Private key As String
    Private nav As NotesViewNavigator
    Private lastAU As Boolean 'last autoupdate state
    Private first As NotesViewEntry
    Private last As NotesViewEntry
    Private debug As Boolean
    Private safe As Boolean 'for safe update (don't replace "existing" value)
    Private NDChave2save() As NotesDocument
    Private UNIDS2save() As String
    Private UNIDS4missmatch() As String
    Private isTmpl As String
    %REM
    *--------------------------------------------
        Sub New
        Description: Comments for Sub
    %END REM
    Sub New(db As NotesDatabase, viewName As String, key As String)
        Dim routineName As String
        routineName="New"
        On Error GoTo ErrH
        'your code here
        me.AutoSave=True
        me.isTmpl={0}
        'Print {Class->} TypeName(Me){;View name:} viewName
        If db Is Nothing Then Error 1024, {DB is Nothing}
        Dim ses As New NotesSession
        Set me.db=db
        'Print {Database RID:} me.db.Replicaid
        Set me.logDoc=me.db.CreateDocument
        Call me.logDoc.Replaceitemvalue({form}, {log})
        Set me.rtTrace=me.logDoc.Createrichtextitem({body})
        Call me.logDoc.Computewithform(False, False)
        me.key=key
        Set me.view=me.db.Getview(Viewname)
        me.lastAU=me.view.AutoUpdate
        me.view.AutoUpdate= False
        me.view.Refresh
        Dim entry As NotesViewEntry

        Dim NEC As NotesViewEntryCollection
        'Print {Class:} TypeName(Me) {->} {Key:} me.key
        Set NEC=view.Getallentriesbykey(me.key, True)
        If Not NEC Is Nothing Then Set entry=NEC.Getfirstentry()
        If entry Is Nothing Then
            Print {Class:} TypeName(Me) {->} {First Entry Is Nothing}
            Set nav=view.Createviewnav()'escape error if key doesn't match any entries
        Else
            'Print {Class:} TypeName(Me) {->} {Entries Count} NEC.Count
            Set me.nav=view.Createviewnavfrom(entry)
            'https://www-10.lotus.com/ldd/ddwiki.nsf/dx/Fast_Retrieval_of_View_Data_Using_the_ViewNavigator_Cache
            nav.BufferMaxEntries = NAV_BUF
            nav.EntryOptions = Vn_entryopt_nocountdata
            Set me.first=entry
            Set entry=NEC.Getlastentry()
            Set me.last=nav.Getentry(entry)
            ForAll col In me.view.Columns
                Dim tmp As NotesViewColumn
                Set tmp=col
                'Print {Column name/pos:}tmp.ItemName {/} tmp.Position-1
                me.columns(tmp.ItemName)=tmp.Position-1
            End ForAll
        End If

Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Function Add2Missmathc
        Description: add to array for missmatch entries
    %END REM
    Function Add4Missmatch(entry As NotesViewEntry) As NotesViewEntry
        Dim routineName As String
        routineName="Add4Missmatch"
        On Error GoTo ErrH
        'your code here
        Dim cnt As Long
        If IsArrayInitialized(me.UNIDS4missmatch) Then
            cnt=UBound(me.UNIDS4missmatch)+1
        End If
        ReDim Preserve me.UNIDS4missmatch(cnt) As String
        me.UNIDS4missmatch(cnt)=entry.Universalid
        Set Add4Missmatch=entry
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function Add2Save
    Description: Comments for Function
    %END REM
    Private Function Add2Save(doc As NotesDocument) As NotesDocument
        Dim routineName As String
        routineName="Add2Save"
        On Error GoTo ErrH
        'your code here
        Dim cnt As Long
        If IsArrayInitialized(me.NDChave2save) Then
            cnt=UBound(me.NDChave2save)+1
        End If
        ReDim Preserve me.NDChave2save(cnt) As NotesDocument
        ReDim Preserve me.UNIDS2save(cnt) As String
        Set me.NDChave2save(cnt)=doc
        me.UNIDS2save(cnt)=doc.Universalid
        Set Add2Save=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Sub Terminate
    Description: destroy object
    %END REM
    Sub Delete()
        Dim routineName As String
        routineName="Delete"
        On Error GoTo ErrH
        'your code here
        'try to save document have been marked for save
        If me.AutoSave Then Me.Save
Quit:
        Exit Sub
ErrH:
        Error Err, Me.RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Function Save
        Description: Comments for Function
    %END REM
    Private Function Save()
        Dim routineName As String
        routineName="Save"
        On Error GoTo ErrH
        'your code here
        If Not me.view Is Nothing Then
            me.view.Refresh
            me.view.Autoupdate=me.lastAU
        End If
        'Print {Class:} TypeName(Me){->Destroy; Key:}key
        If Not IsArrayInitialized(me.NDChave2save) Then GoTo Quit
        'Print {Class:} TypeName(Me){->Saving Documents...} UBound(me.NDChave2save)+1
        Dim lastTry2Save As String
        ForAll obj In me.NDChave2save
            Dim doc As NotesDocument
            Set doc=obj
            If Not doc Is Nothing Then
                lastTry2Save={*Saved Doc Parent/UNID/Form/Name:} & _
                doc.Parentdocumentunid & {/} & _
                doc.Universalid & {/} & _
                doc.GetItemValue({Form})(0)&{/}&doc.Getitemvalue(NAME_FLD)(0) &{*}
                Call doc.Save(True, False)
                'Print {Class:} TypeName(Me){->Saved Doc name:}doc.Getitemvalue(NAME_FLD)(0)
            End If
        End ForAll
        ReDim me.NDChave2save(0) As NotesDocument
        Set me.NDChave2save(0)=Nothing
        'Save=
Quit:
        Exit Function
ErrH:
        Dim s As String
        s=Me.RaiseError
        If Len(lastTry2Save)>0 Then s=s & Chr(10) & lastTry2Save & Chr(10)
        Error Err, s
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Property Set IsDebug
        Description: Comments for Property Set
    %END REM
    Property Set IsDebug As Boolean
        Dim routineName As String
        routineName="IsDebug"
        On Error GoTo ErrH
        'your code here
        me.debug=IsDebug
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
   
    %REM
    *--------------------------------------------
    Property Set IsTemplate
    Description: return ISTEMPLATE_FLD value
    %END REM
    Private Property Get IsTemplate As String
        Dim routineName As String
        routineName="IsTemplate"
        On Error GoTo ErrH
        'your code here
        IsTemplate=me.isTmpl
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
    %REM
    *--------------------------------------------
    Property Set IsTemplate
    Description: Comments for Property Set
    %END REM
    Private Property Set IsTemplate As String
        Dim routineName As String
        routineName="IsTemplate"
        On Error GoTo ErrH
        'your code here
        me.isTmpl=IsTemplate
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
    %REM
    *--------------------------------------------
        Property Get Changes
        Description: Comments for Property Get
    %END REM
    Property Get Changes As Long
        Dim routineName As String
        routineName="Changes"
        On Error GoTo ErrH
'your code here
        If IsArray(me.NDChave2save)Then Changes=UBound(me.NDChave2save)+1
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
    %REM
    *--------------------------------------------
        Property Get ChangesUNIDS
        Description: Comments for Property Get
    %END REM
    Property Get ChangesUNIDS
        Dim routineName As String
        routineName="ChangesUNIDS"
        On Error GoTo ErrH
'your code here
        If IsArrayInitialized(me.UNIDS2save)Then
            ChangesUNIDS=me.UNIDS2save
        Else
            ChangesUNIDS=Split({},{})
        End If
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
    %REM
    *--------------------------------------------
        Function GetFirst
        Description: Comments for Function
    %END REM
    Function GetFirst() As NotesViewEntry
        Dim routineName As String
        routineName="GetFirst"
        On Error GoTo ErrH
        'your code here
        Set GetFirst=me.first
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
        Function GetPrev
        Description: Comments for Function
    %END REM
    Function GetPrev(entry As NotesViewEntry) As NotesViewEntry
        Dim routineName As String
        routineName="GetPrev"
        On Error GoTo ErrH
        'your code here
        If entry.Getposition(POS_SEP) = me.first.Getposition(POS_SEP) Then GoTo Quit
        Set GetPrev=nav.Getprev(entry)
        'If Me.GetPrev.Columnvalues(0)<>key Then Set GetPrev=NOTHING
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
    Function GetNext
    Description: Comments for Function
    %END REM
    Function GetNext(entry As NotesViewEntry) As NotesViewEntry
        Dim routineName As String
        routineName="GetNext"
        On Error GoTo ErrH
        'your code here
        If entry.Getposition(POS_SEP) = me.last.Getposition(POS_SEP) Then GoTo Quit
        Set GetNext=me.nav.Getnext(entry)
        'If Me.GetNext.Columnvalues(0)<>me.key Then Set GetNext=Nothing
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
    Sub Get HashMap
    Description: return List Array
    should be overrided
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="HashMap"
        On Error GoTo ErrH
        'your code here
        'HashMap=
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Sub ShowLog
        Description: Comments for Sub
    %END REM
    Function ShowLog As NotesUIDocument
        Dim routineName As String
        routineName="ShowLog"
        On Error GoTo ErrH
        'your code here
        Dim wks As New NotesUIWorkspace
        me.rtTrace.Update
        Set ShowLog=wks.Editdocument(True, me.logDoc)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function Filter
    Description: return True if value have not to be updated
    %END REM
    Function Filter(key As String) As Boolean
        Dim routineName As String
        routineName="Filter"
        On Error GoTo ErrH
        'your code here
        'Filter=False
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function UpdateByHashMap
        Description: update "collection" according HashMap
        all additional documents will be added
        vnav is another object
    %END REM
    Function UpdateByHashMap(vnav As ViewNavBase)
        Dim routineName As String
        routineName="UpdateByHashMap"
        On Error GoTo ErrH
        'your code here
        If Not (TypeName(vnav) = TypeName(Me)) Then _
        Error 1024, CM_NAVTYPEMISMATCH &TypeName(Me) &{/} &TypeName(vnav)
        Set vnav.dbsource=me.db
        Set me.dbtarget=vnav.db
        'Print {Target DB RID:} vnav.db.Replicaid
        Dim lst List As Variant
        Call Me.GetHashMap(lst)
        Dim entry As NotesViewEntry
        Set entry=vnav.GetFirst()
        Do While Not entry Is Nothing
            Dim tmpkey As String
            tmpkey=entry.Columnvalues(vnav.GetKeyValueCol())
            'check target view key according source key list
            If IsElement(lst(tmpkey)) Then
                'check if key should not be updated
                If Not Filter(tmpkey) Then
                    Dim docres As NotesDocument
                    If vnav.UpdateValues(lst(tmpkey), entry, docres) Then
                        'Call entry.Document.Save(True, False, False)
                        'Print {Add to Save:} docres.Getitemvalue(NAME_FLD)(0) {/} docres.Getitemvalue(VALUE_FLD)(0)
                        Call Add2Save(docres)
                    End If
                End If
                'remove hash element if it has been found
                Erase lst(tmpkey)
            Else
                Call Me.Add4Missmatch(entry)
            End If
            Set entry=vnav.GetNext(entry)
        Loop
        'create document according filter
        'itarate reamin keys
        ForAll m In lst
            Dim doc As NotesDocument
            Set doc=Nothing
            If Not Filter(ListTag(m)) Then Set doc=vnav.CreateDocument(ListTag(m),m)
            If Not doc Is Nothing Then
                SetType doc
                'Call doc.Save(True, False, False)
                Call Add2save(doc)
            End If
        End ForAll
        'UpdateByHashMap=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
        Function GetKeyValue
        Description: return  column Index (view entry) for hash key
        should be overrided
    %END REM
    Function GetKeyValueCol() As Integer
        Dim routineName As String
        routineName="GetKeyValue"
        On Error GoTo ErrH
        'your code here
        'GetKeyValueCol=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
   
    %REM
    *--------------------------------------------
        Function CreateDocument
        Description: should be overrided
        will be called from UpdateByHashMap
    %END REM
    Function CreateDocument(keyfld As String, values) As NotesDocument
        Dim routineName As String
        routineName="CreateDocument"
        On Error GoTo ErrH
        'your code here
        'CreateDocument=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function RemoveMissmatch
        Description: Comments for Function
    %END REM
    Function RemoveMissmatch()
        Dim routineName As String
        routineName="RemoveMissmatch"
        On Error GoTo ErrH
        'your code here
        If IsArrayInitialized(me.UNIDS4missmatch) Then
            ForAll m In me.UNIDS4missmatch
                Dim unid As String
                unid=CStr(m)
                Dim doc As NotesDocument
                Set doc=GetDocumentByUNIDSilent(me.db, unid)
                If Not doc Is Nothing Then
                    Call doc.Remove(True)
                End If
            End ForAll
        End If
        'RemoveMissmatch=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function SetType
    Description: should be overrided
    %END REM
    Private Function SetType(doc As NotesDocument)
        Dim routineName As String
        routineName="SetType"
        On Error GoTo ErrH
        'your code here
        'SetType=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Property Set IsSafe
    Description: replace or not (true - not) to new value with UpdateValues
    %END REM
    Property Set IsSafe As Boolean
        Dim routineName As String
        routineName="IsSafe"
        On Error GoTo ErrH
        'your code here
        me.safe=IsSafe
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
   
    %REM
    *--------------------------------------------
        Function UpdateValues
        Description: assign nev values to entry
        shoul be overrided
    %END REM
    Function UpdateValues(values, entry As NotesViewEntry, docres As NotesDocument) As Boolean
        Dim routineName As String
        routineName="UpdateValues"
        On Error GoTo ErrH
        'your code here
        'UpdateValues=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class

%REM
*********************************************
    Class ViewNav
    Description: creates view Navigator
    only string key accepted, as first sorted column value
    use NAV_BUF for speedup fetch access
%END REM
Class ViewNav As ViewNavBase
   
    %REM
    *--------------------------------------------
    Sub New
    Description: Comments for Sub
    %END REM
    Sub New(viewName As String, key As String), ViewNavBase(ses.Currentdatabase, viewName, key)
        Dim routineName As String
        routineName="New"
        On Error GoTo ErrH
        'your code here
%REM
        me.isTmpl={0}
        Print {View name:} viewName
        Set me.db=ses.Currentdatabase
        Set me.logDoc=me.db.CreateDocument
'        Set me.NDChave2save=db.CreateDocumentCollection
        Call me.logDoc.Replaceitemvalue({form}, {log})
        Set me.rtTrace=me.logDoc.Createrichtextitem({body})
        Call me.logDoc.Computewithform(False, False)
        me.key=key
        Set me.view=db.Getview(Viewname)
        me.lastAU=me.view.AutoUpdate
        me.view.AutoUpdate= False
        me.view.Refresh
        Dim entry As NotesViewEntry
'        Set entry=view.Getentrybykey(me.key, true)
        Dim NEC As NotesViewEntryCollection
        Print {Class:} TypeName(Me) {->} {Key:} me.key
        Set NEC=view.Getallentriesbykey(me.key, True)
        If Not NEC Is Nothing Then Set entry=NEC.Getfirstentry()
        If entry Is Nothing Then
            Print {Class:} TypeName(Me) {->} {First Entry Is Nothing}
            Set nav=view.Createviewnav()'escape error if key doesn't match any entries
        Else
            Print {Class:} TypeName(Me) {->} {Entries Count} NEC.Count
            Set me.nav=view.Createviewnavfrom(entry)
            'https://www-10.lotus.com/ldd/ddwiki.nsf/dx/Fast_Retrieval_of_View_Data_Using_the_ViewNavigator_Cache
            nav.BufferMaxEntries = NAV_BUF
            nav.EntryOptions = Vn_entryopt_nocountdata
            Set me.first=entry
            Set entry=NEC.Getlastentry()
            Set me.last=nav.Getentry(entry)
            ForAll col In me.view.Columns
                Dim tmp As NotesViewColumn
                Set tmp=col
                Print {Column name/pos:}tmp.ItemName {/} tmp.Position-1
                me.columns(tmp.ItemName)=tmp.Position-1
            End ForAll
        End If
%END REM
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    End Class
Sub Initialize
    Set ses=New NotesSession
End Sub
 
  • Нравится
Реакции: Vertigo

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
имплементация, для моих задач, просто как пример
Код:
%REM
*********************************************
    Library ViewUtils
    Created Jan 18, 2016 by Mikhail Cholokov/CRUINTERNET
    Description: Comments for Library
%END REM
Option Public
Option Declare
Use "ViewUtilsBase"
%REM
*********************************************
    Class ViewNavFlds
    Description: for Fields update/create, cached search by key
%END REM
Class ViewNavFlds As ViewNav
    Private parent As NotesDocument
    Sub New(parent As NotesDocument), ViewNav(FLD_VIEWNAME,parent.Universalid)
        'Set me.parent=GetDocumentByUNIDSilent(me.db, me.key)
        Set me.parent=parent
    End Sub

    %REM
    *--------------------------------------------
        Sub GetHashMap
        Description: Comments for Property Get
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="GetHashMap"
        On Error GoTo ErrH
        'your code here
        Dim  entry As NotesViewEntry, cols List As String, cnt As Long
        Set entry=first
        Erase lst
        Do While Not entry Is Nothing
'            Dim idx As Integer
'            idx=0
            Dim xval
            xval=entry.Columnvalues(columns(VALUE_COL))
            If IsArrayInitialized(xval) Then xval=xval(0)
            'Print {value:}xval
            cols(VALUE_COL)=xval
'            idx=idx+1
            cols(COMMENTS_COL)=entry.Columnvalues(columns(COMMENTS_COL))
'            idx=idx+1
            cols(DOCORDER_COL)=entry.Columnvalues(columns(DOCORDER_COL))
'            idx=idx+1
            cols(UNID_COL)=entry.Columnvalues(columns(UNID_COL))
            lst(entry.Columnvalues(columns(NAME_COL)))=(cols)
            cnt=cnt+1
            Set entry=Me.Getnext(entry)
        Loop
        Print {hash members Count:} cnt
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
    Function Filter
    Description: Filter copying update/creating docField
    %END REM
    Private Function Filter(key As String) As Boolean
        Dim routineName As String
        routineName="Filter"
        On Error GoTo ErrH
        'your code here
        'filter field with version from update
        Filter=IsVersion(key)
        'If Me.Filter Then Print {Filtered Key>} key
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function GetKeyValueCol
        Description: return  column Index (view entry) for hash key
    %END REM
    Private Function GetKeyValueCol() As Integer
        Dim routineName As String
        routineName="GetKeyValueCol"
        On Error GoTo ErrH
        'your code here
        GetKeyValueCol=columns(NAME_COL)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
        Function CreateDocument
        Description: Comments for Function
    %END REM
    Private Function CreateDocument(keyfld As String, values) As NotesDocument
        Dim routineName As String
        routineName="CreateDocument"
        On Error GoTo ErrH
        'your code here
        Dim doc As NotesDocument
        Set doc=me.db.CreateDocument()
        Call doc.Replaceitemvalue(NAME_FLD, keyfld)
        'Dim idx As Integer
        Call doc.Replaceitemvalue(VALUE_FLD, values(VALUE_COL))
        'idx=idx+1
        Call doc.Replaceitemvalue(COMMENTS_FLD, values(COMMENTS_COL))
        'idx=idx+1
        Dim item As NotesItem
        'value of DOCORDER_FLD set to Number
        Set item=doc.Replaceitemvalue(DOCORDER_FLD, CInt(values(DOCORDER_COL)))
        Call doc.ReplaceItemValue(UNID_FLD, doc.UniversalID)
        Call doc.Makeresponse(parent)
        Call SetRWAccess(parent, doc)
        Set CreateDocument=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
    Function SetType
    Description: should be overrided
    %END REM
    Private Function SetType(doc As NotesDocument)
        Dim routineName As String
        routineName="SetType"
        On Error GoTo ErrH
        'your code here
        Call doc.Replaceitemvalue(ISTEMPLATE_FLD, Me.IsTemplate)
        Call doc.Replaceitemvalue({Form}, FLD_TYPE)
        'Call doc.Computewithform(False, False)
        Set SetType=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
        Function UpdateValues
        Description: assign nev values to entry document
        call from base class on update
    %END REM
    Private Function UpdateValues(values, entry As NotesViewEntry, docres As NotesDocument) As Boolean
        Dim routineName As String
        routineName="UpdateValues"
        On Error GoTo ErrH
        'your code here
'        Dim idx As Integer
        If Len(values(VALUE_COL))>0 Then
            If values(VALUE_COL)<>BLANK_TEMPL Then
                If values(VALUE_COL)<>entry.Columnvalues(columns(VALUE_COL)) And (Not safe) Then
                    Set docres=entry.Document
                    Call docres.Replaceitemvalue(VALUE_FLD,values(VALUE_COL))
                    UpdateValues=True
                End If
            End If
        End If
'        idx=idx+1
        If values(COMMENTS_COL)<>entry.Columnvalues(columns(COMMENTS_COL)) Then
            Set docres=entry.Document
            Call docres.Replaceitemvalue(COMMENTS_FLD,values(COMMENTS_COL))
            UpdateValues=True
        End If
'        idx=idx+1
        If values(DOCORDER_COL)<>entry.Columnvalues(columns(DOCORDER_COL)) Then
            'value of DOCORDER_FLD set to Number
            Set docres=entry.Document
            Call docres.Replaceitemvalue(DOCORDER_FLD,CInt(values(DOCORDER_COL)))
            UpdateValues=True
        End If
       
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function testOut
        Description: Comments for Function
    %END REM
    Function testOut
        Dim routineName As String
        routineName="testOut"
        On Error GoTo ErrH
        'your code here
        Dim lst List As Variant
        Call Me.GetHashMap(Lst)
        me.PrintTrace({********************************************})
        ForAll cols In lst
            If me.debug Then _
            me.PrintTrace(ListTag(cols) &KEY_SEP _
            &cols(VALUE_COL) &KEY_SEP _
            &cols(COMMENTS_COL) &KEY_SEP _
            &cols(DOCORDER_COL))
        End ForAll
        'testOut=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class

%REM
*********************************************
    Class ViewNavTbls
    Description: for Fields update/create, cached search by key
%END REM
Class ViewNavTbls As ViewNav
    Private parent As NotesDocument
    Sub New(parent As NotesDocument), ViewNav(TBL_VIEWNAME, parent.Universalid)
        Dim routineName As String
        routineName="New"
        On Error GoTo ErrH
        'your code here
        'Set me.parent=GetDocumentByUNIDSilent(me.db, me.key)
        Set me.parent=parent
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
    Function CreateDocument
    Description: Comments for Function
    %END REM
    Private Function CreateDocument(keyfld As String, values) As NotesDocument
        Dim routineName As String
        routineName="CreateDocument"
        On Error GoTo ErrH
        'your code here
        'Print {Class:} TypeName(Me){->} routineName{; Key:}keyfld
        Dim doc As NotesDocument
        Set doc=me.db.CreateDocument()
        Call doc.Replaceitemvalue(PREFIX_FLD,StrLeft(keyfld,PREFIX_SEP))'need for docTables form works right
        Call doc.Replaceitemvalue(SUFFIX_FLD,StrRight(keyfld,PREFIX_SEP))'need for docTables form works right 
        Call doc.Replaceitemvalue(NAME_FLD, keyfld)
        Call doc.Replaceitemvalue(SUFFIX_FLD,StrRight(keyfld,PREFIX_SEP))'need for docTables form works right 
        Call doc.ReplaceItemValue(UNID_FLD, doc.UniversalID)
        Dim unid As String, tmp As NotesDocument
        unid=values
        'get original table doc (see GetHashMap)
        Set tmp=GetDocumentByUNIDSilent(me.db, unid)
        'copy body RT
        Call tmp.Getfirstitem({body}).Copyitemtodocument(doc, {body})
        Call doc.Makeresponse(parent)
        Call SetRWAccess(parent, doc)
        Set CreateDocument=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function Filter
        Description: filter docTables with version from update/creste
    %END REM
    Private Function Filter(key As String) As Boolean
        Dim routineName As String
        routineName="Filter"
        On Error GoTo ErrH
        'your code here
        'filter tables with version from update/creste
        Filter=IsVersion(key)
        'If Me.Filter Then Print {Filtered Key>} key
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
     
    %REM
    *--------------------------------------------
    Sub GetHashMap
    Description: Comments for Sub
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="GetHashMap"
        On Error GoTo ErrH
        'your code here
        Dim entry As NotesViewEntry, cols List As String, cnt As Long
        Erase lst
        Set entry=first
        'only last unid would be saved if NAME_FLD not unique
        Do While Not entry Is Nothing
            'Print {NAME_COL:}entry.Columnvalues(columns(NAME_COL))
            lst(entry.Columnvalues(columns(NAME_COL)))=entry.Universalid
            cnt=cnt+1
            Set entry=Me.Getnext(entry)
        Loop
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
    Function GetKeyValueCol
    Description: Comments for Function
    %END REM
    Private Function GetKeyValueCol() As Integer
        Dim routineName As String
        routineName="GetKeyValueCol"
        On Error GoTo ErrH
        'your code here
        GetKeyValueCol=columns(NAME_COL)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function SetType
    Description: Comments for Function
    %END REM
    Private Function SetType(doc As NotesDocument)
        Dim routineName As String
        routineName="SetType"
        On Error GoTo ErrH
        'your code here
        Call doc.Replaceitemvalue(ISTEMPLATE_FLD, Me.IsTemplate)
        Call doc.Replaceitemvalue({Form}, TBL_TYPE)
        'Call doc.Computewithform(False, False)
        Set SetType=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function UpdateValues
    Description: docTables should not be udated
    %END REM
    Private Function UpdateValues(values, entry As NotesViewEntry, docres As NotesDocument) As Boolean
        Dim routineName As String
        routineName="UpdateValues"
        On Error GoTo ErrH
        'your code here
        UpdateValues=False
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class
%REM
*********************************************
    Class ViewNavFldsPfx
    Description: hash only current prefix (type_fld)
    main usage is new version for docField
%END REM
Class ViewNavFldsPfx As ViewNav
    Private xtype As String
    Private parent As NotesDocument
   
    Sub New(key As String), ViewNav(FLD_VIEWNAME,StrLeft(key,KEY_SEP))
        Set me.parent=GetDocumentByUNIDSilent(me.db,StrLeft(key,KEY_SEP))
        me.xtype=StrRight(key,KEY_SEP)
    End Sub
    %REM
    *--------------------------------------------
        Function CreateDocument
        Description: Comments for Function
    %END REM
    Private Function CreateDocument(keyfld As String, values) As NotesDocument
        Dim routineName As String
        routineName="CreateDocument"
        On Error GoTo ErrH
'your code here
        Dim doc As NotesDocument
        Set doc=me.db.CreateDocument()
        Call doc.Replaceitemvalue(NAME_FLD, keyfld)
        Call doc.Replaceitemvalue(VALUE_FLD, values(VALUE_COL))
        Call doc.Replaceitemvalue(COMMENTS_FLD, values(COMMENTS_COL))
        Dim item As NotesItem
        'value of DOCORDER_FLD set to Number
        Set item=doc.Replaceitemvalue(DOCORDER_FLD, CInt(values(DOCORDER_COL)))
        Call doc.ReplaceItemValue(UNID_FLD, doc.UniversalID)
        Call doc.Makeresponse(parent)
        Call SetRWAccess(parent, doc)
        Set CreateDocument=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Sub GetHashMap
        Description: Comments for Sub
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="GetHashMap"
        On Error GoTo ErrH
'your code here
        Dim  entry As NotesViewEntry, cols List As String, cnt As Long
        Set entry=first
        Erase lst
        Do While Not entry Is Nothing
            If InStr(1,entry.Columnvalues(columns(NAME_COL)), me.xtype &PREFIX_SEP)=1 Then
                cols(VALUE_COL)=entry.Columnvalues(columns(VALUE_COL))
                cols(COMMENTS_COL)=entry.Columnvalues(columns(COMMENTS_COL))
                cols(DOCORDER_COL)=entry.Columnvalues(columns(DOCORDER_COL))
                cols(UNID_COL)=entry.Columnvalues(columns(UNID_COL))
                lst(entry.Columnvalues(columns(NAME_COL)))=(cols)
                cnt=cnt+1
            End If
            Set entry=Me.Getnext(entry)
        Loop
        Print {hash members Count:} cnt

Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Function GetKeyValueCol
        Description: return Index for key column
    %END REM
    Private Function GetKeyValueCol() As Integer
        Dim routineName As String
        routineName="GetKeyValueCol"
        On Error GoTo ErrH
        'your code here
        GetKeyValueCol=columns(NAME_COL)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function SetType
    Description: should be overrided
    %END REM
    Private Function SetType(doc As NotesDocument)
        Dim routineName As String
        routineName="SetType"
        On Error GoTo ErrH
        'your code here
        Call doc.Replaceitemvalue(ISTEMPLATE_FLD, Me.IsTemplate)
        Call doc.Replaceitemvalue({Form}, FLD_TYPE)
        'Call doc.Computewithform(False, False)
        Set SetType=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
    Function UpdateValues
    Description: selected By prefix should not be udated (only create)
    %END REM
    Private Function UpdateValues(values, entry As NotesViewEntry, docres As NotesDocument) As Boolean
        Dim routineName As String
        routineName="UpdateValues"
        On Error GoTo ErrH
        'your code here
        UpdateValues=False
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class

%REM
*********************************************
    Class ViewNavFull
    Description: key is First column and hashMap key as well
    hashMap contains entry.ColumnValues
    only string (for values) and only last value (if multivalue)
%END REM
Class ViewNavFull As ViewNav
    Sub New(viewName As String), ViewNav(viewName,{})
        On Error GoTo ErrH
        Set me.nav=view.Createviewnav()
        'https://www-10.lotus.com/ldd/ddwiki.nsf/dx/Fast_Retrieval_of_View_Data_Using_the_ViewNavigator_Cache
        nav.BufferMaxEntries = NAV_BUF
        nav.EntryOptions = Vn_entryopt_nocountdata
        Set me.first=nav.Getfirst()
        Set me.last=nav.Getlast()
        'Print {Class:} TypeName(Me) {->} {Entries Count} nav.Count
        ForAll col In me.view.Columns
            Dim tmp As NotesViewColumn
            Set tmp=col
            Print {Column name/pos:}tmp.ItemName {/} tmp.Position-1
            me.columns(tmp.ItemName)=tmp.Position-1
        End ForAll
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
    End Sub
    %REM
    *--------------------------------------------
        Function GetHashMap
        Description: Comments for Function
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="GetHashMap"
        On Error GoTo ErrH
        'your code here
        Dim  entry As NotesViewEntry, cols List As String, cnt As Long
        Dim key As String
        Set entry=first
        Erase lst
        Do While Not entry Is Nothing
            key=CStr(entry.Columnvalues(0))
            Dim i As Integer
            i=0
            ForAll v In entry.Columnvalues
                If IsArray(v) Then v=v(UBound(v))
                cols(CStr(i))=CStr(v)
                i=i+1
            End ForAll
            lst(key)=(cols)
            cnt=cnt+1
            Set entry=Me.Getnext(entry)
        Loop
Quit:
            Exit Sub
ErrH:
            Print {Entry lst cnt/current key} cnt {/} key
            Error Err, RaiseError
            Resume Quit
    End Sub
End Class
%REM
*********************************************
    Class ViewNavModified
    Description: for modified documents processing
    fetch entries by parent, hash by unid, update according modified date/time
    AutoSave from base class (trying to Save during Delete)
%END REM
Class ViewNavModified As ViewNavBase
    Private parent As NotesDocument
    Sub New(vName As String, parent As NotesDocument), ViewNavBase(parent.ParentDatabase, vName,parent.Universalid)
        Set me.parent=parent
    End Sub
    %REM
    *--------------------------------------------
        Function CreateDocument
        Description: Comments for Function
    %END REM
    Private Function CreateDocument(keyfld As String, values) As NotesDocument
        Dim routineName As String
        routineName="CreateDocument"
        On Error GoTo ErrH
        'your code here
        Dim tmp As NotesDocument,doc As NotesDocument
        'get original doc
        Set tmp=GetDocumentByUNIDSilent(me.dbsource, keyfld)
        Set doc=me.db.CreateDocument()
        Call tmp.Copyallitems(doc, True)
        doc.Universalid=keyfld
        Set CreateDocument=doc
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function GetHashMap
        Description: Comments for Function
    %END REM
    Sub GetHashMap(lst List As Variant)
        Dim routineName As String
        routineName="GetHashMap"
        On Error GoTo ErrH
        'your code here
        Dim  entry As NotesViewEntry, cols List As String, cnt As Long
        Set entry=first
        Erase lst
        Do While Not entry Is Nothing
            cols(UNIDDOC_COL)=entry.Columnvalues(columns(UNIDDOC_COL))
            cols(MODIFIED_COL)=entry.Columnvalues(columns(MODIFIED_COL))
            lst(cols(UNIDDOC_COL))=(cols)
            cnt=cnt+1
            Set entry=Me.Getnext(entry)
        Loop

Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Function GetKeyValueCol
        Description: return  column Index (view entry) for hash key
    %END REM
    Private Function GetKeyValueCol() As Integer
        Dim routineName As String
        routineName="GetKeyValueCol"
        On Error GoTo ErrH
        'your code here
        GetKeyValueCol=columns(UNIDDOC_COL)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function Save
        Description: expose private function from base class
    %END REM
    Public Function Save()
        Dim routineName As String
        routineName="Save"
        On Error GoTo ErrH
        'your code here
        Save=ViewNavBase..Save()
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function

    %REM
    *--------------------------------------------
        Function UpdateValues
        Description: assign nev values to entry document
        call from base class on update
    %END REM
    Private Function UpdateValues(values, entry As NotesViewEntry, docres As NotesDocument) As Boolean
        Dim routineName As String
        routineName="UpdateValues"
        On Error GoTo ErrH
        'your code here
        Dim dt As New NotesDateTime({}), dt1 As New NotesDateTime({})
        dt.Lslocaltime=CDat(values(MODIFIED_COL))
        dt1.Lslocaltime=entry.Columnvalues(columns(MODIFIED_COL))
        If dt.Timedifference(dt1)>0  Then
            'Print {time diff:}dt.Timedifference(dt1)
            'Print {Compare:}values(MODIFIED_COL){/} entry.Columnvalues(columns(MODIFIED_COL))
            Dim tmp As NotesDocument
            Set tmp=GetDocumentByUNIDSilent(me.dbsource, values(UNIDDOC_COL))
            'Print {Copy modified doc:} me.dbsource.Replicaid {/} values(UNIDDOC_COL)
            Set docres=entry.Document
            Call tmp.Copyallitems(docres,True)
            'Print {Value:} entry.Document.Getitemvalue({value})(0)
            UpdateValues=True
        End If
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class

%REM
*********************************************
    Class ViewNavModifiedWOAS
    Description: Disable AutoSave fom base class
%END REM
Class ViewNavModifiedWOAS As ViewNavModified
    Sub New(vName As String, parent As NotesDocument), ViewNavModified(vName, parent)
        me.AutoSave=False
    End Sub
    %REM
    *--------------------------------------------
        Function Save
        Description: expose private function from base class
    %END REM
    Public Function Save()
        Dim routineName As String
        routineName="Save"
        On Error GoTo ErrH
        'your code here
        Save=ViewNavModified..Save()
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class
Sub Terminate
   
End Sub

%REM
*--------------------------------------------
    Function GetVerNum
    Description: returm version number from xName string
%END REM
Function GetVerNum(xName As String) As Integer
    Dim routineName As String
    routineName="GetVerNum"
    On Error GoTo ErrH
    'your code here
    GetVerNum=(-1)
    If Not IsVersion(xName) Then GoTo Quit
    Dim ver As String
    'get left sting from rightmost VER_SIGN
    ver=StrLeftBack(xName, VER_SIGN)
    'get version sting
    ver=StrRight(UCase(ver),UCase(VER_TMPL))'protect from case sensetive
    If Len(ver)>0 Then GetVerNum=CInt(FullTrim(ver))
Quit:
    Exit Function
ErrH:
    Error Err, RaiseError
    Resume Quit
End Function
%REM
*--------------------------------------------
    Sub SetRWAccess
    Description: assign Reader Atuthor access child document according doc
%END REM
Sub SetRWAccess(doc As NotesDocument, child As NotesDocument)
'выставляет права в дочерних документах равными таковым в родительском
    On Error GoTo ErrH
    ForAll it In doc.Items
        Dim itm As NotesItem, citem As NotesItem
        Set itm=it
        If itm.IsReaders Then
            Set citem=child.ReplaceItemValue(itm.Name, itm.Values)
            citem.IsReaders=True
        ElseIf itm.IsAuthors Then
            Set citem=child.ReplaceItemValue(itm.Name, itm.Values)
            citem.IsAuthors=True
        End If
    End ForAll
Quit:
    Exit Sub
ErrH:
    RaiseError
    Resume Quit
End Sub

%REM
*--------------------------------------------
    Function IsVersion
    Description: if xName is version from base name
%END REM
Function IsVersion(xName) As Boolean
    Dim routineName As String
    routineName="IsVersion"
    On Error GoTo ErrH
'your code here
    IsVersion=UCase(xName) Like {*} &VER_SIGN &UCase(VER_TMPL) &{*} &VER_SIGN &{*}
Quit:
    Exit Function
ErrH:
    Error Err, RaiseError
    Resume Quit
End Function
"раньше" было по коллекциям доков, стало - HashMap + NotesViewNavgator скорость выросла в разы (по сети особенно заметно)
 
  • Нравится
Реакции: Vertigo

alexas1

Green Team
10.04.2014
1 202
225
BIT
36
на ODS 52 раньше замеров не делал... во щща посмотрел:

свежая база ODS 52, 100 000 доков, 2 вида - в 1 кол. юнид и все доки, и ток 1 док
на 10 000 итераций
getbyunid (первый док, который попал в базу) и чтение поля - 0.9
getbyunid (последний записанный док) и чтение поля - 0.45
bykey первого дока большого вида - 1.65
bykey последнего дока большого вида - 1.80
bykey единственного дока в виде - 1.4

та же база - 1 000 000 доков
getbyunid (первый) и чтение поля - 0.9
getbyunid (последний) и чтение поля - 0.45
bykey первого дока большого вида - 1.8
bykey последнего дока большого вида - 2.0
bykey единственного дока в виде - 1.4
entrybykey последнего дока большого вида - 4.5

взять коллекцию 4 000 энтрисов - 0.2
только пройтись по тей - 2.2
получить ВСЕ энтрисы - 180

всё с точностью 0.02 примерно
===========================
занятно)
 
  • Нравится
Реакции: Vertigo

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
Про патч почитал, , однако думаю, что док все таки сохраняется полностью, там даже транслэйшен формулы выполняются. Ну и работает только с веба.

Спасибо за подсказку про вьюэнтрисы. Потестирую.
Однозначно заметил, что если док с множеством полей, то достать с него значение - тянет время.
То есть тут я понимаю выигрыш достать значение со столбца, не залезая в док.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
entrybykey и columnvalues(1) - 4.5с
по навигатору?
[doublepost=1498052294,1498052191][/doublepost]важный момент - отрубать Count nav.EntryOptions = Vn_entryopt_nocountdata
Код:
        Set me.view=me.db.Getview(Viewname)
        me.lastAU=me.view.AutoUpdate
        me.view.AutoUpdate= False
        me.view.Refresh
        Dim entry As NotesViewEntry

        Dim NEC As NotesViewEntryCollection
        'Print {Class:} TypeName(Me) {->} {Key:} me.key
        Set NEC=view.Getallentriesbykey(me.key, True)
        If Not NEC Is Nothing Then Set entry=NEC.Getfirstentry()
        If entry Is Nothing Then
            Print {Class:} TypeName(Me) {->} {First Entry Is Nothing}
            Set nav=view.Createviewnav()'escape error if key doesn't match any entries
        Else
            'Print {Class:} TypeName(Me) {->} {Entries Count} NEC.Count
            Set me.nav=view.Createviewnavfrom(entry)
            'https://www-10.lotus.com/ldd/ddwiki.nsf/dx/Fast_Retrieval_of_View_Data_Using_the_ViewNavigator_Cache
            nav.BufferMaxEntries = NAV_BUF
            nav.EntryOptions = Vn_entryopt_nocountdata
            Set me.first=entry
            Set entry=NEC.Getlastentry()
            Set me.last=nav.Getentry(entry)
            ForAll col In me.view.Columns
                Dim tmp As NotesViewColumn
                Set tmp=col
                'Print {Column name/pos:}tmp.ItemName {/} tmp.Position-1
                me.columns(tmp.ItemName)=tmp.Position-1
            End ForAll
        End If
[doublepost=1498052899][/doublepost]
однако думаю, что док все таки сохраняется полностью, там даже транслэйшен формулы выполняются. Ну и работает только с веба.
различие в передаваемых данных, для сети это ощутимо, на большом объеме, ну да - для веб
[doublepost=1498053208][/doublepost]обычно документы имеют много полей (скрытых в т.ч.) и это дает сильную просадку по загрузке доков в память и "возврат" изменений в бэк
навигатор бежит по индексу, загружает только часть инфы и, к тому же, из локального кэша
все это и должно отразиться на перформансе
 
  • Нравится
Реакции: Vertigo

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
entrybykey последнего дока большого вида - 4.5
возможно наполнение кэша идет, интересно будет по навигатору и перебор значений ок. 1000 в сравнении с доками: мало полей, много полей (+РТ с аттачем)
 

rinsk

Lotus Team
12.11.2009
1 151
125
BIT
3
bykey первого дока большого вида - 1.8
bykey последнего дока большого вида - 2.0
bykey единственного дока в виде - 1.4
entrybykey последнего дока большого вида - 4.5
Это статика.
Если в этот момент кто то что то будет писать - даже 1 док в 10 сек - цифири будут значительно другими.
 

rinsk

Lotus Team
12.11.2009
1 151
125
BIT
3
Прикольно получается - когда апп "летает" при 60-80 коннектов и использовании getentrybykey c 5-10 мс поиска(неск объектов), а вариант doc->>Export2JSON (25 мс)+JDBC_export (30мс)+ExecuteSQL(20мс) с его 70-100мс немного задумчивей...
Но все меняется если 350-500 налетают... getentrybykey ответ до 2-3 секунд... а второй вариант те же 100мс... )))
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!