PrG_Using_Superkeys.xml 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
  4. <sect1 id="Using_SuperKeys">
  5. <title><emphasis role="bold">Using SuperKeys</emphasis></title>
  6. <para>A SuperFile whose sub-files are INDEXes (not DATASETs) is a SuperKey.
  7. As described previously in the <emphasis>Indexing Into SuperFiles</emphasis>
  8. article, there is a problem with using a SuperKey to try to index into a
  9. SuperFile. So what good are SuperKeys?</para>
  10. <para>In the <emphasis>Using ECL Keys (INDEX Files)</emphasis> article, the
  11. technique of creating and using INDEXes that contain payload fields was
  12. demonstrated. By putting the payload fields in the INDEX itself, there
  13. becomes no need to directly access the base dataset from which the INDEX was
  14. built. Thus, the problem becomes moot.</para>
  15. <para>SuperKeys are built with payload keys. And, since the primary
  16. operation for a payload key is the half-keyed JOIN, that also becomes the
  17. primary SuperKey operational use.</para>
  18. <para>Both SuperFiles and SuperKeys may be used in Thor or Roxie operations.
  19. </para>
  20. <para>The following attribute definitions used by the code examples in this
  21. article are declared in the DeclareData MODULE structure attribute:</para>
  22. <programlisting>EXPORT SubKey1 := '~PROGGUIDE::SUPERKEY::Accounts1';
  23. EXPORT SubKey2 := '~PROGGUIDE::SUPERKEY::Accounts2';
  24. EXPORT SubKey3 := '~PROGGUIDE::SUPERKEY::Accounts3';
  25. EXPORT SubKey4 := '~PROGGUIDE::SUPERKEY::Accounts4';
  26. EXPORT SubIDX1 := '~PROGGUIDE::SUPERKEY::KEY::AcctsIDX1';
  27. EXPORT SubIDX2 := '~PROGGUIDE::SUPERKEY::KEY::AcctsIDX2';
  28. EXPORT SubIDX3 := '~PROGGUIDE::SUPERKEY::KEY::AcctsIDX3';
  29. EXPORT SubIDX4 := '~PROGGUIDE::SUPERKEY::KEY::AcctsIDX4';
  30. EXPORT AcctSKname :=
  31. '~PROGGUIDE::SUPERKEY::KEY::AcctsSK';
  32. EXPORT AcctSK := INDEX(Accounts,{PersonID},
  33. </programlisting>
  34. <sect2 id="Building_SuperKeys">
  35. <title>Building SuperKeys</title>
  36. <para>Before you can create a SuperKey, you must first have some INDEXes
  37. to use. The following code (contained in SuperKey1.ECL) builds four
  38. separate payload keys from the Account dataset:</para>
  39. <programlisting>IMPORT $;
  40. IMPORT Std;
  41. s1 := $.DeclareData.Accounts(Account[1] = '1');
  42. s2 := $.DeclareData.Accounts(Account[1] = '2');
  43. s3 := $.DeclareData.Accounts(Account[1] = '3');
  44. s4 := $.DeclareData.Accounts(Account[1] IN ['4','5','6','7','8','9']);
  45. Rec := $.DeclareData.Layout_Accounts_Link;
  46. RecPlus := {Rec,UNSIGNED8 RecPos{virtual(fileposition)}};
  47. d1 := DATASET($.DeclareData.SubKey1,RecPlus,THOR);
  48. d2 := DATASET($.DeclareData.SubKey2,RecPlus,THOR);
  49. d3 := DATASET($.DeclareData.SubKey3,RecPlus,THOR);
  50. d4 := DATASET($.DeclareData.SubKey4,RecPlus,THOR);
  51. i1 := INDEX(d1,{PersonID},
  52. {Account,OpenDate,IndustryCode,AcctType,AcctRate,
  53. Code1,Code2,HighCredit,Balance,RecPos},
  54. $.DeclareData.SubIDX1);
  55. i2 := INDEX(d2,{PersonID},
  56. {Account,OpenDate,IndustryCode,AcctType,AcctRate,
  57. Code1,Code2,HighCredit,Balance,RecPos},
  58. $.DeclareData.SubIDX2);
  59. i3 := INDEX(d3,{PersonID},
  60. {Account,OpenDate,IndustryCode,AcctType,AcctRate,
  61. Code1,Code2,HighCredit,Balance,RecPos},
  62. $.DeclareData.SubIDX3);
  63. i4 := INDEX(d4,{PersonID},
  64. {Account,OpenDate,IndustryCode,AcctType,AcctRate,
  65. Code1,Code2,HighCredit,Balance,RecPos},
  66. $.DeclareData.SubIDX4);
  67. BldDat := PARALLEL(
  68. IF(~Std.File.FileExists($.DeclareData.SubKey1),
  69. OUTPUT(s1,
  70. {PersonID,Account,OpenDate,IndustryCode,AcctType,
  71. AcctRate,Code1,Code2,HighCredit,Balance},
  72. $.DeclareData.SubKey1)),
  73. IF(~Std.File.FileExists($.DeclareData.SubKey2),
  74. OUTPUT(s2,
  75. {PersonID,Account,OpenDate,IndustryCode,AcctType,
  76. AcctRate,Code1,Code2,HighCredit,Balance},
  77. $.DeclareData.SubKey2)),
  78. IF(~Std.File.FileExists($.DeclareData.SubKey3),
  79. OUTPUT(s3,
  80. {PersonID,Account,OpenDate,IndustryCode,AcctType,
  81. AcctRate,Code1,Code2,HighCredit,Balance},
  82. $.DeclareData.SubKey3)),
  83. IF(~Std.File.FileExists($.DeclareData.SubKey4),
  84. OUTPUT(s4,
  85. {PersonID,Account,OpenDate,IndustryCode,AcctType,
  86. AcctRate,Code1,Code2,HighCredit,Balance},
  87. $.DeclareData.SubKey4)));
  88. BldIDX := PARALLEL(
  89. IF(~Std.File.FileExists($.DeclareData.SubIDX1),
  90. BUILDINDEX(i1)),
  91. IF(~Std.File.FileExists($.DeclareData.SubIDX2),
  92. BUILDINDEX(i2)),
  93. IF(~Std.File.FileExists($.DeclareData.SubIDX3),
  94. BUILDINDEX(i3)),
  95. IF(~Std.File.FileExists($.DeclareData.SubIDX4),
  96. BUILDINDEX(i4)));
  97. SEQUENTIAL(BldDat,BldIDX);
  98. </programlisting>
  99. <para>This code sequentially builds logical files by taking sub-sets of
  100. records from the Accounts dataset and writing those records to files on
  101. disk. Once the logical files physically exist, then the BUILDINDEX actions
  102. write the payload keys to disk.</para>
  103. <para>One interesting twist to this code is the use of the
  104. Std.File.FileExists function to detect whether these files have already
  105. been created. The code in the next section also uses the
  106. Std.File.SuperFileExists function to detect whether the SuperFile has
  107. already been created, and create it only if it hasn't been. This technique
  108. allows the example code in this article to run correctly whether another
  109. user has already gone through the examples or not.</para>
  110. </sect2>
  111. <sect2 id="Creating_a_SuperKey">
  112. <title>Creating a SuperKey</title>
  113. <para>Creating a SuperKey is exactly the same process as creating a
  114. SuperFile. The following code (contained in SuperKey2.ECL) creates a
  115. SuperKey and adds the first two payload keys to it:</para>
  116. <programlisting>IMPORT $;
  117. IMPORT Std;
  118. SEQUENTIAL(
  119. IF(~Std.File.SuperFileExists($.DeclareData.AcctSKname),
  120. Std.File.CreateSuperFile($.DeclareData.AcctSKname)),
  121. Std.File.StartSuperFileTransaction(),
  122. Std.File.ClearSuperFile($.DeclareData.AcctSKname),
  123. Std.File.AddSuperFile($.DeclareData.AcctSKname,$.DeclareData.SubIDX1),
  124. Std.File.AddSuperFile($.DeclareData.AcctSKname,$.DeclareData.SubIDX2),
  125. Std.File.FinishSuperFileTransaction());
  126. </programlisting>
  127. </sect2>
  128. <sect2 id="Using_a_SuperKey">
  129. <title>Using a SuperKey</title>
  130. <para>Once you have a SuperKey ready for use, you can use it in half-keyed
  131. JOINs, as demonstrated in this code (contained in SuperKey3.ECL):</para>
  132. <programlisting>IMPORT $;
  133. r1 := RECORD
  134. $.DeclareData.Layout_Person;
  135. $.DeclareData.Layout_Accounts;
  136. END;
  137. r1 Xform($.DeclareData.Person.FilePlus L, $.DeclareData.AcctSK R) := TRANSFORM
  138. SELF := L;
  139. SELF := R;
  140. END;
  141. J3 := JOIN($.DeclareData.Person.FilePlus(PersonID BETWEEN 1 AND 100),
  142. $.DeclareData.AcctSK,
  143. LEFT.PersonID=RIGHT.PersonID,
  144. Xform(LEFT,RIGHT));
  145. OUTPUT(J3,ALL);
  146. </programlisting>
  147. </sect2>
  148. <sect2 id="Maintaining_SuperKeys">
  149. <title>Maintaining SuperKeys</title>
  150. <para>A SuperKey is simply a SuperFile whose component sub-files are
  151. payload keys. Therefore, building and maintaining a SuperKey is exactly
  152. the same process as described already in the <emphasis>Creating and
  153. Maintaining SuperFiles</emphasis> article. The only significant difference
  154. is the manner in which you create the component sub-files, which process
  155. is already described in the <emphasis>Using ECL Keys (INDEX
  156. Files)</emphasis> article.</para>
  157. </sect2>
  158. </sect1>