Пример #1
0
bool TDBPIVOT::FindDefaultColumns(PGLOBAL g)
  {
  PCOLDEF cdp;
  PTABDEF defp = Tdbp->GetDef();

  if (!Fncol) {
    for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
      if (!Picol || stricmp(Picol, cdp->GetName()))
        Fncol = cdp->GetName();
  
    if (!Fncol) {
      strcpy(g->Message, MSG(NO_DEF_FNCCOL));
      return true;
      } // endif Fncol
  
    } // endif Fncol
  
  if (!Picol) {
    // Find default Picol as the last one not equal to Fncol
    for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
      if (stricmp(Fncol, cdp->GetName()))
        Picol = cdp->GetName();
  
    if (!Picol) {
      strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
      return true;
      } // endif Picol
  
    } // endif Picol
  
  return false;
  } // end of FindDefaultColumns
Пример #2
0
PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
  {
  int     i;
  PCOLDEF cdp;
  PCOL    cp, colp = NULL, cprec = NULL;

  if (trace)
    htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n",
          GetAmType(), SVP(name), Name, num);

  for (cdp = To_Def->GetCols(), i = 1; cdp; cdp = cdp->GetNext(), i++)
    if ((!name && !num) ||
         (name && !stricmp(cdp->GetName(), name)) || num == i) {
      /*****************************************************************/
      /*  Check for existence of desired column.                       */
      /*  Also find where to insert the new block.                     */
      /*****************************************************************/
      for (cp = Columns; cp; cp = cp->GetNext())
        if ((num && cp->GetIndex() == i) || 
            (name && !stricmp(cp->GetName(), name)))
          break;             // Found
        else if (cp->GetIndex() < i)
          cprec = cp;

      if (trace)
        htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);

      /*****************************************************************/
      /*  Now take care of Column Description Block.                   */
      /*****************************************************************/
      if (cp)
        colp = cp;
      else if (!(cdp->Flags & U_SPECIAL))
        colp = MakeCol(g, cdp, cprec, i);
      else if (Mode != MODE_INSERT)
        colp = InsertSpcBlk(g, cdp);

      if (trace)
        htrc("colp=%p\n", colp);

      if (name || num)
        break;
      else if (colp && !colp->IsSpecial())
        cprec = colp;

      } // endif Name

  return (colp);
  } // end of ColDB
Пример #3
0
bool TDBASE::IsSpecial(PSZ name)
  {
  for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext())
    if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL))
      return true;   // Special column to ignore while inserting

  return false;    // Not found or not special or not inserting
  }  // end of IsSpecial
Пример #4
0
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
  {
//char *name = cdp->GetName();
  char   *name = cdp->GetFmt();
  PCOLUMN cp;
  PCOL    colp;

  cp= new(g) COLUMN(cdp->GetName());

  if (! To_Table) {
    strcpy(g->Message, "Cannot make special column: To_Table is NULL");
    return NULL;
  } else
    cp->SetTo_Table(To_Table);

  if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") ||
      !stricmp(name, "FPATH")  || !stricmp(name, "FNAME") ||
      !stricmp(name, "FTYPE")  || !stricmp(name, "SERVID")) {
    if (!To_Def || !(To_Def->GetPseudo() & 2)) {
      sprintf(g->Message, MSG(BAD_SPEC_COLUMN));
      return NULL;
      } // endif Pseudo

    if (!stricmp(name, "FILEID"))
      colp = new(g) FIDBLK(cp, OP_XX);
    else if (!stricmp(name, "FDISK"))
      colp = new(g) FIDBLK(cp, OP_FDISK);
    else if (!stricmp(name, "FPATH"))
      colp = new(g) FIDBLK(cp, OP_FPATH);
    else if (!stricmp(name, "FNAME"))
      colp = new(g) FIDBLK(cp, OP_FNAME);
    else if (!stricmp(name, "FTYPE"))
      colp = new(g) FIDBLK(cp, OP_FTYPE);
    else
      colp = new(g) SIDBLK(cp);

  } else if (!stricmp(name, "TABID")) {
    colp = new(g) TIDBLK(cp);
  } else if (!stricmp(name, "PARTID")) {
    colp = new(g) PRTBLK(cp);
//} else if (!stricmp(name, "CONID")) {
//  colp = new(g) CIDBLK(cp);
  } else if (!stricmp(name, "ROWID")) {
    colp = new(g) RIDBLK(cp, false);
  } else if (!stricmp(name, "ROWNUM")) {
      colp = new(g) RIDBLK(cp, true);
  } else {
    sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
    return NULL;
  } // endif's name

  if (!(colp = InsertSpecialColumn(colp))) {
    sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
    return NULL;
    } // endif Insert

  return (colp);
  } // end of InsertSpcBlk
