Example #1
0
bool DBFFAM::OpenTableFile(PGLOBAL g)
  {
  char    opmode[4], filename[_MAX_PATH];
//int     ftype = Tdbp->GetFtype();
  MODE    mode = Tdbp->GetMode();
  PDBUSER dbuserp = PlgGetUser(g);

  switch (mode) {
    case MODE_READ:
      strcpy(opmode, "rb");
      break;
    case MODE_DELETE:
      if (!Tdbp->GetNext()) {
        // Store the number of deleted lines
        DelRows = -1;      // Means all lines deleted
//      DelRows = Cardinality(g); no good because of soft deleted lines

        // This will erase the entire file
        strcpy(opmode, "w");
        Tdbp->ResetSize();
        Records = 0;
        break;
        } // endif

      // Selective delete, pass thru
    case MODE_UPDATE:
      UseTemp = Tdbp->IsUsingTemp(g);
      strcpy(opmode, (UseTemp) ? "rb" : "r+b");
      break;
    case MODE_INSERT:
      // Must be in text mode to remove an eventual EOF character
      strcpy(opmode, "a+");
      break;
    default:
      sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
      return true;
    } // endswitch Mode

  // Now open the file stream
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!(Stream = PlugOpenFile(g, filename, opmode))) {
    if (trace)
      htrc("%s\n", g->Message);
    
    return (mode == MODE_READ && errno == ENOENT)
            ? PushWarning(g, Tdbp) : true;
    } // endif Stream

  if (trace)
    htrc("File %s is open in mode %s\n", filename, opmode);

  To_Fb = dbuserp->Openlist;     // Keep track of File block

  /*********************************************************************/
  /*  Allocate the line buffer. For mode Delete a bigger buffer has to */
  /*  be allocated because is it also used to move lines into the file.*/
  /*********************************************************************/
  return AllocateBuffer(g);
  } // end of OpenTableFile
Example #2
0
bool TDBCAT::Initialize(PGLOBAL g)
  {
  if (Init)
    return false;

  if (!(Qrp = GetResult(g)))
    return true;

  if (Qrp->Truncated) {
    sprintf(g->Message, "Result limited to %d lines", Qrp->Maxres);
    PushWarning(g, this);
    } // endif Truncated

  if (Qrp->BadLines) {
    sprintf(g->Message, "%d bad lines in result", Qrp->BadLines);
    PushWarning(g, this);
    } // endif Badlines

  Init = true;
  return false;
  } // end of Initialize
Example #3
0
PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode)
  {
  /*********************************************************************/
  /*  Allocate a TDB of the proper type.                               */
  /*  Column blocks will be allocated only when needed.                */
  /*********************************************************************/
  // Mapping not used for insert (except for true VEC not split tables)
  // or when UseTemp is forced
  bool map = Mapped && (Estimate || mode != MODE_INSERT) &&
             !(PlgGetUser(g)->UseTemp == TMP_FORCE &&
             (mode == MODE_UPDATE || mode == MODE_DELETE));
  PTXF txfp;
  PTDB tdbp;

  if (Multiple) {
    strcpy(g->Message, MSG(NO_MUL_VCT));
    return NULL;
    } // endif Multiple

  if (Split) {
    if (map)
      txfp = new(g) VMPFAM(this);
    else
      txfp = new(g) VECFAM(this);

  } else if (Huge)
    txfp = new(g) BGVFAM(this);
  else if (map)
    txfp = new(g) VCMFAM(this);
  else
    txfp = new(g) VCTFAM(this);

  tdbp = new(g) TDBVCT(this, txfp);

  /*********************************************************************/
  /*  For block tables, get eventually saved optimization values.      */
  /*********************************************************************/
  if (mode != MODE_INSERT)
    if (tdbp->GetBlockValues(g))
      PushWarning(g, (PTDBASE)tdbp);
//    return NULL;            // causes a crash when deleting index

  return tdbp;
  } // end of GetTable
