#ident "$URL: svn://elmer/devel/SVN/SDDAS/trunk/libdB/CloseNdx.c $ %D% SwRI" #include #include #include #include #include #include #include #include #include #include "dbf.h" /******************** ** >FILE: CloseNdx.c ********************/ /******************************************** ** Function: int CloseNdx(int dbf, int ndx) ** ** Description: ** This subroutine closes the index file associated with the database ** structure d. If the current record has been updated then it is written ** to the database file. Once the database file is closed, all the ** parameters in the database structure is reset. ** ** Return Values: ** ***************** *****************/ dbRet_t CloseNdx(SDDAS_INT dbf, SDDAS_INT ndx) { struct tm *mytm; struct stat buf; dbfRecord_t *D; ndxRecord_t *N; char *cptr, iHeader[96]; int fd, nbytes; SDDAS_INT i; if ((D = GetOldDbfHandle(dbf)) == NULL) return FAILURE; if ((N = GetOldNdxHandle(dbf, ndx)) == NULL) return FAILURE; if (N->Index == NULL) return SUCCESS; /* | if the header information for the index file has changes re-write it to | the index file */ if (N->iStatus == Updated) { /* | first, let's clear a buffer out that will hold this information */ memset(iHeader, 0, sizeof(iHeader)); /* | fill the buffer with the next free record, the maximum number of index | records the current index array will hold, and the number of index | fields for the current index array */ *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT)]) = N->NextFreeIndexRec; *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT) * 2]) = N->MAXIndexRecs; *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT) * 3]) = N->NumIndexFields; /* | now fill the buffer with all the key field info */ cptr = &iHeader[sizeof (SDDAS_INT) * 4]; N->KeyLen = 0; for (i=0; iNumIndexFields; i++) { memcpy(cptr, (N->IndexFields+i)->Name, FIELD_NAME_LEN); memcpy(cptr+FIELD_NAME_LEN, (char *)&(N->IndexFields+i)->Typ, 3); *(cptr+15) = '\0'; cptr += 16; N->KeyLen += N->IndexFields[i].Len; } /* | open the index file */ if ((fd = open(N->IndexName, O_CREAT | O_RDWR | O_BINARY, 0666)) < 0) { dbf_code = errno; sprintf(msg, "'%s'", N->IndexName); return FAILURE; } /* | get the date of the file for the header information */ (void)fstat(fd, &buf); mytm = localtime(&buf.st_mtime); iHeader[1] = (char) mytm->tm_year; /* Year */ iHeader[2] = (char) mytm->tm_mon; /* Month of year */ iHeader[3] = (char) mytm->tm_mday; /* Day of month */ /* | write out the header information */ if (write(fd, (char *)iHeader, sizeof(iHeader)) < sizeof(iHeader)) { dbf_code = errno; sprintf(msg, "'%s'", N->IndexName); return FAILURE; } /* | now determine the size of the index array and write it out */ nbytes = N->KeyLen + DB_ALIGN(N->KeyLen) + sizeof(SDDAS_INT); nbytes *= N->MAXIndexRecs; if (write(fd, (char *)N->Index, nbytes) < nbytes) { dbf_code = errno; sprintf(msg, "'%s'", N->IndexName); return FAILURE; } /* | close the index file */ (void)close(fd); } free((char *)N->IndexFields); free(N->Index); if (N == D->ndxRecords) D->ndxRecords = N->next; else { ndxRecord_t *n; for (n = D->ndxRecords ; n->next != NULL; n = n->next) if (n->next == N) break; n->next = N->next; } free(N); return SUCCESS; }