Пример #5
0
PCOL TDBXCL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
  {
  PCOL colp;
  
  if (!stricmp(cdp->GetName(), Xcolumn)) {
		Xcolp = new(g) XCLCOL(g, cdp, this, cprec, n);
    colp = Xcolp;
  } else
    colp = new(g) PRXCOL(cdp, this, cprec, n);

  return colp;
  } // end of MakeCol
Пример #6
0
PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
	{
	PCOL colp = NULL;

	if (!stricmp(cdp->GetName(), Rcolumn)) {
		// Allocate a RANK column
		colp = new(g) RANKCOL(cdp, this, n);
	} else if (!stricmp(cdp->GetName(), Xcolumn)) {
		// Allocate the OCCUR column
		colp = Xcolp = new(g) OCCURCOL(cdp, this, n);
	} else
		return new(g) PRXCOL(cdp, this, cprec, n);

	if (cprec) {
		colp->SetNext(cprec->GetNext());
		cprec->SetNext(colp);
	} else {
		colp->SetNext(Columns);
		Columns = colp;
	} // endif cprec

	return colp;
	} // end of MakeCol
Пример #7
0
bool TDBPIVOT::GetSourceTable(PGLOBAL g)
  {
  if (Tdbp)
    return false;             // Already done

  if (!Tabsrc && Tabname) {
    // Get the table description block of this table
    if (!(Tdbp = GetSubTable(g, ((PPIVOTDEF)To_Def)->Tablep, true)))
      return true;

    if (!GBdone) {
      char   *colist;
      PCOLDEF cdp;

      if (FindDefaultColumns(g))
        return true;
  
      // Locate the suballocated colist (size is not known yet)
      *(colist = (char*)PlugSubAlloc(g, NULL, 0)) = 0;
  
      // Make the column list
      for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext())
        if (!cdp->GetOffset())
          strcat(strcat(colist, cdp->GetName()), ", ");
  
      // Add the Pivot column at the end of the list
      strcat(colist, Picol);
  
      // Now we know how much was suballocated
      PlugSubAlloc(g, NULL, strlen(colist) + 1);
  
      // Locate the source string (size is not known yet)
      Tabsrc = (char*)PlugSubAlloc(g, NULL, 0);
  
      // Start making the definition
      strcat(strcat(strcpy(Tabsrc, "SELECT "), colist), ", ");
  
      // Make it suitable for Pivot by doing the group by
      strcat(strcat(Tabsrc, Function), "(");
      strcat(strcat(strcat(Tabsrc, Fncol), ") "), Fncol);
      strcat(strcat(Tabsrc, " FROM "), Tabname);
      strcat(strcat(Tabsrc, " GROUP BY "), colist);
  
      if (Tdbp->IsView())     // Until MariaDB bug is fixed
        strcat(strcat(Tabsrc, " ORDER BY "), colist);

      // Now we know how much was suballocated
      PlugSubAlloc(g, NULL, strlen(Tabsrc) + 1);
      } // endif !GBdone

  } else if (!Tabsrc) {
    strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
    return true;
  } // endif

  if (Tabsrc) {
    // Get the new table description block of this source table
    PTABLE tablep = new(g) XTAB("whatever", Tabsrc);

    tablep->SetQualifier(Database);

    if (!(Tdbp = GetSubTable(g, tablep, true)))
      return true;

    } // endif Tabsrc

  return false;
  } // end of GetSourceTable
