home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / src / create.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-25  |  8.5 KB  |  321 lines

  1. /*
  2.  * METALBASE 5.0
  3.  *
  4.  * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  5.  *                                       [ t-richj@microsoft.com ]
  6.  */
  7.  
  8. #define CREATE_C
  9. #include "mbase.h"
  10. #include "internal.h"
  11.  
  12. /*
  13.  ******************************************************************************
  14.  *
  15.  */
  16.  
  17. relation *
  18. mb_new ()
  19. {
  20.    relation *rel;
  21.  
  22.    if ((rel = New (relation)) == RNULL)
  23.       relerr (MB_NO_MEMORY, RNULL);
  24.  
  25.    rel->num_i  = 0;
  26.    rel->num_f  = 0;
  27.    rel->serial = 0L;
  28.  
  29.    relerr (MB_OKAY, rel);
  30. }
  31.  
  32. mb_err
  33. mb_addindex (rel, name, dups, desc)
  34. relation    *rel;
  35. char             *name,      *desc;
  36. int                     dups;
  37. {
  38.    char  *pch, *line, temp[128], t2[5];
  39.    int    i;
  40.  
  41.    if (_identify (rel) != -1 || dups < 0 || dups > 1 ||
  42.        ! name || ! *name || ! desc || *desc < '0' || *desc > '9')
  43.       {
  44.       baderr (MB_BAD_INDEX);
  45.       }
  46.  
  47.    rel->itype[rel->num_i] = dups;  /* 1 == dups, 0 == nodups */
  48.  
  49.    strcpy (rel->iname[rel->num_i], name);
  50.    strcpy (rel->idxs[rel->num_i], "000");
  51.  
  52.    strcpy (temp, desc);
  53.    line  = temp;
  54.  
  55.    for (i = 0; i < MAX_IDX-1; i++)
  56.       {
  57.       if ((pch = strchr (line, ',')) == NULL)
  58.          break;
  59.       *pch = 0;
  60.  
  61.       sprintf (t2, "%03d", atoi (line));
  62.       strcat (rel->idxs[rel->num_i], t2);
  63.  
  64.       line = pch+1;
  65.       }
  66.  
  67.    sprintf (t2, "%03d", atoi (line));
  68.    strcat (rel->idxs[rel->num_i], t2);
  69.  
  70.    sprintf (t2, "%03d", i+1);
  71.    strncpy (rel->idxs[rel->num_i], t2, 3);
  72.  
  73.    rel->num_i ++;
  74.  
  75.    baderr (MB_OKAY);
  76. }
  77.  
  78. mb_err
  79. mb_addfield (rel, name, type, arg)
  80. relation    *rel;
  81. char             *name;
  82. ftype                   type;
  83. long                          arg;
  84. {
  85.    strcpy (rel->name[rel->num_f], name);
  86.  
  87.    if (type == T_SERIAL)
  88.       {
  89.       rel->serial = arg;  /* serial is temporary storage for NextSerial */
  90.       }
  91.  
  92.    switch (rel->type[rel->num_f] = type)
  93.       {
  94.       case T_CHAR:    rel->siz [rel->num_f] = (int)arg;  break;
  95.       case T_SHORT:   rel->siz [rel->num_f] =  2;        break;
  96.       case T_USHORT:  rel->siz [rel->num_f] =  2;        break;
  97.       case T_LONG:    rel->siz [rel->num_f] =  4;        break;
  98.       case T_ULONG:   rel->siz [rel->num_f] =  4;        break;
  99.       case T_FLOAT:   rel->siz [rel->num_f] =  4;        break;
  100.       case T_DOUBLE:  rel->siz [rel->num_f] =  8;        break;
  101.       case T_MONEY:   rel->siz [rel->num_f] =  8;        break;
  102.       case T_TIME:    rel->siz [rel->num_f] =  4;        break;
  103.       case T_DATE:    rel->siz [rel->num_f] =  4;        break;
  104.       case T_SERIAL:  rel->siz [rel->num_f] =  4;        break;
  105.       }
  106.  
  107.    rel->num_f ++;
  108.  
  109.    baderr (MB_OKAY);
  110. }
  111.  
  112.  
  113. /*
  114.  ******************************************************************************
  115.  *
  116.  */
  117.  
  118. mb_err
  119. mb_create (rel, name, mem)
  120. relation  *rel;
  121. char           *name;
  122. int                   mem;
  123. {
  124.    char   temp[35];
  125.    int    i, R, n, j;
  126.    short  tshort;
  127.    long   tlong;
  128.  
  129.    (void)mem;    /* Reference for compiler's sake; unused in MetalBase 5.0 */
  130.  
  131.    if (! rel || _identify (rel) != -1)
  132.       baderr (MB_BAD_REL);
  133.  
  134.    if (! rel->num_i)   baderr (MB_NO_INDICES);
  135.    if (! rel->num_f)   baderr (MB_NO_FIELDS);
  136.  
  137.  
  138. /*
  139.  * See if we can create the file (if it already exists, delete it).
  140.  *
  141.  */
  142.  
  143.    if (access (name, 0) != -1)
  144.       unlink (name);
  145.    if ((R = creatx (name)) == -1)
  146.       baderr (MB_NO_WRITE);
  147.    modex (name, 0666);   /* Make the file   -rw-rw-rw-  */
  148.    close (R);
  149.  
  150.    if ((R = openx (name, OPENMODE)) == -1)
  151.       {
  152.       unlink (name);  /* We made it, but can't open it, so delete it. */
  153.       baderr (MB_NO_WRITE);
  154.       }
  155.  
  156.  
  157. /*
  158.  * Great; we've created the file.  Now fill it out...
  159.  *
  160.  */
  161.  
  162.    temp[0] = 50;  writx (R, temp, 1);  /* MetalBase 5.0 Signature */
  163.    temp[0] =  0;  writx (R, temp, 1);  /* Zero users              */
  164.  
  165.    for (tshort = 0, i = 0; i < 2; i++)
  166.       write (R, &tshort, 2);           /* Temporary and exclusive locks */
  167.  
  168.    for (tlong = 0L, i = 0; i < 3; i++)
  169.       writx (R, &tlong, 4);            /* Pointers to fields,indices,recs */
  170.  
  171.    writx (R, &tlong, 4);               /* Number of records */
  172.    writx (R, &rel->serial, 4);         /* Next serial value */
  173.  
  174.    tshort = (short)rel->num_f;  writx (R, &tshort, 2);  /* Number of fields  */
  175.    tshort = (short)rel->num_i;  writx (R, &tshort, 2);  /* Number of indices */
  176.  
  177.    for (i = 0; i < rel->num_i; i++)
  178.       writx (R, &tlong, 4);       /* Pointers to top of each index tree */
  179.  
  180. /*
  181.  * That was ugly.  We're now ready to write the fields' descriptions...
  182.  *
  183.  */
  184.  
  185.    tlong = lseek (R, 0L, 1);               /* Current position?             */
  186.    lseek (R, POS_FIELDPTR(verCURRENT), 0); /* Pointer to fields' positions  */
  187.    writx (R, &tlong, 4);
  188.    lseek (R, tlong, 0);           /* Move back to where we were    */
  189.  
  190. /*
  191.  * A: var*F.....Fields' descriptions:
  192.  *                 byte    0 : Type (0-10, as listed above)
  193.  *                 bytes 1-2 : Size (short/ used only for char fields)
  194.  *                 bytes 3-? : Name (max len = 20, terminated by '|')
  195.  *
  196.  */
  197.  
  198.    for (i = 0; i < rel->num_f; i++)
  199.       {
  200.       temp[0] = (char)rel->type[i];   writx (R,  temp,   1);
  201.       tshort  = (short)rel->siz[i];   writx (R, &tshort, 2);
  202.  
  203.       writx (R, rel->name[i], strlen(rel->name[i]));
  204.       writx (R, "|", 1);
  205.       }
  206.  
  207. /*
  208.  * That was uglier.  We're now ready to write the indices' descriptions...
  209.  *
  210.  */
  211.  
  212.    tlong = lseek (R, 0L, 1);   /* Current position?             */
  213.    lseek (R, POS_INDEXPTR, 0); /* Pointer to indices' positions */
  214.    writx (R, &tlong, 4);
  215.    lseek (R, tlong, 0);        /* Move back to where we were    */
  216.  
  217. /*
  218.  * B: var*I.....Indices' descriptions:
  219.  *                 byte    0 : Type (0-1, 0==nodups, 1==dups)
  220.  *                 bytes   1 : Number of fields in this index
  221.  *                 bytes 2-? : Name (max len = 20, terminated by ':')
  222.  *                       --- : Each field's sequential # (as short, 0-based)
  223.  *      1.......Separator ('\n')
  224.  *
  225.  */
  226.  
  227.    for (i = 0; i < rel->num_i; i++)
  228.       {
  229.       strzcpy (temp, rel->idxs[i], 3);
  230.       n = atoi (temp);
  231.  
  232.       temp[0] = (char)rel->itype[i];  /* 0==nodups, 1==dups                */
  233.       temp[1] = (char)n;              /* N==number of fields in this index */
  234.  
  235.       writx (R, temp, 2);
  236.  
  237.       writx (R, rel->iname[i], strlen (rel->iname[i]));
  238.       writx (R, ":", 1);
  239.  
  240.       for (j = 0; j < n; j++)
  241.          {
  242.          strzcpy (temp, &rel->idxs[i][3 + j*3], 3);
  243.          tshort = (short)atoi (temp);
  244.          writx (R, &tshort, 2);
  245.          }
  246.       }
  247.  
  248. /*
  249.  * Next, there's the stuff that's new to 5.0-- rel->hack points to the position
  250.  * of all the new stuff.  Included are:
  251.  *    6 bytes (3 * sizeof(short))  - Hacklock positions
  252.  *   60 bytes (30 * sizeof(short)) - Thirty-position service queue
  253.  *   30 bytes (30 * sizeof(char))  - Queue strobes
  254.  *   32 bytes (8 * sizeof(long))   - Reserved for later use
  255.  *
  256.  */
  257.  
  258.    rel->hack = lseek (R, 0L, 1);  /* Remember current position */
  259.    tshort = 0;
  260.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  261.  
  262.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  263.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  264.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  265.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  266.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  267.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  268.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  269.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  270.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  271.    writx (R, &tshort, 2); writx (R, &tshort, 2); writx (R, &tshort, 2);
  272.  
  273.    for (i = 0; i < 30; i++)
  274.       temp[i] = 0;
  275.  
  276.    writx (R, temp, 30);
  277.  
  278.    tlong = 0L;
  279.    writx (R, &tlong, 4); writx (R, &tlong, 4);  /* RESERVED SPACE */
  280.    writx (R, &tlong, 4); writx (R, &tlong, 4);  /* RESERVED SPACE */
  281.    writx (R, &tlong, 4); writx (R, &tlong, 4);  /* RESERVED SPACE */
  282.    writx (R, &tlong, 4); writx (R, &tlong, 4);  /* RESERVED SPACE */
  283.  
  284.    writx (R, SNGCR, NUMCR);
  285.  
  286.    tlong = lseek (R, 0L, 1);   /* Current position?             */
  287.    lseek (R, POS_RECZERO, 0);  /* Pointer to record #0          */
  288.    writx (R, &tlong, 4);
  289.  
  290.    rel->recz = tlong;
  291.  
  292.    close (R);
  293.  
  294.    baderr (MB_OKAY);
  295. }
  296.  
  297. int
  298. mb_getname (rel, name, fIndex)
  299. relation   *rel;
  300. char            *name;
  301. int                    fIndex;
  302. {
  303.    int   i;
  304.  
  305.    if (fIndex)
  306.       {
  307.       for (i = 0; i < rel->num_i; i++)
  308.          if (! strcmp (rel->iname[i], name))
  309.             return i;
  310.       }
  311.    else
  312.       {
  313.       for (i = 0; i < rel->num_f; i++)
  314.          if (! strcmp (rel->name[i], name))
  315.             return i;
  316.       }
  317.  
  318.    return -1;
  319. }
  320.  
  321.