⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ug_ch5b.htm

📁 db.* (pronounced dee-be star) is an advanced, high performance, small footprint embedded database fo
💻 HTM
📖 第 1 页 / 共 2 页
字号:
/* fetch each member of set and display text */while (d_findnm(CUST_NOTES, task, CURR_DB) == S_OKAY) {   d_recread(text, task, CURR_DB);   printf("%s\n", text);}</font></pre><p><font size="2">Each member of the <b>cust_notes</b> set is anoccurrence of either the <b>text30</b>, <b>text55</b>, or<b>text80</b> record types. Here it does not matter which recordtype is read, since each contains only one string field. Thecharacter array <b>text</b> is used to store the contents of all.The function <b>d_crtype</b>, however, could have been used todetermine the type of the text records.</font></p><p><b><a name="tims"></a>Database Examples from tims</b></p><p>One of the requirements for the <b>tims</b> database exampleswas to list technical publications in the library by key word orphrase. This involves traversing the many-to-many relationshipbetween the <b>key_word</b> record and the <b>info</b> record twice(once to get the <b>info</b> record from the specified key word,and again to retrieve all of the key words associated with thatlocated info record), and then scanning the <b>abstract</b> set toretrieve the text for the abstract.</p><p>Function <b>by_key</b> lists all of the <b>info</b> records thathave the user-entered key word or phrase. For each <b>info</b>record selected, all of its key words and its abstract areprinted.</p><pre><font color="#0000FF">#include &lt;stdio.h&gt;#include "db.star.h"#include "tims.h"extern DB_TASK *task;/* Find publications by key word or phrase */ by_key(){   struct info irec;   /* info record variable */      char name[SIZEOF_NAME];   /* author's name */   char key[SIZEOF_KWORD];      /* key word */   /* find key word record */   printf("key word: ");   gets(key);   if (d_keyfind(KWORD, key, task, CURR_DB) == S_NOTFOUND)      printf("no records found\n");   else    {      /* scan thru key_to_info set */      d_setor(KEY_TO_INFO, task, CURR_DB);      for (   status = d_findfm(KEY_TO_INFO, task, CURR_DB);         status == S_OKAY;         status = d_findnm(KEY_TO_INFO, task, CURR_DB))      {         /* find curr owner of curr intersect record and read it */         d_findco(INFO_TO_KEY, task, CURR_DB);               d_recread(&amp;irec, task, CURR_DB);                   /* find author of info record */         d_findco(HAS_PUBLISHED, task, CURR_DB);         d_crread(NAME, name, task, CURR_DB);                  /* print results */         printf("id_code   : %s\n", irec.id_code);         printf("author        : %s\n", name);         printf("title      : %s\n", irec.info_title);         printf("publ.        : %s, %s\n", irec.publisher, irec.pub_date);         pr_keywords();         pr_abstract();      }   }}</font></pre><p><font size="2">Figure 5-2 illustrates the operation of function<b>by_key</b> up to the point where function <b>pr_keywords</b> iscalled. The <b>d_keyfind</b> locates the <b>key_word</b> recordoccurrence, which is then made the current owner of set<b>key_to_info</b>. As each intersect record that is a member ofthe <b>info_to_key</b> set is found (using<b>d_findnm</b>(KEY_TO_INFO, CURR_DB)), its owner through the<b>info_to_key</b> set is found (using <b>d_</b>findco(INFO_TO_KEY,CURR_DB)), and the <b>info</b> record contents are read. The<b>author</b> is found (and made current) through the<b>has_published</b> set (using <b>d_findco</b>(HAS_PUBLISHED,CURR_DB)) and the name is read using function <b>d_crread</b> toread a field of the current record.</font></p><p align="center">&nbsp;</p><p align="center"><img alt="dbstar_5-2.gif - 5385 Bytes" border="0"height="292" src="dbstar_5-2.gif" width="401"></p><p align="center">Fig. 5-2. Function by_key Operation</p><p>Function <b>pr_keywords</b> is called to print all of the keywords and phrases associated with an <b>info</b> record (note thatat least one key word will appear in each list, the one chosen inthe call to <b>by_key</b>). Function <b>d_members</b> returns, invariable <b>count</b>, the number of members in set<b>info_to_key</b>. If there are any members, then the owner ofeach intersect member record is found through the<b>key_to_info</b> set, and from this owner record the key word isread and displayed. This function (<b>pr_keywords</b>) will changethe currency associated with set <b>key_to_info</b>, which is usedby function <b>by_key</b> in its scanning of that set. Thus, it isnecessary for the current member of <b>key_to_info</b> to be saved(by <b>d_csmget</b>) before the key words are retrieved, and thenrestored (by <b>d_csmset</b>, which sets both current member andcurrent owner) after they have been retrieved.</p><pre><font color="#0000FF">/* Print key words */pr_keywords(){   long count;               /* number of info_to_key members */   char key[SIZEOF_KWORD]      /* key word or phrase */   DB_ADDR dba;               /* db addr of key_to_info member */   /*   the current member of the has_published set is the      info record whose key words are to be listed */   d_setom(INFO_TO_KEY, HAS_PUBLISHED, task, CURR_DB);   /* fetch number of members of info_to_key */   d_members(INFO_TO_KEY, &amp;count, task, CURR_DB);   /* list the key words, if any */   if (count &gt; 0L)    {      /* save current member of key_to_info because it's         going to change and we may be currently scanning         though that set */      d_csmget(KEY_TO_INFO, &amp;dba, task, CURR_DB);      printf("key words:\n----------\n");      /* find each intersect member record */      while (d_findnm(INFO_TO_KEY, task, CURR_DB) == S_OKAY)       {         /* find, read and print corresponding key_word */         d_findco(KEY_TO_INFO, task, CURR_DB);         d_crread(KWORD, key, task, CURR_DB);         printf("   %s\n", key);      }      printf("\n");            /* reset key_to_info current member and owner */      if (dba != NULL_DBA)          d_csmset(KEY_TO_INFO, &amp;dba, task, CURR_DB);    }}</font></pre><p><font size="2">The abstract is printed by function<b>pr_abstract</b>, which simply scans through the abstract setowned by the current <b>info</b> record to read and display eachline of abstract text.</font></p><pre><font color="#0000FF">/* Print abstract */pr_abstract(){   long count;               /* number of abstract members */   char txt[SIZEOF_LINE];      /* line of abstract text */   /*   the current member of has_published       is the info record whose abstract is to be printed */   d_setom(ABSTRACT, HAS_PUBLISHED, task, CURR_DB);   /* fetch number of lines in abstract */   d_members(ABSTRACT, &amp;count, task, CURR_DB);   /* print abstract, if one exists */   if ( count &gt; 0L )    {      printf("abstract:\n---------\n");      /* find, read and print each abstract text line */      while (d_findnm(ABSTRACT, task, CURR_DB) == S_OKAY)       {          d_csmread(ABSTRACT, LINE, txt, task, CURR_DB);         printf("  %s\n", txt);      }   }   printf("\n");}</font></pre><p><font size="2">The other retrieval requirement is to be able tolist all of the publications in the <b>tims</b> database that areby a particular author. This is accomplished with function<b>by_author</b>. The author is located by scanning through the(system-owned) <b>author_list</b> set, and comparing auser-specified name with the author name. When a match is found,each <b>info</b> record owned by the located author is read anddisplayed, along with its associated key words andabstract.</font></p><pre><font color="#0000FF">/* Find publication by author */by_author(){   int status;   struct info irec;         /* info rec variable */   char search[SIZEOF_NAME];   /* author to search for */   char name[SIZEOF_NAME];         /* find author record */   printf("author: ");   gets(search);   for (status = d_findfm(AUTHOR_LIST, task, CURR_DB);        status == S_OKAY;        status = d_findnm(AUTHOR_LIST, task, CURR_DB))    {      d_crread(NAME, name, task, CURR_DB);      if (strcmp(search, name) == 0)         break;      else if (strcmp(search, name) &lt; 0)      {         status = S_NOTFOUND;         break;   /* sorted alphabetically */      }   }   if (status == S_OKAY )    {      d_setor(HAS_PUBLISHED, task, CURR_DB);      for (status = d_findfm(HAS_PUBLISHED, task, CURR_DB);           status == S_OKAY;            status = d_findnm(HAS_PUBLISHED, task, CURR_DB))       {         /* read and print info record */         d_recread(&amp;irec, task, CURR_DB);         printf("id_code  : %s\n", irec.id_code);         printf("author   : %s\n", name);         printf("title    : %s\n", irec.info_title);         printf("publ.    : %s, %s\n", irec.publisher, irec.pub_date);         pr_keywords();         pr_abstract();      }   }   else      printf("author record not found\n");}</font></pre><h3><a name="Direct"></a>5.4.3 Direct Access Retrieval</h3><p><font size="2">Direct access retrieval is used to locatesequentially all occurrences of a particular record type and todirectly read the contents of a record that has first been locatedby a key, set, or sequential retrieval. Sequential retrieval isperformed using these functions:</font></p><table cellspacing="0" border="0" cellpadding="7" width="542"><tr><td width="17%" valign="top"><p><b><font size="2">d_recfrst</font></b></p></td><td width="83%" valign="top"><p><font size="2">Locates the first occurrence on the data file ofthe specified record type.</font></p></td></tr><tr><td width="17%" valign="top"><p><b><font size="2">d_reclast</font></b></p></td><td width="83%" valign="top"><p><font size="2">Locates the last occurrence on the data file ofthe specified record type.</font></p></td></tr><tr><td width="17%" valign="top"><p><b><font size="2">d_recnext</font></b></p></td><td width="83%" valign="top"><p><font size="2">Finds the next occurrence of a record of the sametype.</font></p></td></tr><tr><td width="17%" valign="top"><p><b><font size="2">d_recprev</font></b></p></td><td width="83%" valign="top"><p><font size="2">Finds the next previous occurrence of a record ofthe same type.</font></p></td></tr></table><p><font size="2">When the retrieval order is not important (thephysical order of records on a file may seem random), thesequential functions are the quickest way to scan records. The<b>id_list</b> function is an example of such a scan.</font></p><pre><font color="#0000FF">/* produce a quick sequential listing of all id_code's */id_list(){   int status;   char id_code[SIZEOF_ID_CODE];   for (   status = d_recfrst(INFO, task, CURR_DB);         status == S_OKAY;          status = d_recnext(task, CURR_DB))    {      d_crread( ID_CODE, id_code, task, CURR_DB);      printf("%s\n", id_code);   }}</font></pre><p><font size="2">These functions maintain their own currency byrecord type. In a loop, these four functions will maintain theirown positional information, even if there are other functions inthe loop that change currency table settings. To establish orrestore a position from which to continue scanning, the function<b>d_recset</b> can be used. This function will set the currentposition of a sequential scan from the current record. Thus if a<b>d_recfrst/d_recnext</b> loop needs to contain an inner loop fora different record type, the position can be saved and restoredaround the inner loop, as follows:</font></p><pre><font color="#0000FF">DB_ADDR t1dba;int status1, status2;for (   status1 = d_recfrst(TYPE1, task, CURR_DB);       status1 == S_OKAY;       status1 = d_recnext(task, CURR_DB)) {   d_crget(&amp;t1dba, task, CURR_DB);   ...   for (   status2 = d_reclast(TYPE2, task, CURR_DB);         status2 == S_OKAY;         status2 = d_recprev(task, CURR_DB))    {      ...   }   d_crset(&amp;t1dba, task, CURR_DB);   d_recset(TYPE1, task, CURR_DB);}</font></pre><p><font size="2">The function <b>page_full</b> begins with thecurrent record (which is assumed to be a <b>key_word</b> type), andcreates a list of the next twenty key word occurrences, as shownbelow:</font></p><pre><font color="#0000FF">/* create a list of key words for display */page_full( char **pglist, int dir ) {   int i, status;   for (   status = d_recset(KEY_WORD, task, CURR_DB), i = 0;          (status == S_OKAY) &amp;&amp; (i &lt; 20);         status = (dir ?   d_recnext(task, CURR_DB) :                        d_recprev(task, CURR_DB)), i++ )    {      d_crread(KWORD, pglist[i], task, CURR_DB);   }}</font></pre><p><font size="2">Functions <b>d_recread</b>, <b>d_crread</b>,<b>d_csoread</b>, and <b>d_csmread</b> read part or all of thecontents of the current record, owner, or member, copying the datato an application program defined buffer. A pointer to this bufferis an argument to each of these functions.</font></p><p>Functions <b>d_decode_dba</b> and <b>d_encode_dba</b> are usedto decode and encode a database address with its file number andslot number. It can be used in conjunction with functions<b>d_crget</b> and <b>d_crset</b> to utilize a record's databaseaddress as a primary key, which can be displayed and referenced bya user in order to directly access individual record occurrences.For example, a database address for the record at slot number 17112on file number 11 could be displayed as a primary key field calledid number that, to the user, could look like the following:</p><pre><font color="#0000FF">id number:  11-17112</font></pre><p><font size="2">By always displaying this number (actually thedatabase address) when a record is displayed, and by requiring thisfield to be entered whenever the record is modified, the record canbe located in a single disk read. The code to display the fieldfollows.</font></p><pre><font color="#0000FF">DB_ADDR dba;         /* database address of current record */short file;         /* file number */unsigned long slot;   /* slot number */.../* record to be displayed is current record */d_crget(&amp;dba, task, CURR_DB);d_decode_dba(dba, &amp;file, &amp;slot);printf("id number: %d-%ld\n", file, slot);</font></pre><p><font size="2">When the user has entered an id number, therecord can be read as follows:</font></p><pre><font color="#0000FF">DB_ADDR dba;         /* database address */int file;            /* file number */unsigned long slot;   /* slot number */struct record rec;   /* db.* record buffer */.../* extract file number of slot number from id number string */... (you supply the tedious stuff)/* form database address */d_encode_dba(file, slot, &amp;dba);/* set current record and read record contents */d_crset(&amp;dba, task, CURR_DB);d_recread(&amp;rec, task, CURR_DB);/* display record */...</font></pre><p><a href="UG_Ch5c.htm">Next Page</a></p></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -