How To Count And Delete Deletion Stubs

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#1
Ниже представлен код, использующий Notes C API для получения/удаления т.з. Deletion Stub.
Код рабочий, проверен в Notes 6.5.3. Думаю в 7-ке будет работать тоже. В 8-ке не знаю...

How to count and delete deletion stubs

Christophe Windelen wrote a blog entry a couple of years ago with a solution on how to delete deletion stubs for a Lotus Notes database. Take a look at his code to accomplish that, very nice!

I have modified it just a little bit to be able to first choose which database to work on and then to choose if you only want to count or if you want to count and delete them

(Options):
Код:
Option Public
Const wAPIModule = "NNOTES" ' Windows/32

(Declarations):
Declare Private Sub IDDestroyTable Lib wAPIModule Alias "IDDestroyTable" _
( Byval hT As Long)
Declare Private Function IDScan Lib wAPIModule Alias "IDScan" _
( Byval hT As Long, Byval F As Integer, ID As Long) As Integer
Declare Private Function NSFDbOpen Lib wAPIModule Alias "NSFDbOpen" _
( Byval P As String, hDB As Long) As Integer
Declare Private Function NSFDbClose Lib wAPIModule Alias "NSFDbClose" _
( Byval hDB As Long) As Integer
Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" _
( Byval hDB As Long, Byval C As Integer, Byval S As Currency, U As Currency, hT As Long) As Integer
Declare Private Function NSFNoteDelete Lib wAPIModule Alias "NSFNoteDelete" _
( Byval hDB As Long, Byval N As Long, Byval F As Integer) As Integer
Declare Private Function OSPathNetConstruct Lib wAPIModule Alias "OSPathNetConstruct" _
( Byval NullPort As Long, Byval Server As String, Byval FIle As String, Byval PathNet As String) As Integer
Declare Private Sub TimeConstant Lib wAPIModule Alias "TimeConstant" _
( Byval C As Integer, T As Currency)
Dim Db As NotesDatabase
Initialize:
Код:
Sub Initialize
Dim Session As New NotesSession
Dim ws As New NotesUIWorkspace
Dim dbInfo As Variant
Dim sDbServer As String
Dim sDbPath As String
Dim retVal As Integer

dbInfo = ws.Prompt(13, "Choose database", "Choose a database")
sDbServer = dbInfo(0)
sDbPath = dbInfo(1)

Set db = session.GetDatabase(sDbServer, sDbPath)

retVal = ws.Prompt (PROMPT_YESNOCANCEL, _
"Delete or just count?", _
"Do you want to delete all of the deletion stubs in this database [Yes] or just count them [No]")

Select Case retVal
Case 1 : Call countAndDeleteStubs(db, 1)
Case 0 : Call countAndDeleteStubs(db, 0)
Case -1 : Msgbox "Operation cancelled"
End Select

End Sub
countAndDeleteStubs:
Код:
Sub countAndDeleteStubs(db As NotesDatabase, choice As Integer)
Dim ever As Currency, last As Currency
Dim hT As Long, RRV As Long, hDB As Long
With db
np$ = Space(1024)
OSPathNetConstruct 0, db.Server, db.FilePath, np$
End With
NSFDbOpen np$, hDB
TimeConstant 2, ever
NSFDbGetModifiedNoteTable hDB, &H7FFF, ever, last, hT
n& = 0
done = (IDScan(hT, True, RRV) = 0)
While Not done
If RRV < 0 Then
If (choice = 1) Then
NSFNoteDelete hDB, RRV And &H7FFFFFFF, &H0201
End If
n& = n& + 1
End If
done = (IDScan(hT, False, RRV) = 0)
Wend
IDDestroyTable hT
NSFDbClose hDB

If (choice = 1) Then
Msgbox "Deleted " & Cstr(n&) & " stubs in database " & db.FilePath & " on server " & db.Server
Else
Msgbox "Database " & db.FilePath & " on server " & db.Server & " contains " & Cstr(n&) & " stubs"
End If

End Sub
взято отсюда
http://www.wohill.com/design/272/How-to-co...tion-stubs.html
 

Kizarek86

Lotus team
20.07.2007
864
4
#2
Данный код не работает WinServer2008 64 и Domino 8.5.2 64.
Вешает Агент Менеджер.

Может знает кто как вылечить?)
 

Kizarek86

