void DOSFAM::CloseTableFile(PGLOBAL g) { int rc; if (UseTemp && T_Stream) { if (Tdbp->Mode == MODE_UPDATE) { // Copy eventually remaining lines bool b; fseek(Stream, 0, SEEK_END); Fpos = ftell(Stream); rc = MoveIntermediateLines(g, &b); } // endif Mode // Delete the old file and rename the new temp file. RenameTempFile(g); // Also close all files } else { rc = PlugCloseFile(g, To_Fb); if (trace) htrc("DOS Close: closing %s rc=%d\n", To_File, rc); } // endif UseTemp Stream = NULL; // So we can know whether table is open } // end of CloseTableFile
void BLKFAM::CloseTableFile(PGLOBAL g) { int rc, wrc = RC_OK; if (UseTemp && T_Stream) { if (Tdbp->GetMode() == MODE_UPDATE) { // Copy eventually remaining lines bool b; fseek(Stream, 0, SEEK_END); Fpos = ftell(Stream); rc = MoveIntermediateLines(g, &b); } else rc = RC_OK; if (rc == RC_OK) // Delete the old file and rename the new temp file. rc = RenameTempFile(g); // Also close all files else rc = PlugCloseFile(g, To_Fb); } else { // Closing is True if last Write was in error if (Tdbp->GetMode() == MODE_INSERT && CurNum && !Closing) { // Some more inserted lines remain to be written Rbuf = CurNum--; Closing = true; wrc = WriteBuffer(g); } else if (Modif && !Closing) { // Last updated block remains to be written Closing = true; wrc = ReadBuffer(g); } // endif's rc = PlugCloseFile(g, To_Fb); if (trace) htrc("BLK CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n", To_File, Tdbp->GetMode(), wrc, rc); } // endif UseTemp Stream = NULL; // So we can know whether table is open } // end of CloseTableFile
void MAPFAM::CloseTableFile(PGLOBAL g) { PlugCloseFile(g, To_Fb); To_Fb = NULL; // To get correct file size in Cardinality if (trace) htrc("MAP Close: closing %s count=%d\n", To_File, (To_Fb) ? To_Fb->Count : 0); } // end of CloseTableFile
int DOSFAM::RenameTempFile(PGLOBAL g) { char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH]; int rc; if (!To_Fbt) return RC_INFO; // Nothing to do ??? // This loop is necessary because, in case of join, // To_File can have been open several times. for (PFBLOCK fb = PlgGetUser(g)->Openlist; fb; fb = fb->Next) if (fb == To_Fb || fb == To_Fbt) rc = PlugCloseFile(g, fb); tempname = (char*)To_Fbt->Fname; PlugSetPath(filename, To_File, Tdbp->GetPath()); strcat(PlugRemoveType(filetemp, filename), ".ttt"); remove(filetemp); // May still be there from previous error if (rename(filename, filetemp)) { // Save file for security sprintf(g->Message, MSG(RENAME_ERROR), filename, filetemp, strerror(errno)); rc = RC_FX; } else if (rename(tempname, filename)) { sprintf(g->Message, MSG(RENAME_ERROR), tempname, filename, strerror(errno)); rc = rename(filetemp, filename); // Restore saved file rc = RC_FX; } else if (remove(filetemp)) { sprintf(g->Message, MSG(REMOVE_ERROR), filetemp, strerror(errno)); rc = RC_INFO; // Acceptable } else rc = RC_OK; return rc; } // end of RenameTempFile
int DOSFAM::DeleteRecords(PGLOBAL g, int irc) { bool moved; int curpos = ftell(Stream); /*********************************************************************/ /* There is an alternative here: */ /* 1 - use a temporary file in which are copied all not deleted */ /* lines, at the end the original file will be deleted and */ /* the temporary file renamed to the original file name. */ /* 2 - directly move the not deleted lines inside the original */ /* file, and at the end erase all trailing records. */ /* This will be experimented, but method 1 must be used for Unix as */ /* the function needed to erase trailing records is not available. */ /*********************************************************************/ if (trace) htrc( "DOS DeleteDB: rc=%d UseTemp=%d curpos=%d Fpos=%d Tpos=%d Spos=%d\n", irc, UseTemp, curpos, Fpos, Tpos, Spos); if (irc != RC_OK) { /*******************************************************************/ /* EOF: position Fpos at the end-of-file position. */ /*******************************************************************/ fseek(Stream, 0, SEEK_END); Fpos = ftell(Stream); if (trace) htrc("Fpos placed at file end=%d\n", Fpos); } // endif irc if (Tpos == Spos) { /*******************************************************************/ /* First line to delete, Open temporary file. */ /*******************************************************************/ if (UseTemp) { if (OpenTempFile(g)) return RC_FX; } else { /*****************************************************************/ /* Move of eventual preceeding lines is not required here. */ /* Set the target file as being the source file itself. */ /* Set the future Tpos, and give Spos a value to block copying. */ /*****************************************************************/ T_Stream = Stream; Spos = Tpos = Fpos; } // endif UseTemp } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ if (MoveIntermediateLines(g, &moved)) return RC_FX; if (irc == RC_OK) { /*******************************************************************/ /* Reposition the file pointer and set Spos. */ /*******************************************************************/ if (!UseTemp || moved) if (fseek(Stream, curpos, SEEK_SET)) { sprintf(g->Message, MSG(FSETPOS_ERROR), 0); return RC_FX; } // endif Spos = GetNextPos(); // New start position if (trace) htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos); } else { /*******************************************************************/ /* Last call after EOF has been reached. */ /* The UseTemp case is treated in CloseTableFile. */ /*******************************************************************/ if (!UseTemp) { /*****************************************************************/ /* Because the chsize functionality is only accessible with a */ /* system call we must close the file and reopen it with the */ /* open function (_fopen for MS ??) this is still to be checked */ /* for compatibility with Text files and other OS's. */ /*****************************************************************/ char filename[_MAX_PATH]; int h; // File handle, return code PlugSetPath(filename, To_File, Tdbp->GetPath()); /*rc=*/ PlugCloseFile(g, To_Fb); if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0) return RC_FX; /*****************************************************************/ /* Remove extra records. */ /*****************************************************************/ #if defined(UNIX) if (ftruncate(h, (off_t)Tpos)) { sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno)); close(h); return RC_FX; } // endif #else if (chsize(h, Tpos)) { sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno)); close(h); return RC_FX; } // endif #endif close(h); if (trace) htrc("done, h=%d irc=%d\n", h, irc); } // endif !UseTemp } // endif irc return RC_OK; // All is correct } // end of DeleteRecords
void DBFFAM::CloseTableFile(PGLOBAL g, bool abort) { int rc = RC_OK, wrc = RC_OK; MODE mode = Tdbp->GetMode(); Abort = abort; // Closing is True if last Write was in error if (mode == MODE_INSERT && CurNum && !Closing) { // Some more inserted lines remain to be written Rbuf = CurNum--; // Closing = true; wrc = WriteBuffer(g); } else if (mode == MODE_UPDATE || mode == MODE_DELETE) { if (Modif && !Closing) { // Last updated block remains to be written Closing = true; wrc = WriteModifiedBlock(g); } // endif Modif if (UseTemp && T_Stream && wrc == RC_OK) { if (!Abort) { // Copy any remaining lines bool b; Fpos = Tdbp->Cardinality(g); Abort = MoveIntermediateLines(g, &b) != RC_OK; } // endif Abort // Delete the old file and rename the new temp file. RenameTempFile(g); goto fin; } // endif UseTemp } // endif's mode if (Tdbp->GetMode() == MODE_INSERT) { int n = ftell(Stream) - Headlen; rc = PlugCloseFile(g, To_Fb); if (n >= 0 && !(n % Lrecl)) { n /= Lrecl; // New number of lines if (n > Records) { // Update the number of rows in the file header char filename[_MAX_PATH]; PlugSetPath(filename, To_File, Tdbp->GetPath()); if ((Stream= global_fopen(g, MSGID_OPEN_MODE_STRERROR, filename, "r+b"))) { fseek(Stream, 4, SEEK_SET); // Get header.Records position fwrite(&n, sizeof(int), 1, Stream); fclose(Stream); Stream= NULL; Records= n; // Update Records value } } // endif n } // endif n } else // Finally close the file rc = PlugCloseFile(g, To_Fb); fin: if (trace) htrc("DBF CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n", To_File, mode, wrc, rc); Stream = NULL; // So we can know whether table is open } // end of CloseTableFile