Example #4
0
bool MAPFAM::OpenTableFile(PGLOBAL g)
  {
  char    filename[_MAX_PATH];
  int     len;
  MODE    mode = Tdbp->GetMode();
  PFBLOCK fp;
  PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;

#if defined(_DEBUG)
  // Insert mode is no more handled using file mapping
  assert(mode != MODE_INSERT);
#endif   // _DEBUG

  /*********************************************************************/
  /*  We used the file name relative to recorded datapath.             */
  /*********************************************************************/
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  /*********************************************************************/
  /*  Under Win32 the whole file will be mapped so we can use it as    */
  /*  if it were entirely read into virtual memory.                    */
  /*  Firstly we check whether this file have been already mapped.     */
  /*********************************************************************/
  if (mode == MODE_READ) {
    for (fp = dbuserp->Openlist; fp; fp = fp->Next)
      if (fp->Type == TYPE_FB_MAP && !stricmp(fp->Fname, filename)
                     && fp->Count && fp->Mode == mode)
        break;

    if (trace)
      htrc("Mapping file, fp=%p\n", fp);

  } else
    fp = NULL;

  if (fp) {
    /*******************************************************************/
    /*  File already mapped. Just increment use count and get pointer. */
    /*******************************************************************/
    fp->Count++;
    Memory = fp->Memory;
    len = fp->Length;
  } else {
    /*******************************************************************/
    /*  If required, delete the whole file if no filtering is implied. */
    /*******************************************************************/
    bool   del;
    HANDLE hFile;
    MEMMAP mm;

    del = mode == MODE_DELETE && !Tdbp->GetNext();

    if (del)
      DelRows = Cardinality(g);

    /*******************************************************************/
    /*  Create the mapping file object.                                */
    /*******************************************************************/
    hFile = CreateFileMap(g, filename, &mm, mode, del);

    if (hFile == INVALID_HANDLE_VALUE) {
      DWORD rc = GetLastError();

      if (!(*g->Message))
        sprintf(g->Message, MSG(OPEN_MODE_ERROR),
                "map", (int) rc, filename);

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

      return (mode == MODE_READ && rc == ENOENT)
              ? PushWarning(g, Tdbp) : true;
      } // endif hFile

    /*******************************************************************/
    /*  Get the file size (assuming file is smaller than 4 GB)         */
    /*******************************************************************/
    len = mm.lenL;
    Memory = (char *)mm.memory;

    if (!len) {              // Empty or deleted file
      CloseFileHandle(hFile);
      Tdbp->ResetSize();
      return false;
      } // endif len

    if (!Memory) {
      CloseFileHandle(hFile);
      sprintf(g->Message, MSG(MAP_VIEW_ERROR),
                          filename, GetLastError());
      return true;
      } // endif Memory

#if defined(WIN32)
    if (mode != MODE_DELETE) {
#else   // !WIN32
    if (mode == MODE_READ) {
#endif  // !WIN32
      CloseFileHandle(hFile);                    // Not used anymore
      hFile = INVALID_HANDLE_VALUE;              // For Fblock
      } // endif Mode

    /*******************************************************************/
    /*  Link a Fblock. This make possible to reuse already opened maps */
    /*  and also to automatically unmap them in case of error g->jump. */
    /*  Note: block can already exist for previously closed file.      */
    /*******************************************************************/
    fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
    fp->Type = TYPE_FB_MAP;
    fp->Fname = (char*)PlugSubAlloc(g, NULL, strlen(filename) + 1);
    strcpy((char*)fp->Fname, filename);
    fp->Next = dbuserp->Openlist;
    dbuserp->Openlist = fp;
    fp->Count = 1;
    fp->Length = len;
    fp->Memory = Memory;
    fp->Mode = mode;
    fp->File = NULL;
    fp->Handle = hFile;                // Used for Delete
  } // endif fp

  To_Fb = fp;                               // Useful when closing

  /*********************************************************************/
  /*  The pseudo "buffer" is here the entire file mapping view.        */
  /*********************************************************************/
  Fpos = Mempos = Memory;
  Top = Memory + len;

  if (trace)
    htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n",
          fp, fp->Count, Memory, len, Top);

  return AllocateBuffer(g);          // Useful for DBF files
  } // end of OpenTableFile

/***********************************************************************/
/*  GetRowID: return the RowID of last read record.                    */
/***********************************************************************/
int MAPFAM::GetRowID(void)
  {
  return Rows;
  } // end of GetRowID

/***********************************************************************/
/*  GetPos: return the position of last read record.                   */
/***********************************************************************/
int MAPFAM::GetPos(void)
  {
  return Fpos - Memory;
  } // end of GetPos

/***********************************************************************/
/*  GetNextPos: return the position of next record.                    */
/***********************************************************************/
int MAPFAM::GetNextPos(void)
  {
  return Mempos - Memory;
  } // end of GetNextPos

