コード例 #1
0
ファイル: filamtxt.cpp プロジェクト: SunguckLee/MariaDB
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
ファイル: filamtxt.cpp プロジェクト: SunguckLee/MariaDB
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
ファイル: filamtxt.cpp プロジェクト: SunguckLee/MariaDB
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
コード例 #4
0
ファイル: filamtxt.cpp プロジェクト: SunguckLee/MariaDB
int DOSFAM::ReadBuffer(PGLOBAL g)
  {
  char *p;
  int   rc;

  if (!Stream)
    return RC_EF;

  if (trace > 1)
    htrc("ReadBuffer: Tdbp=%p To_Line=%p Placed=%d\n",
                      Tdbp, Tdbp->To_Line, Placed); 

  if (!Placed) {
    /*******************************************************************/
    /*  Record file position in case of UPDATE or DELETE.              */
    /*******************************************************************/
    if (RecordPos(g))
      return RC_FX;

    CurBlk = (int)Rows++;

     if (trace > 1)
      htrc("ReadBuffer: CurBlk=%d\n", CurBlk); 

  } else
    Placed = false;

  if (trace > 1)
    htrc(" About to read: stream=%p To_Buf=%p Buflen=%d\n",
                          Stream, To_Buf, Buflen);

  if (fgets(To_Buf, Buflen, Stream)) {
    p = To_Buf + strlen(To_Buf) - 1;

    if (trace > 1)
      htrc(" Read: To_Buf=%p p=%c\n", To_Buf, To_Buf, p);

#if defined(UNIX)
    if (true) {
      // Data files can be imported from Windows (having CRLF)
#else
    if (Bin) {
      // Data file is read in binary so CRLF remains
#endif
      if (*p == '\n' || *p == '\r') {
        // is this enough for Unix ???
        *p = '\0';          // Eliminate ending CR or LF character

        if (p > To_Buf) {
          // is this enough for Unix ???
          p--;

          if (*p == '\n' || *p == '\r')
            *p = '\0';      // Eliminate ending CR or LF character

          } // endif To_Buf

        } // endif p

    } else if (*p == '\n')
      *p = '\0';          // Eliminate ending new-line character

    if (trace > 1)
      htrc(" To_Buf='%s'\n", To_Buf);

    strcpy(Tdbp->To_Line, To_Buf);
    num_read++;
    rc = RC_OK;
  } else if (feof(Stream)) {
    rc = RC_EF;
  } else {
#if defined(UNIX)
    sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
#else
    sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#endif

    if (trace)
      htrc("%s\n", g->Message);

    rc = RC_FX;
  } // endif's fgets

  if (trace > 1)
    htrc("ReadBuffer: rc=%d\n", rc);

  IsRead = true;
  return rc;
  } // end of ReadBuffer

/***********************************************************************/
/*  WriteBuffer: File write routine for DOS access method.             */
/***********************************************************************/
int DOSFAM::WriteBuffer(PGLOBAL g)
  {
  char *crlf = "\n";
  int  curpos = 0;
  bool  moved = true;

  // T_Stream is the temporary stream or the table file stream itself
  if (!T_Stream)
    if (UseTemp && Tdbp->Mode == MODE_UPDATE) {
      if (OpenTempFile(g))
        return RC_FX;

    } else
      T_Stream = Stream;

  if (Tdbp->Mode == MODE_UPDATE) {
    /*******************************************************************/
    /*  Here we simply rewrite a record on itself. There are two cases */
    /*  were another method should be used, a/ when Update apply to    */
    /*  the whole file, b/ when updating the last field of a variable  */
    /*  length file. The method could be to rewrite a new file, then   */
    /*  to erase the old one and rename the new updated file.          */
    /*******************************************************************/
    curpos = ftell(Stream);

    if (trace)
      htrc("Last : %d cur: %d\n", Fpos, curpos);

    if (UseTemp) {
      /*****************************************************************/
      /*  We are using a temporary file. Before writing the updated    */
      /*  record, we must eventually copy all the intermediate records */
      /*  that have not been updated.                                  */
      /*****************************************************************/
      if (MoveIntermediateLines(g, &moved))
        return RC_FX;

      Spos = curpos;                          // New start position
    } else
      // Update is directly written back into the file,
      //   with this (fast) method, record size cannot change.
      if (fseek(Stream, Fpos, SEEK_SET)) {
        sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
        return RC_FX;
        } // endif

    } // endif mode

  /*********************************************************************/
  /*  Prepare the write buffer.                                        */
  /*********************************************************************/
#if defined(WIN32)
  if (Bin)
    crlf = "\r\n";
#endif   // WIN32
  strcat(strcpy(To_Buf, Tdbp->To_Line), crlf);

  /*********************************************************************/
  /*  Now start the writing process.                                   */
  /*********************************************************************/
  if ((fputs(To_Buf, T_Stream)) == EOF) {
    sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno));
    return RC_FX;
    } // endif EOF

  if (Tdbp->Mode == MODE_UPDATE && moved)
    if (fseek(Stream, curpos, SEEK_SET)) {
      sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
      return RC_FX;
      } // endif

  if (trace)
    htrc("write done\n");

  return RC_OK;
  } // end of WriteBuffer