Lotus team
20.07.2007
864
4
#3
Использую скрипт удаления стабов:
http://codeby.net/forum/threads/30190.html

Сечас идет тест миграции с 8.0.2x32 на 8.5.2x64.

Данный скрипт на некоторое время вешает систему (запуск на сервере) на строке:
NSFDbGetModifiedNoteTable hDB, &H7FFF, ever, last, hT

После чего агент постоянно висит.

Может кто сталкивался...
Или прошу поделиться идеями.

заранее спасибо.
 

TIA

:-)
Lotus team
15.05.2009
790
3
#4
Под 64бит хэндлы стали тоже 64 бит вместо 32. Соответственно, в декларациях их надо заменить на структуру. Что-то вроде

Код:
Type HANDLE64
hLo as Long
hHi as Long
End Type

Declare Private Function NSFDbOpen Lib wAPIModule Alias "NSFDbOpen" _
( Byval P As String, hDB As HANDLE64) As Integer
Либо любой другой тип данных подходящей размерности.
Через Type можно задать параметр любой размерности, а для приведённого примера можно исп. и Double
 

Kizarek86

Lotus team
20.07.2007
864
4
#5
Код:
Const wAPIModule = "NNOTES" ' Windows/32
Type HANDLE64
hLo As Long
hHi As Long
End Type
Declare Private Sub IDDestroyTable Lib wAPIModule Alias "IDDestroyTable" (Byval hT As Long)
Declare Private Sub TimeConstant Lib wAPIModule Alias "TimeConstant" (Byval C As Integer, T As Currency)
Declare Private Function IDScan Lib wAPIModule Alias "IDScan" (Byval hT As Long, Byval F As Integer, ID As Long) As Integer
Declare Private Function NSFDbOpen Lib wAPIModule Alias "NSFDbOpen" (Byval P As String, hDB As HANDLE64) As Integer
Declare Private Function NSFDbClose Lib wAPIModule Alias "NSFDbClose" (hDB As HANDLE64) As Integer
Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" (hDB As HANDLE64, Byval C As Integer, Byval S As Currency, U As Currency, hT As Long) As Integer
Declare Private Function NSFNoteDelete Lib wAPIModule Alias "NSFNoteDelete" (hDB As HANDLE64, Byval N As Long, Byval F As Integer) As Integer
Function DeleteStubs(db As NotesDatabase, choice As Integer) As Double
Dim ever As Currency, last As Currency
Dim hT As Long, RRV As Long, hDB As HANDLE64

Call NSFDbOpen(db.Server + "!!" + db.FilePath, hDB)

Call TimeConstant(1, ever)

Call NSFDbGetModifiedNoteTable(hDB, &H7FFF, ever, last, hT)

n& = 0

done = (IDScan(hT, True, RRV) = 0) 
While Not done
If RRV < 0 Then
If (choice = 1) Then
Call NSFNoteDelete(hDB, RRV And &H7FFFFFFF, &H0201)
End If
n& = n& + 1
End If
done = (IDScan(hT, False, RRV) = 0)
Wend

Call IDDestroyTable(hT)

Call NSFDbClose(hDB)

DeleteStubs = n&
End Function
Таже фигня...
 

TIA

:-)
Lotus team
15.05.2009
790
3
#6
ByVal потерян. Я поторописля, в LS не удаётся передать Type по значению. Значит просто меняем на Double или Currency.

Код:
Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" (Byval hDB As Double, Byval C As Integer, Byval S As Currency, U As Currency, hT As Long) As Integer
 

Kizarek86

Lotus team
20.07.2007
864
4
#8
ByVal потерян. Я поторописля, в LS не удаётся передать Type по значению. Значит просто меняем на Double или Currency.

Код:
Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" (Byval hDB As Double, Byval C As Integer, Byval S As Currency, U As Currency, hT As Long) As Integer
Double и Currency ведут себя аналогично(
 

TIA

:-)
Lotus team
15.05.2009
790
3
#9
>В объявлении использовать Any.
Так значения будет передаваться по ссылке.

>Double и Currency ведут себя аналогично
Дык ещё и hT надо к правильной размерности привести
 

TIA

:-)
Lotus team
15.05.2009
790
3
#14
>Справка дизайнера с Вами не согласна:

Справка то согласна (тыц):
Arguments of type Any are always passed by reference, regardless of the type of data they contain.
 