/***********************************************************************/
/*  SetPos: Replace the table at the specified position.               */
/***********************************************************************/
bool MAPFAM::SetPos(PGLOBAL g, int pos)
  {
  Fpos = Mempos = Memory + pos;

  if (Mempos >= Top || Mempos < Memory) {
    strcpy(g->Message, MSG(INV_MAP_POS));
    return true;
    } // endif Mempos

  Placed = true;
  return false;
  } // end of SetPos
Example #5
0
bool DOSFAM::OpenTableFile(PGLOBAL g)
  {
  char    opmode[4], filename[_MAX_PATH];
//int     ftype = Tdbp->GetFtype();
  MODE    mode = Tdbp->Mode;
  PDBUSER dbuserp = PlgGetUser(g);

  // This is required when using Unix files under Windows
  Bin = (Ending == 1);

  switch (mode) {
    case MODE_READ:
      strcpy(opmode, "r");
      break;
    case MODE_DELETE:
      if (!Tdbp->Next) {
        // Store the number of deleted lines
        DelRows = Cardinality(g);

        if (Blocked) {
          // Cardinality must return 0
          Block = 0;
          Last = Nrec;
          } // endif blocked

        // This will erase the entire file
        strcpy(opmode, "w");
        Tdbp->ResetSize();
        break;
        } // endif

      // Selective delete, pass thru
      Bin = true;
    case MODE_UPDATE:
      if ((UseTemp = Tdbp->IsUsingTemp(g))) {
        strcpy(opmode, "r");
        Bin = true;
      } else
        strcpy(opmode, "r+");

      break;
    case MODE_INSERT:
      strcpy(opmode, "a+");
      break;
    default:
      sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
      return true;
    } // endswitch Mode

  // For blocked I/O or for moving lines, open the table in binary
  strcat(opmode, (Blocked || Bin) ? "b" : "t");

  // Now open the file stream
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!(Stream = PlugOpenFile(g, filename, opmode))) {
    if (trace)
      htrc("%s\n", g->Message);

    return (mode == MODE_READ && errno == ENOENT)
            ? PushWarning(g, Tdbp) : true;
    } // endif Stream

  if (trace)
    htrc("File %s open Stream=%p mode=%s\n", filename, Stream, opmode);

  To_Fb = dbuserp->Openlist;     // Keep track of File block

  /*********************************************************************/
  /*  Allocate the line buffer. For mode Delete a bigger buffer has to */
  /*  be allocated because is it also used to move lines into the file.*/
  /*********************************************************************/
  return AllocateBuffer(g);
  } // end of OpenTableFile