Пример #8
0
bool TDBCSV::SkipHeader(PGLOBAL g)
  {
  int len = GetFileLength(g);
  bool rc = false;

#if defined(_DEBUG)
  if (len < 0)
    return true;
#endif   // _DEBUG

  if (Header) {
    if (Mode == MODE_INSERT) {
      if (!len) {
        // New file, the header line must be constructed and written
        int     i, n = 0;
        int    hlen = 0;
        bool    q = Qot && Quoted > 0;
        PCOLDEF cdp;

        // Estimate the length of the header list
        for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) {
          hlen += (1 + strlen(cdp->GetName()));
          hlen += ((q) ? 2 : 0);
          n++;            // Calculate the number of columns
          } // endfor cdp

        if (hlen > Lrecl) {
          sprintf(g->Message, MSG(LRECL_TOO_SMALL), hlen);
          return true;
          } // endif hlen

        // File is empty, write a header record
        memset(To_Line, 0, Lrecl);

        // The column order in the file is given by the offset value
        for (i = 1; i <= n; i++)
          for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext())
            if (cdp->GetOffset() == i) {
              if (q)
                To_Line[strlen(To_Line)] = Qot;

              strcat(To_Line, cdp->GetName());

              if (q)
                To_Line[strlen(To_Line)] = Qot;

              if (i < n)
                To_Line[strlen(To_Line)] = Sep;

              } // endif Offset

        rc = (Txfp->WriteBuffer(g) == RC_FX);
        } // endif !FileLength

    } else if (Mode == MODE_DELETE) {
      if (len)
        rc = (Txfp->SkipRecord(g, true) == RC_FX);

    } else if (len) // !Insert && !Delete
      rc = (Txfp->SkipRecord(g, false) == RC_FX || Txfp->RecordPos(g));

    } // endif Header

  return rc;
  } // end of SkipHeader
Пример #9
0
bool TDBCSV::OpenDB(PGLOBAL g)
  {
  bool    rc = false;
  PCOLDEF cdp;
  PDOSDEF tdp = (PDOSDEF)To_Def;

  if (Use != USE_OPEN && (Columns || Mode == MODE_UPDATE)) {
    // Allocate the storage used to read (or write) records
    int     i, len;
    PCSVCOL colp;

    if (!Fields)              // May have been set in TABFMT::OpenDB
      if (Mode != MODE_UPDATE && Mode != MODE_INSERT) {
        for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
          if (!colp->IsSpecial() && !colp->IsVirtual())
            Fields = MY_MAX(Fields, (int)colp->Fldnum);

        if (Columns)
          Fields++;           // Fldnum was 0 based

      } else
        for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
          if (!cdp->IsVirtual())
            Fields++;

    Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
    Fldlen = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);

    if (Mode == MODE_INSERT || Mode == MODE_UPDATE) {
      Field = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
      Fldtyp = (bool*)PlugSubAlloc(g, NULL, sizeof(bool) * Fields);
      } // endif Mode

    for (i = 0; i < Fields; i++) {
      Offset[i] = 0;
      Fldlen[i] = 0;

      if (Field) {
        Field[i] = NULL;
        Fldtyp[i] = false;
        } // endif Field

      } // endfor i

    if (Field)
      // Prepare writing fields
      if (Mode != MODE_UPDATE) {
        for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
          if (!colp->IsSpecial() && !colp->IsVirtual()) {
            i = colp->Fldnum;
            len = colp->GetLength();
            Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
            Field[i][len] = '\0';
            Fldlen[i] = len;
            Fldtyp[i] = IsTypeNum(colp->GetResultType());
            } // endif colp

      } else     // MODE_UPDATE
        for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
          if (!cdp->IsVirtual()) {
            i = cdp->GetOffset() - 1;
            len = cdp->GetLength();
            Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
            Field[i][len] = '\0';
            Fldlen[i] = len;
            Fldtyp[i] = IsTypeNum(cdp->GetType());
            } // endif cdp

    } // endif Use

  if (Header) {
    // Check that the Lrecl is at least equal to the header line length
    int     headlen = 0;
    PCOLDEF cdp;
    PDOSDEF tdp = (PDOSDEF)To_Def;

    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      headlen += strlen(cdp->GetName()) + 3;  // 3 if names are quoted

    if (headlen > Lrecl) {
      Lrecl = headlen;
      Txfp->Lrecl = headlen;
      } // endif headlen

    } // endif Header

  Nerr = 0;
  rc = TDBDOS::OpenDB(g);

  if (!rc && Mode == MODE_UPDATE && To_Kindex)
    // Because KINDEX::Init is executed in mode READ, we must restore
    // the Fldlen array that was modified when reading the table file.
    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      Fldlen[cdp->GetOffset() - 1] = cdp->GetLength();

  return rc;
  } // end of OpenDB