nvyush

Lotus team
22.04.2009
2 317
0
#15
Значит у бимеров левая нога не знает, что пишет правая B)
Passing arguments by value

When an argument is passed by value, the C function receives a copy of the actual value of the argument.

To specify that the argument should always be passed by value, use the keyword ByVal preceding the parameter declaration for that argument in the Declare statement for the C function.
To specify that the argument should be passed by value in a particular call to the function, use parentheses around the argument in the call.


The C routine cannot change this value, even if the C routine defines the argument as passed by reference.
[table]
[tr]Data typeKeywordHow it is passed to a C function[/tr]
[tr]Boolean A 2-byte Integer, of value 0 or -1, is pushed on the call stack.[/tr]
[tr]Byte A 1-byte Integer value is pushed on the call stack.[/tr]
[tr]Integer A 2-byte Integer value is pushed on the call stack.[/tr]
[tr]Long A 4-byte Long value is pushed on the call stack.[/tr]
[tr]Single A 4-byte Single value is pushed on the call stack.[/tr]
[tr]Double An 8-byte Double value is pushed on the call stack.[/tr]
[tr]Currency An 8-byte value, in the LotusScript internal Currency format, is pushed on the call stack.[/tr]
[tr]String A 4-byte pointer to the characters is pushed on the call stack. The C function should not write to memory beyond the end of the string.

If the call is made with a variable, changes to the string by the C function are reflected in the variable. This is not true for a string argument to a LotusScript function declared as ByVal.[/tr]
[tr]Variant A 16-byte structure, in the LotusScript format for Variants, is pushed on the call stack.[/tr]
[tr]Product object A 4-byte product object handle is pushed on the call stack.[/tr]
[tr]Any The number of bytes of data in the argument is pushed on the call stack. For example, the argument contains a Long value, then the called function receives 4 bytes. The function may receive a different number of bytes at run time.[/tr][/table]
No other data types—arrays, lists, fixed-length strings, types, classes, or voids—can be passed by value. It is a run-time error to use these types as arguments.

Any of the data types that can be passed by value can also be passed by reference.

The argument ByVal 0& specifies a null pointer to a C function, when the argument is declared as Any.
 

hosm

* so what *
18.05.2009
2 442
6
#16
А мб, в 8ке просто переделали по сравнению с 7кой? Это надо пробовать.
 

hosm

* so what *
18.05.2009
2 442
6
#17
>Под 64бит хэндлы стали тоже 64 бит вместо 32.
Неправда насчет доминошных, цитаты из Notes С API (8.5.3):
Domino handles are 32bit on domino 32 and 64 platforms. However, windows handles are 64bit on 64bit windows. So please use DHANDLE instead of system HANDLE which is 32bit on all 32 and 64 bit platforms. Use HANDLE only when we need to use windows API but all Domino API calls should be passed with DHANDLE.
А вот указатели - да, будут 64бит под 64битную платформу.
32 bit to 64 bit changes

There are three different popular data models on 64bit platforms – LP64, LLP64 and ILP64. Windows x64 platforms use LLP64 data model. Since Domino is cross platform application we went with LLP64 on Windows x64 and other UNIX64 bit platforms. Only pointer and long long are 64bits while LONG is still maintained as 32 bit even though native long is 64bit on UNIX 64bit platforms. This makes the users to be aware of not to use long but to use LONG to be consistent across domino platforms.
 

savl

Lotus team
28.10.2011
2 136
105
#19
а если еще вот так:
STATUS LNPUBLIC NSFDbGetModifiedNoteTable(DBHANDLE hDB,WORD NoteClassMask,TIMEDATE Since,TIMEDATE far *retUntil,HANDLE far *rethTable)
Код:
Type TIMEDATE
Innards0 As Long
Innards1 As Long
End Type
Толька для retUntil сделать, а остальное оставить как было в оригинале.
 

Мыш

Премиум
12.02.2008
1 097
10
#20
Че-то они мну запутали :) Выходит, что для хэндлов long можно передавать ByVal, для указателей - Double, но использовать возвращаемые значения (судя по кэйзу), не получится?

Во чего нарыл... Ответ как-то удручает... :) Опять же, непонятно - проблемв только с этой ф-цией или с API, в целом?
И на закуску - Вот это Мораль: 64-бита - "это не наш метод". По крайней мере, на текущий момент...