Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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