Example #6
0
PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
  {
  PTDBASE tdbp;

  if (Catfunc != FNC_COL) {
    USETEMP tmp = Use_Temp;
    bool    map = Mapped && mode != MODE_INSERT &&
                  !(tmp != TMP_NO && mode == MODE_UPDATE) &&
                  !(tmp == TMP_FORCE &&
                  (mode == MODE_UPDATE || mode == MODE_DELETE));
    PTXF    txfp;

    /*******************************************************************/
    /*  Allocate a file processing class of the proper type.           */
    /*******************************************************************/
    if (map) {
      // Should be now compatible with UNIX
      txfp = new(g) MAPFAM(this);
    } else if (Compressed) {
#if defined(ZIP_SUPPORT)
      if (Compressed == 1)
        txfp = new(g) ZIPFAM(this);
      else
        txfp = new(g) ZLBFAM(this);

#else   // !ZIP_SUPPORT
        strcpy(g->Message, "Compress not supported");
        return NULL;
#endif  // !ZIP_SUPPORT
    } else
      txfp = new(g) DOSFAM(this);

    /*******************************************************************/
    /*  Allocate a TDB of the proper type.                             */
    /*  Column blocks will be allocated only when needed.              */
    /*******************************************************************/
    if (!Fmtd)
      tdbp = new(g) TDBCSV(this, txfp);
    else
      tdbp = new(g) TDBFMT(this, txfp);

    if (Multiple)
      tdbp = new(g) TDBMUL(tdbp);
    else
      /*****************************************************************/
      /*  For block tables, get eventually saved optimization values.  */
      /*****************************************************************/
      if (tdbp->GetBlockValues(g)) {
        PushWarning(g, tdbp);
//      return NULL;          // causes a crash when deleting index
      } else {
        if (IsOptimized()) {
          if (map) {
            txfp = new(g) MBKFAM(this);
          } else if (Compressed) {
#if defined(ZIP_SUPPORT)
            if (Compressed == 1)
              txfp = new(g) ZBKFAM(this);
            else {
              txfp->SetBlkPos(To_Pos);
              ((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL);
              } // endelse
#else
            sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
            return NULL;
#endif
          } else
            txfp = new(g) BLKFAM(this);

          ((PTDBDOS)tdbp)->SetTxfp(txfp);
          } // endif Optimized

      } // endelse

  } else
    tdbp = new(g)TDBCCL(this);

  return tdbp;
  } // end of GetTable
Example #7
0
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
                  const char *user, const char *pwd,
                  const char *table, const char *colpat,
                  int port, bool info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT,  TYPE_STRING, TYPE_INT,
                   TYPE_STRING, TYPE_SHORT,  TYPE_SHORT,  TYPE_SHORT,
                   TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
                   TYPE_STRING};
  XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,  FLD_TYPENAME, FLD_PREC,
                   FLD_KEY,  FLD_SCALE, FLD_RADIX,    FLD_NULL,
                   FLD_REM,  FLD_NO,    FLD_DEFAULT,  FLD_EXTRA,
                   FLD_CHARSET};
  unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
  char   *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
  int     i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
  int     len, type, prec, rc, k = 0;
  PQRYRES qrp;
  PCOLRES crp;
  MYSQLC  myc;

  if (!port)
    port = mysqld_port;

  if (!info) {
    /********************************************************************/
    /*  Open the connection with the MySQL server.                      */
    /********************************************************************/
    if (myc.Open(g, host, db, user, pwd, port))
      return NULL;

    /********************************************************************/
    /*  Do an evaluation of the result size.                            */
    /********************************************************************/
    STRING cmd(g, 64, "SHOW FULL COLUMNS FROM ");
    bool   b = cmd.Append((PSZ)table);

    b |= cmd.Append(" FROM ");
    b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName));

    if (colpat) {
      b |= cmd.Append(" LIKE ");
      b |= cmd.Append((PSZ)colpat);
      } // endif colpat

    if (b) {
      strcpy(g->Message, "Out of memory");
      return NULL;
      } // endif b

    if (trace)
      htrc("MyColumns: cmd='%s'\n", cmd.GetStr());

    if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) {
      myc.Close();
      return NULL;
      } // endif n

    /********************************************************************/
    /*  Get the size of the name and default columns.                   */
    /********************************************************************/
    length[0] = myc.GetFieldLength(0);
//  length[10] = myc.GetFieldLength(5);
  } else {
    n = 0;
    length[0] = 128;
  } // endif info

  /**********************************************************************/
  /*  Allocate the structures used to refer to the result set.          */
  /**********************************************************************/
  if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
                             buftyp, fldtyp, length, false, true)))
    return NULL;

  // Some columns must be renamed
  for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
    switch (++i) {
      case  2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
      case  4: crp->Name = "Length";    break;
      case  5: crp->Name = "Key";       break;
      case 10: crp->Name = "Date_fmt";  break;
      case 11: crp->Name = "Default";   break;
      case 12: crp->Name = "Extra";     break;
      case 13: crp->Name = "Collation"; break;
      } // endswitch i

  if (info)
    return qrp;

  /**********************************************************************/
  /*  Now get the results into blocks.                                  */
  /**********************************************************************/
  for (i = 0; i < n; /*i++*/) {
    if ((rc = myc.Fetch(g, -1)) == RC_FX) {
      myc.Close();
      return NULL;
    } else if (rc == RC_EF)
      break;

    // Get column name
    colname = myc.GetCharField(0);
    crp = qrp->Colresp;                    // Column_Name
    crp->Kdata->SetValue(colname, i);

    // Get type, type name, precision, unsigned and zerofill
    chset = myc.GetCharField(2);
    fld = myc.GetCharField(1);
    prec = 0;
    len = 0;
    v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
    *uns = 0;
    *zero = 0;

    switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
      case 3:
        nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero);
        break;
      case 2:
        nf = sscanf(fld, "%[^(](%d) %s %s", buf, &len, uns, zero) + 1;
        break;
      case 1:
        nf = sscanf(fld, "%s %s %s", buf, uns, zero) + 2;
        break;
      default:
        sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
        myc.Close();
        return NULL;
      } // endswitch nf

    if ((type = MYSQLtoPLG(buf, &v)) == TYPE_ERROR) {
      if (v == 'K') {
        // Skip this column
        sprintf(g->Message, "Column %s skipped (unsupported type %s)",
                colname, buf);
        PushWarning(g, thd);
        continue;
        } // endif v

      sprintf(g->Message, "Column %s unsupported type %s", colname, buf);
      myc.Close();
      return NULL;
    } else if (type == TYPE_STRING) {
      if (v == 'X') {
        len = GetConvSize();
        sprintf(g->Message, "Column %s converted to varchar(%d)",
                colname, len);
        PushWarning(g, thd);
        v = 'V';
      } else
        len = MY_MIN(len, 4096);

    } // endif type

    qrp->Nblin++;
    crp = crp->Next;                       // Data_Type
    crp->Kdata->SetValue(type, i);

    switch (nf) {
      case 5:  crp->Nulls[i] = 'Z'; break;
      case 4:  crp->Nulls[i] = 'U'; break;
      default: crp->Nulls[i] = v;   break;
      } // endswitch nf

    crp = crp->Next;                       // Type_Name
    crp->Kdata->SetValue(buf, i);

    if (type == TYPE_DATE) {
      // When creating tables we do need info about date columns
      fmt = MyDateFmt(buf);
      len = strlen(fmt);
    } else
      fmt = NULL;

    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len, i);

    crp = crp->Next;                       // key (was Length)
    fld = myc.GetCharField(4);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Scale
    crp->Kdata->SetValue(prec, i);

    crp = crp->Next;                       // Radix
    crp->Kdata->SetValue(0, i);

    crp = crp->Next;                       // Nullable
    fld = myc.GetCharField(3);
    crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i);

    crp = crp->Next;                       // Remark
    fld = myc.GetCharField(8);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Date format