コード例 #5
0
ファイル: filamtxt.cpp プロジェクト: SunguckLee/MariaDB
int BLKFAM::WriteBuffer(PGLOBAL g)
  {
  if (Tdbp->GetMode() == MODE_INSERT) {
    /*******************************************************************/
    /*  In Insert mode, blocks are added sequentially to the file end. */
    /*******************************************************************/
    if (!Closing) {                    // Add line to the write buffer
      strcat(strcpy(CurLine, Tdbp->GetLine()), CrLf);

      if (++CurNum != Rbuf) {
        CurLine += strlen(CurLine);
        return RC_OK;                  // We write only full blocks
        } // endif CurNum

      } // endif Closing

    //  Now start the writing process.
    NxtLine = CurLine + strlen(CurLine);
    BlkLen = NxtLine - To_Buf;

    if (fwrite(To_Buf, 1, BlkLen, Stream) != (size_t)BlkLen) {
      sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
      Closing = true;      // To tell CloseDB about a Write error
      return RC_FX;
      } // endif size

    CurBlk++;
    CurNum = 0;
    CurLine = To_Buf;
  } else {
    /*******************************************************************/
    /*  Mode == MODE_UPDATE.                                           */
    /*******************************************************************/
    char  *crlf;
    size_t len;
    int   curpos = ftell(Stream);
    bool   moved = true;

    // T_Stream is the temporary stream or the table file stream itself
    if (!T_Stream)
      if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) {
        if (OpenTempFile(g))
          return RC_FX;

      } else
        T_Stream = Stream;

    if (UseTemp) {
      /*****************************************************************/
      /*  We are using a temporary file. Before writing the updated    */
      /*  record, we must eventually copy all the intermediate records */
      /*  that have not been updated.                                  */
      /*****************************************************************/
      if (MoveIntermediateLines(g, &moved))
        return RC_FX;

      Spos = GetNextPos();                     // New start position

      // Prepare the output buffer
#if defined(WIN32)
      crlf = "\r\n";
#else
      crlf = "\n";
#endif   // WIN32
      strcat(strcpy(OutBuf, Tdbp->GetLine()), crlf);
      len = strlen(OutBuf);
    } else {
      if (fseek(Stream, Fpos, SEEK_SET)) {   // Fpos is last position
        sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
        return RC_FX;
        } // endif fseek

      // Replace the line inside read buffer (length has not changed)
      memcpy(CurLine, Tdbp->GetLine(), strlen(Tdbp->GetLine()));
      OutBuf = CurLine;
      len = (size_t)(NxtLine - CurLine);
    } // endif UseTemp

    if (fwrite(OutBuf, 1, len, T_Stream) != (size_t)len) {
      sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
      return RC_FX;
      } // endif fwrite

    if (moved)
      if (fseek(Stream, curpos, SEEK_SET)) {
        sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
        return RC_FX;
        } // endif

  } // endif Mode

  return RC_OK;
  } // end of WriteBuffer
コード例 #6
0
ファイル: filamdbf.cpp プロジェクト: knielsen/mariadb-10.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