note IDs詳解

轉載自:http://note IDsdeveloper.e800.com.cn/articles/2008/514/1210751113936_1.html

本文詳細描述了 note IDs,並且解釋了 Domino or Notes 任務 (複製等)使用 note ID 的組件時有什麼不同以及 API 程序怎麼使用他們.

  note ID 包括如下部分:

  UNID (Universal Note ID) - 唯一地確定了文檔(note), 不管它(note)是位於何處或所處何時.另一方面, 每個文檔(note)的複本擁有相同的 UNID, 並且 UNID 不會因爲文檔的更改而變化.

  OID (Originator ID) - 確定文檔(note)的特殊的修訂版本,不管它(note)位於何處,也就是說,每個文檔(note)的複本擁有相同的 OID, 但是當文檔(note)更改時OID也會隨之修改.

  GNID (Global Note ID) - 確定一個特殊數據庫中的一個特殊文檔(note),GNID 不會隨文檔(note)的改變而變化。一個文檔(note)複本的GNID可能會不同,因爲畢竟他們在數據庫中的位置可能不同。

  NID (Note ID) - 確定給定數據庫中的一個特殊的文檔(note)。NID 不包含數據庫的信息(只在數據庫內定位有效:譯者注),並且文檔(note)修改時不會變化。

  IID (Instance ID) - 確定一個給定數據庫中的一個文檔(note)的特殊修訂版本,IID 不包含數據庫信息,文檔(note)修改時,IID會變化。

  GIID (Global Instance ID) - 確定一個特殊數據庫中的一個文檔(note)的特殊修訂版本. GIID 包含數據庫信息。The GIID 文檔(note)修改時,IID會變化。

  你可以從 Notes 用戶界面可以檢查 ID 的信息。在視圖中選擇一個文檔並且打開它。然後選擇菜單 文件 - 文檔屬性。Notes 顯示“文檔屬性”信息框。在信息頁,Notes 顯示和這個文檔相關聯的數據信息,包括文檔創建和修改的日期和時間以及note ID 信息。 note ID 信息顯示成三行,包含關鍵字和16進制字符。對於一個典型的文檔,通常是這個樣子:

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  這三行包含所選文檔 Originator ID (OID), Universal Note ID (UNID), Global Note ID (GID), 和 Note ID (NID) 。

  The Universal Note ID (UNID) and the Originator ID (OID)

  第一、二行組成了完整的 Originator ID, Originator ID 由 Universal Note ID (整個第一行)加上序列時間和序列號(第二行):

  Originator ID (OID) =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  Universal Note ID (UNID) =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  Sequence Time =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  ************************

  Sequence Number =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  Originator ID (或 Universal Note ID)的前兩部分由文件號(File member)和文檔號(note member)組成。第一行由 /"OF/" (/"Originator ID - File/"),緊跟16個16進制字符,然後是連字符 /"-/" ,然後是 /"ON/" (/"Originator ID - Note/"),後面又是16個16進制字符。 /"OF/" 後面連字符之前的16個16進制字符構成了OID的文件號(File member)。/"ON/" 後面連字符之前的16個16進制字符構成了OID的文檔號(note member)。

  OID.File =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  OID.Note =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  在頭文件 nsfdata.h 中包含了下面的定義 ORIGINATORID 數據結構和 UNIVERSALNOTEID 數據結構:

  typedef struct {

  DBID File; /* Unique (random) number */

  /* (Even though this field is called /"File,/" */

  /* it doesn/'t have anything to do with the file!) */

  TIMEDATE Note; /* Original Note Creation time/date */

  /* (THE ABOVE 2 FIELDS MUST BE FIRST - UNID */

  /* COPIED FROM HERE ASSUMED AT OFFSET 0) */

  DWORD Sequence; /* LOW ORDER: sequence number, 1 for first version */

  /* HIGH ORDER WORD: flags, as above */

  TIMEDATE SequenceTime;/* time/date when sequence number was bumped */

  } ORIGINATORID;

  #define OID ORIGINATORID

  typedef struct {

  DBID File; /* Unique (random) number */

  /* (Even though this field is called /"File,/" */

  /* it doesn/'t have anything to do with the file!) */

  TIMEDATE Note; /* Original Note Creation time/date */

  } UNIVERSALNOTEID;

  #define UNID UNIVERSALNOTEID

  文檔的 Originator ID (OID) 確定了同一個文檔(note)的所有複本。OID 由兩部分組成:Universal Note ID (UNID) 和序列號(sequence number)、序列時間( sequence time)。 UNID 唯一的確定了同一個文檔(note)的所有場合的複本。序列號(sequence number )和序列時間( sequence time) 放在一起區別同一文檔(note)的不同版本。

  Universal note ID (UNID) 確定了駐留在所有服務器上的同一個文檔(note)。然而,UNID 缺少直接訪問一個給定數據庫中的文檔(note)的信息。UNID 用於從一個文檔來(note)引用另一個指定的文檔(note)。答覆文檔中的/"$REF/" (FIELD_LINK) 域包含了其父文檔的 UNID , DocLinks(參見nsfdata.h中的 NOTELINK 數據結構)包含了鏈接文檔(note)的 UNID ,和鏈接視圖的 UNID 以及鏈接文檔所在數據庫的 ID (ViewLinks 包含了相同的信息,不同的是鏈接文檔的那部分全部設爲0, 而 DatabaseLinks 包含的信息是鏈接文檔和鏈接視圖的部分全部設爲0) 。UNID 的重要特徵是它能總是確定同一個文檔(),不論它是否更新過。

  UNID, the OID, 和複製器( Replicator)

  Universal Note ID (Originator ID的第一部分) 唯一的確定了同一文檔(note)的所有版本和複本。如果兩個文檔(note)具有相同的UNID則它們互爲複本。因此,相同文檔(note)的所有複本的不同版本都有相同的 UNID。這就導出一個必然的結論:一個數據庫中不能含有兩個具有相同UNID的文檔(note)。如果複製器(replicator)發現同一個數據庫中兩個文檔(note)具有相同的UNID,它就會產生一個錯誤消息寫到日誌裏,並且不對文檔進行復制。

  完整的 Originator ID, 從另一個方面唯一地確定了一個文檔(note)的一個特殊版本。就是說,一個文檔的相同版本的複本具有相同的OID。同時,一個文檔(note)複本修改後,它就會有不同的OID。因爲在文檔(note)被編輯後, Domino 和 Notes 會增加序列號(sequence number)和序列時間(sequence)。 當文檔(note)的一個複本保持不變,而另一個複本被編輯並修改,於是這兩個複本具有相同的 UNID但是序列號(sequence number)和序列時間(sequence times)不同,因此OID也不同。

  Domino 複製器(replicator)使用UNID 來匹配數據庫中的文檔(note),例如:如果數據庫A和數據庫B進行復制,數據庫A中有個文檔含有特殊的UNID,但是數據庫B中沒有,於是複製器(replicator)在數據庫B中創建一個該文檔的複本拷貝。

  如果數據庫A中包含一個文檔(note)同時數據庫B中有個文檔(note)和它有相同的UNID,複製器(replicator)推斷這兩個文檔(note)是同一個文檔的兩個複本。這種情況下,複製器(replicator)繼續檢查兩個文檔的序列號(sequence number )和序列時間(sequence time),然後複製器(replicator)推斷是否是同一時間更新過需不需要複製。如果序列號(sequence number )或序列時間(sequence time)其中有一個或兩個都不同,複製器必須決定哪一個是最近更新的哪一個比較舊一點。

  如果其中一個更新過,而另一個未更新過,這樣第一個複本的序列號會比第二個複本的序列號大,複製器(replicator)根據這種情況使用第一個複本覆蓋第二個複本,從而達到兩個數據庫同步的目的。

  複製衝突

  複製衝突(Replication conflicts)發生在同時編輯並保存同一個文檔(note)。如果用戶修改了數據庫A中的一個文檔複本,而另一個數據庫B中的文檔複本也被修改(所作修改都在上一次成功複製之後,下一次複製之前),於是兩個文檔複本具有相同的序列號()但是序列時間不同。這種情況下,複製器產生一個複製衝突,因爲一個文檔的兩個複本在同一時期都進行了修改。(如果把一個文檔的多個複本看成是同一個文檔的話,這就表示同一個文檔同時被修改。)

  複製器通過生成複製衝突文檔處理這種複製衝突。序列時間較早的文檔(document)被標誌爲衝突文檔。兩個數據庫中將會具有兩個文檔,只不過序列時間較早的文檔會成爲序列時間較晚的文檔的答覆文檔。

  複製器產生複製文檔衝突,會在衝突文檔前標誌黑色菱形標記。複製器把序列時間較晚的文檔拷貝到序列時間較早的文檔所在的數據庫中,並完整的保持它的 OID。 然後複製器把序列時間較早的文檔轉成一個新的文檔生成一個截然不同的 OID 並給它增加一個特殊的條目 /"$Conflict/" (VIEW_CONFLICT_ITEM) 。 這個 $Conflict 條目會使文檔在視圖的左邊顯示一個黑色的菱形標記,表示它是一個衝突文檔。 複製器也會給這個衝突文檔增加一個$REF 條目使他變成答覆文檔,$REF 條目中含有其父文檔(序列時間較晚)的UNID。

  注意: 衝突文檔(黑色菱形標記文檔)並不總是立刻出現在兩個服務器上。當擁有序列時間較晚文檔的服務器發起複製時,衝突文檔不會立刻在複製完成後出現在這個服務器上,但是會出現在那個擁有序列時間較早文檔的服務器上。這是因爲複製器僅在擁有序列時間較早文檔的服務器上產生複製衝突文檔(黑色菱形標記)。

  特殊地,當服務器B初始發起複製,首先服務器B從服務器A拉(PULL),然後服務器A從服務器B拉(PULL)。當服務器B從服務器A拉動改變時,B看到了A上的衝突文檔,發現B上的文檔較新(序列時間較晚),所以不會把A上的衝突文檔拉到B上。這樣做的理由是因爲B已經是最新的文檔了,不需要再取得舊的文檔了。然後 A 從B拉動改變,看到B上的文檔較新,因此A把自己的較舊的文檔變成複製衝突(黑色菱形),並把B上的較新的文檔拷貝到A上。這就滿足複製的需要:使數據庫保持最新的同步。於是衝突文檔(較晚的)不會出現在B上。下一次服務器B和服務器A進行復制時,衝突文檔(較晚的)就會出現同時出現在兩個服務器上達到同步的目的。

  The OID and the API

  API 程序使用 NSFNoteGetInfo 來獲得 Originator ID 的不同構件,可以指定 _NOTE_OID 標誌位,例如:

  ORIGINATORID NoteOID;

  /*

  * Get the OID from the note AFTER it has been updated

  */

  NSFNoteGetInfo (hNote, _NOTE_OID, &NoteOID);

  NSFNoteUpdate 導致 Domino 和 Notes 改變正在更新的文檔的序列號(sequence number)和序列時間(sequence time)。 因此, API 程序特別注意他們調用 NSFNoteUpdate 和 NSFNoteGetInfo 的順序。

  特別的,使用 NSFNoteCreate 創建一個新文檔(note)獲得文檔的句柄後,直到這個文檔保存到數據庫中(使用 NSFNoteUpdate),NSFNoteGetInfo 才能返回有效的 OID。但是,既然這時 UNID 已經被賦值,所以 API 程序能夠使用 NSFNoteGetInfo 分析並返回新建文檔的 UNID 。

  UNID.File

  OID的文件號(File member )包含了一個號碼,依賴於 Domino 或 Notes 的不同版本。 Notes 2.1之前的版本中,文件號表示數據庫文件創建的時間和日期。Notes 2.1 版本設置文件號(File member)跟用戶有關的唯一標誌符,一部分取自創建文檔的用戶的ID,一部分取自文檔所在的數據庫。Notes 3.0 及以後版本文檔創建後把文件號(File member)設置成一個隨機的號碼。

  UNID.Note

  OID的文檔號(Note member)是文檔創建的時間。 (詳細信息參見數據結構 TIMEDATE )

  Global Note ID (GNID) and NOTEID (NID)

  Global Note ID (GNID) 由兩部分組成:數據庫 ID 和文檔ID(Note ID)。既然 GNID 確定數據庫和數據庫中的文檔,所以它可以唯一的確定所有數據庫中所有文檔的所有複本。

  GNID 出現在 ID 信息的最後一行(使用 Design - Document Properties信息框)。第一部分對應數據結構 GLOBALNOTEID 的文件部分(File member),第二部分對應數據結構 GLOBALNOTEID的 NoteID 部分。

  Global Note ID (GNID) =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  Database ID (GNID.File) =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  Note ID (GNID.NoteID) =

  ID: OF0000039D:3836C29F-ON85255DC9:0056FB94

  SD00255DF4:0057B8FA-SN00000003

  DB85255CD9:00567287-NT0000C092

  第三行開始是字符 /"DB/" (表示 /"Data Base/"),緊跟16個16進制字符,然後是連字符,然後是 /"NT/" (/"NoTe/"),跟着是8個16進制字符。在/"DB/" 後連字符前的16個16進制字符構成了 GNID的文件號(File member), /"NT/" 後的8個16進制字符構成 Note ID 。

  Global Note ID (GNID)

  不象 OID,GNID 不能區別同一文檔的不同版本,因爲 NoteID 和包含文檔的文件有關,所以文檔複本的 GNID 很可能不同。

  Database ID (GNID的文件部分)包含了數據庫的複本ID(replica ID),API 頭文件 nsfdata.h 定義 DBID 數據結構爲 TIMEDATE類型:

  #define DBID TIMEDATE

  這個 8-byte DBID 包含了數據庫原始創建的 TIMEDATE。你可以驗證GNID的文件號(File member),顯示在 File - Document 屬性對話框,將會和數據庫的 Replica ID相同,它顯示在 File - Database 屬性信息框。因爲一個特殊數據庫中的所有複本都有相同的 DBID,所以一個數據庫中的所有複本數據庫中的所有文檔都有相同的 GNID.File.

  typedef struct {

  DBID File; /* Creation Date/Time of NSF where note was created */

  NOTEID NoteID; /* Note/'s RRV in this file */

  } GLOBALNOTEID;

  #define GNID GLOBALNOTEID

  Note ID (NID)

  note ID (NID) 確定數據庫中的一個文檔。NID 是文檔(note)的記錄重佈置向量(Record Relocation Vector (RRV))的文件位置。一個 RRV 是一個 DWORD 型的偏移量。 因爲 note ID 有時會被描述爲 /"the Note/'s RRV in this file./",所以常會導致錯誤的理解。事實上,note ID 對於 RRV來講是在文件中的偏移量,表示文檔記錄的入口點。RRV 是一個基本的數據結構,而 note ID 則更加明確。在 Domino 和Notes 內部,除了文檔之外的其他不同對象也都有相關的 RRV。

  typedef DWORD RRV;

  typedef DWORD NOTEID;

  在一個數據庫文件中,note ID 保證不會改變,除非這個文檔被刪除。當文檔被刪除時,note ID中的RRV_DELETED 標誌位被設置。

  #define RRV_DELETED 0x80000000L /* indicates a deleted note */

  因爲 note ID 在數據庫文件中是明確的,其他數據庫中的同一文檔的複本拷貝很可能會有不同的 note ID。 INSTANCEID (IID) Instance ID 表示給定數據庫中的文檔對象的實例。每次文檔(note)被修改,Domino 或 Notes 使用時間和日期標誌 instance ID。Instance ID 由文檔修改的 TIMEDATE 和 note ID組成。

  typedef struct {

  TIMEDATE Note; /* Note/'s MODIFICATION date/time */

  NOTEID NoteID; /* Note/'s RRV */

  } INSTANCEID;

  #define IID INSTANCEID

  文檔修改的 TIMEDATE (數據結構IID中的 Note 部分)和OID的修訂時間不是相同的概念。數據庫視圖使用文檔(note)的 IID 修改時間 來決定什麼時候顯示未讀文檔標誌。你可以使用NSFNoteGetInfo 並指定 _NOTE_MODIFIED 標誌位來訪問IID修改時間。 複製器使用OID的修訂時間(Revision Time)來比較不同數據庫中文檔的複本。 可以使用NSFNoteGetInfo 並指定 _NOTE_OID 標誌位來訪問OID修訂時間。

  IID的 NoteID 部分是和GNID的 NoteID部分值相同。

  NSFNoteUpdate 每次 NSF 文件更新時更新修改時間,這個修改時間(modification timedate)控制視圖顯示未讀文檔標記。

  一個API程序有幾種方式得到 IID ,從GNID 中取得Note ID,NIFReadEntries 緩衝區或者 SEARCH_MATCH數據結構的ID的NoteID 部分 。從SEARCH_MATCH數據結構的ID的NoteID 部分,或者調用 NSFNoteGetInfo 並指定 _NOTE_MODIFIED標誌位來獲取修改時間

  GLOBALINSTANCEID (GIID)

  Global Instance ID 是跨數據庫的文檔(note)實例。它包含了 Instance ID 的相同的部分並且增加了 database ID作爲文件號。帶有最近修改時間的文檔是最新( /"most recent/")實例。

  typedef struct {

  DBID File; /* database Creation time/date */

  TIMEDATE Note; /* note Modification time/date */

  NOTEID NoteID; /* note ID in database */

  } GLOBALINSTANCEID;

  #define GIID GLOBALINSTANCEID

  API 程序能夠初始化一個 GIID 數據結構給文檔,通過調用 NSFDbIDGet 來獲得文件號,調用 NSFNoteGetInfo並指定_NOTE_MODIFIED 來獲得對應於修改時間的部分。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章