Note背后

## Note背后 ##

如前所述,Notes数据库的核心就是其中保存各种数据的通用结构note。Notes提供的很多功能都是建立在这种结构上,我们开发的应用程序也是围绕着它的应用,同时受益于和受制于它的特点。之后的几篇文章,我都会介绍一些关于这位幕后主角的信息。

在Notes数据库中,我们会接触到各种不同形式的数据。在workspace(工作台)上,可以看到数据库的图标;在视图里,可以看到文档列表;打开其中一个,可以看到文档的内容;通过相应的菜单命令,可以在对话框中看到存取控制列表和复制公式等等;在designer(设计器)里可以看到表单、代理和脚本库。所有这些数据在形式上和功能上是如此不同,但是在数据库中都是以同样的结构note保存。文档(document)作为用户note、数据note的同义词,是我们很熟悉的。对于开发和管理人员,有趣和值得注意的是,设计元素与文档从技术上说没有多少差别。或者说在Notes程序的眼中,它们只是同一种东西的不同子类,在读取、修改、保存和删除等操作上没有差别。我们在desinger中已经可以看到这一点的表现,各种设计元素的列表和显示文档的视图就十分相似,在每个设计元素的属性中,还可以看到和文档一样的域列表。我们甚至可以创建一个视图,显示设计元素。在给出这样一个例子前,我们先看看Notes是怎样区分各种note的。

Notes程序将note分成下面这些类型。

类型 说明 NOTE_CLASS 单复数
ACL 设定数据库的存取权限。 0x0040 单个
Document 用户文档。 0x0001 多个
Design 设计note集合,即NotesNoteCollection。 0x0020  
Field 共享域(字段) 0x0400 多个
Filter 代理、代理数据、大纲、脚本库、数据库脚本都归在此类型下。 0x0200  
Agent     多个
Agent Data     多个
Outline     多个
Script Library     多个
Database Script     单个
Form 表单、子表单、页面、帧结构集、图片资源、Java资源、共享操作、XPage都归在此类型下。 0x0004  
Form     多个
Subform     多个
Page     多个
Frameset     多个
Image Resource     多个
Java Resource     多个
Shared Action 所有共享操作保存在唯一的note里。   单个
Xpage     多个
Icon 设定数据库的图标、标题和分类。 0x0010 单个
Info 设定“关于数据库”的帮助。 0x0002 单个
Help 设定“使用数据库”的帮助。 0x0100 单个
Help Index 设定Notes产品帮助信息的索引。 0x0080 单个
ReplFormula 设定复制公式。 0x0800 单个
View 视图、文件夹、导航器都归在此类型下。 0x0008  
View     多个
Folder     多个
Navigator     多个

“NOTE_CLASS”是Notes程序中代表不同note类型的代码,这里用16进制表示。

“单复数”列指的是该类型的note在数据库中只能有一个还是可以有多个。

可以看出程序中Notes对note的分类,特别是设计元素,与我们在开发中认识的分类有很大的不同。表单、子表单、页面、XPage这些都是Form类型的note在应用上的分类。实际上从功能的角度我们也能体会到它们中的一些除了某些特性,确实是相同的。比如子表单除了不能单独,显示与表单完全一样;页面除了不能插入域用于保存和显示文档,与表单的功能也一致。视图和文件夹的情况也类似。

另外还可以看出,NOTE_CLASS是被设计成可以参与“或”运算的标志位。这样既可以用单个NOTE_CLASS确定某个类型的note,也可以用任意多个NOTE_CLASS的“或”组合代表多种note。比如将所有设计元素的NOTE_CLASS组合起来,就成为代表数据库中所有设计note的标志位0x7ffe,再与0x0001做“或”运算,就成为表示所有note的0x7fff。NOTE_CLASS还被用来表示其他一些含义,比如0x8000表示某类note中的默认个体,0x1000表示私有设计note。