//  crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
    crp->Kdata->SetValue(fmt, i);

    crp = crp->Next;                       // New (default)
    fld = myc.GetCharField(5);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (extra)
    fld = myc.GetCharField(6);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (charset)
    fld = chset;
    crp->Kdata->SetValue(fld, i);

    i++;                                   // Can be skipped
    } // endfor i

#if 0
  if (k > 1) {
    // Multicolumn primary key
    PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;

    for (i = 0; i < n; i++)
      if (vbp->GetIntValue(i))
        vbp->SetValue(k, i);

    } // endif k
#endif // 0

  /**********************************************************************/
  /*  Close MySQL connection.                                           */
  /**********************************************************************/
  myc.Close();

  /**********************************************************************/
  /*  Return the result pointer for use by GetData routines.            */
  /**********************************************************************/
  return qrp;
  } // end of MyColumns
Example #8
0
bool ZIPFAM::OpenTableFile(PGLOBAL g)
  {
  char    opmode[4], filename[_MAX_PATH];
  MODE    mode = Tdbp->GetMode();

  switch (mode) {
    case MODE_READ:
      strcpy(opmode, "r");
      break;
    case MODE_UPDATE:
      /*****************************************************************/
      /* Updating ZIP files not implemented yet.                       */
      /*****************************************************************/
      strcpy(g->Message, MSG(UPD_ZIP_NOT_IMP));
      return true;
    case MODE_DELETE:
      if (!Tdbp->GetNext()) {
        // Store the number of deleted lines
        DelRows = Cardinality(g);

        // This will erase the entire file
        strcpy(opmode, "w");
//      Block = 0;                // For ZBKFAM
//      Last = Nrec;              // For ZBKFAM
        Tdbp->ResetSize();
      } else {
        sprintf(g->Message, MSG(NO_PART_DEL), "ZIP");
        return true;
      } // endif filter

      break;
    case MODE_INSERT:
      strcpy(opmode, "a+");
      break;
    default:
      sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
      return true;
    } // endswitch Mode

  /*********************************************************************/
  /*  Open according to logical input/output mode required.            */
  /*  Use specific zlib functions.                                     */
  /*  Treat files as binary.                                           */
  /*********************************************************************/
  strcat(opmode, "b");
  Zfile = gzopen(PlugSetPath(filename, To_File, Tdbp->GetPath()), opmode);

  if (Zfile == NULL) {
    sprintf(g->Message, MSG(GZOPEN_ERROR),
            opmode, (int)errno, filename);
    strcat(strcat(g->Message, ": "), strerror(errno));
    return (mode == MODE_READ && errno == ENOENT)
            ? PushWarning(g, Tdbp) : true;
    } // endif Zfile

  /*********************************************************************/
  /*  Something to be done here. >>>>>>>> NOT DONE <<<<<<<<            */
  /*********************************************************************/
//To_Fb = dbuserp->Openlist;     // Keep track of File block

  /*********************************************************************/
  /*  Allocate the line buffer.                                        */
  /*********************************************************************/
  return AllocateBuffer(g);
  } // end of OpenTableFile