Пример #10
0
bool DBFFAM::AllocateBuffer(PGLOBAL g)
  {
  char c;
  int  rc;
  MODE mode = Tdbp->GetMode();

  Buflen = Blksize;
  To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);

  if (mode == MODE_INSERT) {
#if defined(WIN32)
    /************************************************************************/
    /*  Now we can revert to binary mode in particular because the eventual */
    /*  writing of a new header must be done in binary mode to avoid        */
    /*  translating 0A bytes (LF) into 0D0A (CRLF) by Windows in text mode. */
    /************************************************************************/
    if (_setmode(_fileno(Stream), _O_BINARY) == -1) {
      sprintf(g->Message, MSG(BIN_MODE_FAIL), strerror(errno));
      return true;
      } // endif setmode
#endif   // WIN32

    /************************************************************************/
    /*  If this is a new file, the header must be generated.                */
    /************************************************************************/
    int len = GetFileLength(g);

    if (!len) {
      // Make the header for this DBF table file
      struct tm  *datm;
      int         hlen, n = 0;
      ushort      reclen = 1;
      time_t      t;
      DBFHEADER  *header;
      DESCRIPTOR *descp;
      PCOLDEF     cdp;
      PDOSDEF     tdp = (PDOSDEF)Tdbp->GetDef();

      // Count the number of columns
      for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
        if (!(cdp->Flags & U_SPECIAL)) {
          reclen += cdp->GetLong();
          n++;
          } // endif Flags

      if (Lrecl != reclen) {
        sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
        return true;
        } // endif Lrecl

      hlen = HEADLEN * (n + 1) + 2;
      header = (DBFHEADER*)PlugSubAlloc(g, NULL, hlen);
      memset(header, 0, hlen);
      header->Version = DBFTYPE;
      t = time(NULL) - (time_t)DTVAL::GetShift();
      datm = gmtime(&t);
      header->Filedate[0] = datm->tm_year - 100;
      header->Filedate[1] = datm->tm_mon + 1;
      header->Filedate[2] = datm->tm_mday;
      header->Headlen = (ushort)hlen;
      header->Reclen = (ushort)reclen;
      descp = (DESCRIPTOR*)header;

      // Currently only standard Xbase types are supported
      for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
        if (!(cdp->Flags & U_SPECIAL)) {
          descp++;
      
          switch ((c = *GetFormatType(cdp->GetType()))) {
            case 'S':           // Short integer
            case 'L':           // Large (big) integer
            case 'T':           // Tiny integer
              c = 'N';          // Numeric
            case 'N':           // Numeric (integer)
            case 'F':           // Float (double)
              descp->Decimals = (uchar)cdp->F.Prec;
            case 'C':           // Char
            case 'D':           // Date
              break;
            default:            // Should never happen
              sprintf(g->Message, "Unsupported DBF type %c for column %s",
                                  c, cdp->GetName());
              return true;
            } // endswitch c
      
          strncpy(descp->Name, cdp->GetName(), 11);
          descp->Type = c;
          descp->Length = (uchar)cdp->GetLong();
          } // endif Flags

      *(char*)(++descp) = EOH;

      //  Now write the header
      if (fwrite(header, 1, hlen, Stream) != (unsigned)hlen) {
        sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
        return true;
        } // endif fwrite

      Records = 0;
      Headlen = hlen;
    } else if (len < 0)
      return true;            // Error in GetFileLength

    /************************************************************************/
    /*  For Insert the buffer must be prepared.                             */
    /************************************************************************/
    memset(To_Buf, ' ', Buflen);
    Rbuf = Nrec;                     // To be used by WriteDB
  } else if (UseTemp) {
    // Allocate a separate buffer so block reading can be kept
    Dbflen = Nrec;
    DelBuf = PlugSubAlloc(g, NULL, Blksize);
  } // endif's

  if (!Headlen) {
    /************************************************************************/
    /*  Here is a good place to process the DBF file header                 */
    /************************************************************************/
    DBFHEADER header;

    if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) {
      if (Lrecl != (int)header.Reclen) {
        sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen);
        return true;
        } // endif Lrecl

      Records = (int)header.Records;
      Headlen = (int)header.Headlen;
    } else if (rc == RC_NF) {
      Records = 0;
      Headlen = 0;
    } else              // RC_FX
      return true;                  // Error in dbfhead

    } // endif Headlen

  /**************************************************************************/
  /*  Position the file at the begining of the data.                        */
  /**************************************************************************/
  if (Tdbp->GetMode() == MODE_INSERT)
    rc = fseek(Stream, 0, SEEK_END);
  else
    rc = fseek(Stream, Headlen, SEEK_SET);

  if (rc) {
    sprintf(g->Message, MSG(BAD_DBF_FILE), Tdbp->GetFile(g));
    return true;
    } // endif fseek

  return false;
  } // end of AllocateBuffer