下一个问题是,Notes程序如何区分具有相同NOTE_CLASS的不同设计元素。答案是借助于另一个文本型的标志—— Flagsitem Flags条目,它被用于保存很多重要的行为信息,其中一个字符表示一个特性,有些特性只适用于一种NOTE_CLASS,有些则对所有note都适用。通过查看设计元素的属性,可以在它们的域列表中找到$Flags。下面举几个例子:

‘A’ – FORM,说明一个子表单在增加子表单的列表中。

‘a’ – VIEW,说明一个视图不包含任何文件夹中的文档。

‘w’ – 所有,说明这个设计note对Web客户端隐藏。

‘#’ – FORM,说明这是一个帧结构集。

可以看出,确定某种设计元素的类型与描述其他特性被混合在一起,而字符的数量是有限的,所以当新特性和新类型不断被增加时,这种编码方式的资源很快会被耗尽。于是Notes开始采用“模式”,也即具有特殊功能的字符与普通字符的组合,来表示某种信息。比如用”+sh.”表示脚本库。

以上这些描述可能会显得距离太遥远,下面就来看一个实际应用的例子。

我们建一个视图来显示设计元素。不妨把视图命名为( DesignElements) DesignElements。视图选择公式(View Selection)需要由我们想包含的元素种类来决定。下表列出了每种设计元素对应的NOTE_CLASS和所需的选择公式(引自Make a Notes view list design elements)。

设计元素种类
NOTE_CLASS( 16进制 )
选择公式(R8.5)
  • Form
  • Form (4)
  • !@Matches($Flags; “*{UWy#i:|@Kgz}*”)
  • View
  • View (8)
  • !@Matches($Flags; “*{FG^}*”)
  • Folder
  • View (8)
  • @Contains($Flags; “F”)
  • Agent
  • Filter (200)
  • !@Matches($Flags; “*{QXstmz{}*”)
  • Image
  • Form (4)
  • @Contains($Flags; “i”)
  • Subform
  • Form (4)
  • @Contains($Flags; “U”)
  • Outline
  • Filter (200)
  • @Contains($Flags; “m”)
  • Frameset
  • Form (4)
  • @Contains($Flags; “#”)
  • Page
  • Form (4)
  • @Contains($Flags; “W”)
  • Script Library (excluding Web Service Consumers)
  • Filter (200)
  • @Matches( Flags; "*{sh}*") & !@Contains(FlagsExt; “W”)
  • Stylesheet
  • Form (4)
  • @Contains($Flags; “=”)
  • Theme
  • Form (4)
  • @Contains( Flags; "g") & @Contains(Flags; “`”)
  • Composite Application
  • Form (4)
  • @Contains($Flags; “|”)
  • Wiring Properties
  • Form (4)
  • @Contains($Flags; “:”)
  • Web Service Consumer
  • Filter (200)
  • @Contains( FlagsExt; "W") & @Matches(Flags; “*{sh}*”)
  • Web Service Provider
  • Filter (200)
  • @Contains($Flags; “{“)
  • XPage
  • Form (4)
  • @Contains( Flags; "g") & @Contains(Flags; “K”)
  • Custom Control
  • Form (4)
  • @Contains( Flags; "g") & @Contains(Flags; “;”)
  • File Resource
  • Form (4)
  • @Contains( Flags; "g") & !@Matches(Flags; “*{~K[];`}*”)
  • Hidden File Resource (created by XPage build)
  • Form (4)
  • @Contains( Flags; "g") & @Contains(Flags; “~”) & !@Matches($Flags; “*{~K[];`}*”)
  • Shared Field
  • Field (400)
  • N/A
  • Shared Action
  • Form (4)
  • @Contains($Flags; “y”)
  • Database Icon
  • Icon (10)
  • N/A
  • Help About Document
  • Help About (2)
  • N/A
  • Help Using Document
  • Help Using (100)
  • N/A
  • Database Script
  • Filter (200)
  • @Contains($Flags; “t”)
  • Data Connection
  • Filter (200)
  • @Contains($Flags; “k”)
  • Navigator
  • View (8)
  • @Contains($Flags; “G”)
  • Applet
  • Form (4)
  • @Contains($Flags; “@”)
  • Shared Column
  • View (8)
  • @Contains($Flags; “^”)
  • DB2 Access View
  • Form (4)
  • @Contains($Flags; “z”)
  • Stored full-text query
  • Filter (200)
  • @Contains($Flags; “O”)
  • Agent Data Note
  • Filter (200)
  • @Contains($Flags; “X”)
  • Database ACL
  • ACL (40)
  • N/A

因为每个设计元素的名称都保留在一个$Title条目中,所以可以建一个名称列,公式为:

$Title

根据需要和喜好,还可以添加“最近修改人”,“最近修改时间”等列。

针对含有代码的设计元素(代理、脚本库等)我们还可以显示它们使用的编程语言,公式为:

f:=$Flags;
@If(@Contains(f; “s”);
@If(@Contains(f; “j”);
“Java“;
@IsAvailable(“$ScriptLib”);
“LotusScript”;”“);
@Contains(f; “j”); “Java”;
@Contains(f; “L”); “LotusScript”;
@Contains(f; “f”); “Formula”;
“”)

现在在Notes中显示这个视图,什么都没有!因为在视图中还有一个开关—— FormulaClassnoteNOTECLASS1NOTECLASSFORMnote,4note32766NotesDocumentNotesDocumentGetViewNotesViewnoteNotesDocument使noteGetDocumentByUNIDNotesViewUniversalIDnoteUniversalIDDesignElements FormulaClass条目。考虑到今后可能会对这个视图做修改,而在某些版本(例如6.5)的设计器中,每次视图在被保存时,$FormulaClass条目都会被自动恢复成”1”,所以我们将这段代码放在视图的一个按钮中,每次修改视图之后,都在Notes客户端运行一次。

[vb] view plain copy
print ?
  1. Option Public   
  2. Option Declare  
  3. Sub Initialize  
  4.     Dim s As New NotesSession  
  5.     Dim db As NotesDatabase  
  6.     Set db=s.CurrentDatabase  
  7.     Dim view As NotesView  
  8.         Set view=db.GetView(DesignElements")  
  9.     If view Is Nothing Then      Exit Sub      End If        Dim viewDoc As NotesDocument      Set viewDoc=db.GetDocumentByUNID(view.UniversalID)      '将FormulaClass改成任何希望包含的设计元素对应的值。  
  10.     Call viewDoc.ReplaceItemValue(“$FormulaClass”,“4”)  
  11.     Call viewDoc.Sign()  
  12.     Call viewDoc.Save(True,False)  
  13.   
  14.     Dim ws As New NotesUIWorkspace  
  15.     Call ws.ViewRebuild()  
  16. End Sub  
Option Public 
Option Declare
Sub Initialize
    Dim s As New NotesSession
    Dim db As NotesDatabase
    Set db=s.CurrentDatabase
    Dim view As NotesView
        Set view=db.GetView("$DesignElements")
    If view Is Nothing Then
    Exit Sub
    End If

    Dim viewDoc As NotesDocument
    Set viewDoc=db.GetDocumentByUNID(view.UniversalID)
    '将$FormulaClass改成任何希望包含的设计元素对应的值。
    Call viewDoc.ReplaceItemValue("$FormulaClass","4")
    Call viewDoc.Sign()
    Call viewDoc.Save(True,False)

    Dim ws As New NotesUIWorkspace
    Call ws.ViewRebuild()
End Sub
最后需要指出的是,因为需要同时使用NOTE_CLASS和选择公式才能确定某些设计元素的类型,所以如果将上述视图的 FormulaClassnote32766使使!@Match()NOTECLASS使 FormulaClass为某个具体的NOTE_CLASS值。

你可能感兴趣的:(Lotus,数据库,Lotus-Note)