Exemple #1
0
bool BLKFAM::AllocateBuffer(PGLOBAL g)
  {
  int  len;
  MODE mode = Tdbp->GetMode();

  // For variable length files, Lrecl does not include CRLF
  len = Lrecl + ((Tdbp->GetFtype()) ? 0 : Ending);
  Buflen = len * Nrec;
  CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);

  if (UseTemp || mode == MODE_DELETE) {
    if (mode == MODE_UPDATE)
      OutBuf = (char*)PlugSubAlloc(g, NULL, len + 1);

    Dbflen = Buflen;
    DelBuf = PlugSubAlloc(g, NULL, Dbflen);
  } else if (mode == MODE_INSERT)
    Rbuf = Nrec;                     // To be used by WriteDB

  return false;
  } // end of AllocateBuffer
Exemple #2
0
char *PRXCOL::Decode(PGLOBAL g, const char *cnm)
  {
  char  *buf= (char*)PlugSubAlloc(g, NULL, strlen(cnm) + 1);
  uint   dummy_errors;
  uint32 len= copy_and_convert(buf, strlen(cnm) + 1,
                               &my_charset_latin1,
                               cnm, strlen(cnm),
                               &my_charset_utf8_general_ci,
                               &dummy_errors);
  buf[len]= '\0';
  return buf;
  } // end of Decode
Exemple #3
0
bool CHRBLK::Init(PGLOBAL g, bool check)
  {
  Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
  Valp[Long] = '\0';

  if (!Blkp)
    if (AllocBuff(g, Nval * Long))
      return true;

  Check = check;
  Global = g;
  return false;
  } // end of Init
char *TDBINI::GetSeclist(PGLOBAL g)
  {
  if (trace)
    htrc("GetSeclist: Seclist=%p\n", Seclist);
    
  if (!Seclist) {
    // Result will be retrieved from the INI file
    Seclist = (char*)PlugSubAlloc(g, NULL, Seclen);
    GetPrivateProfileSectionNames(Seclist, Seclen, Ifile);
    } // endif Seclist

  return Seclist;
  } // end of GetSeclist
Exemple #5
0
char *PlugDup(PGLOBAL g, const char *str)
  {
  char  *buf; 
  size_t len;

  if (str && (len = strlen(str))) {
    buf = (char*)PlugSubAlloc(g, NULL, len + 1);
    strcpy(buf, str);
  } else
    buf = NULL;

  return(buf);
  } /* end of PlugDup */
Exemple #6
0
bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
  {
  Module = Cat->GetStringCatInfo(g, "Module", "");
  Subtype = Cat->GetStringCatInfo(g, "Subtype", Module);

  if (!*Module)
    Module = Subtype;

  Desc = (char*)PlugSubAlloc(g, NULL, strlen(Module)
                                    + strlen(Subtype) + 3);
  sprintf(Desc, "%s(%s)", Module, Subtype);
  return false;
  } // end of DefineAM
Exemple #7
0
void STRBLK::SetValue(PSZ p, int n)
  {
  if (p) {
    if (!Sorted || !n || !Strp[n-1] || strcmp(p, Strp[n-1])) {
      Strp[n] = (PSZ)PlugSubAlloc(Global, NULL, strlen(p) + 1);
      strcpy(Strp[n], p);
    } else
      Strp[n] = Strp[n-1];

  } else
    Strp[n] = NULL;

  } // end of SetValue
Exemple #8
0
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i)
{
  if (args->args[i]) {
    int n = args->lengths[i];
    PSZ s = (PSZ)PlugSubAlloc(g, NULL, n + 1);

    memcpy(s, args->args[i], n);
    s[n] = 0;
    return s;
  } else
    return NULL;

} // end of MakePSZ
Exemple #9
0
char *PlugReadMessage(PGLOBAL g, int mid, char *m) 
  {
  char  msgfile[_MAX_PATH], msgid[32], buff[256];
  char *msg;
  FILE *mfile = NULL;

  GetPrivateProfileString("Message", msglang, "Message\\english.msg", 
                                     msgfile, _MAX_PATH, plgini);

  if (!(mfile = fopen(msgfile, "rt"))) {
    sprintf(stmsg, "Fail to open message file %s for %s", msgfile, msglang);
    goto err;
    } // endif mfile

  for (;;)
    if (!fgets(buff, 256, mfile)) {
      sprintf(stmsg, "Cannot get message %d %s", mid, SVP(m));
      goto fin;
    } else
      if (atoi(buff) == mid)
        break;

  if (sscanf(buff, " %*d %s \"%[^\"]", msgid, stmsg) < 2) {
    // Old message file
    if (!sscanf(buff, " %*d \"%[^\"]", stmsg)) {
      sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m));
      goto fin;
    } else
      m = NULL;

    } // endif sscanf

  if (m && strcmp(m, msgid)) {
    // Message file is out of date
    strcpy(stmsg, m);
    goto fin;
    } // endif m

 fin:
  fclose(mfile);

 err:
  if (g) {
    // Called by STEP
    msg = (char *)PlugSubAlloc(g, NULL, strlen(stmsg) + 1);
    strcpy(msg, stmsg);
  } else // Called by MSG or PlgGetErrorMsg
    msg =  stmsg;

  return msg;
  } // end of PlugReadMessage
Exemple #10
0
PSZ ARRAY::MakeArrayList(PGLOBAL g)
  {
  char   *p, *tp;
  int    i;
  size_t  z, len = 2;

  if (Type == TYPE_LIST)
    return "(?" "?" "?)";             // To be implemented

  z = MY_MAX(24, GetTypeSize(Type, Len) + 4);
  tp = (char*)PlugSubAlloc(g, NULL, z);

  for (i = 0; i < Nval; i++) {
    Value->SetValue_pvblk(Vblp, i);
    Value->Print(g, tp, z);
    len += strlen(tp);
    } // enfor i

  if (trace)
    htrc("Arraylist: len=%d\n", len);

  p = (char *)PlugSubAlloc(g, NULL, len);
  strcpy(p, "(");

  for (i = 0; i < Nval;) {
    Value->SetValue_pvblk(Vblp, i);
    Value->Print(g, tp, z);
    strcat(p, tp);
    strcat(p, (++i == Nval) ? ")" : ",");
    } // enfor i

  if (trace)
    htrc("Arraylist: newlen=%d\n", strlen(p));

  return p;
  } // end of MakeArrayList
Exemple #11
0
void STRBLK::SetValue(char *sp, uint len, int n)
  {
  PSZ p;

  if (sp) {
    if (!Sorted || !n || !Strp[n-1] || strlen(Strp[n-1]) != len ||
                                       strncmp(sp, Strp[n-1], len)) {
      p = (PSZ)PlugSubAlloc(Global, NULL, len + 1);
      memcpy(p, sp, len);
      p[len] = 0;
    } else
      p = Strp[n-1];

  } else
    p = NULL;

  Strp[n] = p;
  } // end of SetValue
Exemple #12
0
void TDBWMI::DoubleSlash(PGLOBAL g)
  {
  if (To_CondFil && strchr(To_CondFil->Body, '\\')) {
    char *body = To_CondFil->Body;
    char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2);
    int   i = 0, k = 0;

    do {
      if (body[i] == '\\')
        buf[k++] = '\\';

      buf[k++] = body[i];
      } while (body[i++]);

    To_CondFil->Body = buf;
    } // endif To_CondFil

  } // end of DoubleSlash
Exemple #13
0
bool ZBKFAM::AllocateBuffer(PGLOBAL g)
  {
  Buflen = Nrec * (Lrecl + 2);
  CurLine = To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);

  if (Tdbp->GetMode() == MODE_INSERT) {
    // Set values so Block and Last can be recalculated
    if (Last == Nrec) {
      CurBlk = Block;
      Rbuf = Nrec;                   // To be used by WriteDB
    } else {
      // The last block must be completed
      CurBlk = Block - 1;
      Rbuf = Nrec - Last;            // To be used by WriteDB
    } // endif Last

    } // endif Insert

  return false;
  } // end of AllocateBuffer
Exemple #14
0
bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
  {
  Nspace = GetStringCatInfo(g, "Namespace", "Root\\CimV2");
  Wclass = GetStringCatInfo(g, "Class",
          (!stricmp(Nspace, "root\\cimv2") ? "ComputerSystemProduct" : 
           !stricmp(Nspace, "root\\cli")   ? "Msft_CliAlias" : ""));

  if (!*Wclass) {
    sprintf(g->Message, "Missing class name for %s", Nspace);
    return true;
  } else if (!strchr(Wclass, '_')) {
    char *p = (char*)PlugSubAlloc(g, NULL, strlen(Wclass) + 7);
    Wclass = strcat(strcpy(p, "Win32_"), Wclass);
  } // endif Wclass

  if (Catfunc == FNC_NO)
    Ems = GetIntCatInfo("Estimate", 100);

  return false;
  } // end of DefineAM
Exemple #15
0
bool TDBTBM::OpenTables(PGLOBAL g)
  {
  int    k;
  THD   *thd = current_thd;
  PTABLE tabp, *ptabp = &Tablist;
  PTBMT  tp, *ptp = &Tmp;

  // Allocates the TBMT blocks for the tables
  for (tabp = Tablist; tabp; tabp = tabp->Next)
    if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL) {
      // Remove remote table from the local list
      *ptabp = tabp->Next;

      // Make the remote table block
      tp = (PTBMT)PlugSubAlloc(g, NULL, sizeof(TBMT));
      memset(tp, 0, sizeof(TBMT));
      tp->G = g;
      tp->Tap = tabp;
      tp->Thd = thd;

      // Create the thread that will do the table opening.
      pthread_attr_init(&tp->attr);
//    pthread_attr_setdetachstate(&tp->attr, PTHREAD_CREATE_JOINABLE);

      if ((k = pthread_create(&tp->Tid, &tp->attr, ThreadOpen, tp))) {
        sprintf(g->Message, "pthread_create error %d", k);
        Nbc++;
        continue;
        } // endif k

      // Add it to the remote list
      *ptp = tp;
      ptp = &tp->Next;
      Nrc++;         // Number of remote connections
    } else {
      ptabp = &tabp->Next;
      Nlc++;         // Number of local connections
    } // endif Type

  return false;
  } // end of OpenTables
bool INIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
  {
  char   buf[8];

  Fn = GetStringCatInfo(g, "Filename", NULL);
  GetCharCatInfo("Layout", "C", buf, sizeof(buf));
  Layout = toupper(*buf);

  if (Fn) {
    char   *p = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);

    PlugSetPath(p, Fn, GetPath());
    Fn = p;
  } else {
    strcpy(g->Message, MSG(MISSING_FNAME));
    return true;
  } // endif Fn

  Ln = GetSizeCatInfo("Secsize", "8K");
  Desc = Fn;
  return false;
  } // end of DefineAM
Exemple #17
0
bool ZIPFAM::AllocateBuffer(PGLOBAL g)
  {
  MODE mode = Tdbp->GetMode();

  Buflen = Lrecl + 2;                     // Lrecl does not include CRLF
//Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1);    NIY

  if (trace)
    htrc("SubAllocating a buffer of %d bytes\n", Buflen);

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

  if (mode == MODE_INSERT) {
    /*******************************************************************/
    /*  For Insert buffer must be prepared.                            */
    /*******************************************************************/
    memset(To_Buf, ' ', Buflen);
    To_Buf[Buflen - 2] = '\n';
    To_Buf[Buflen - 1] = '\0';
    } // endif Insert

  return false;
  } // end of AllocateBuffer
Exemple #18
0
bool TDBOCCUR::ViewColumnList(PGLOBAL g)
	{
	char *pn;
	int   i;
  PCOL  colp, cp;
  PTDBMY tdbp;

  if (!Tdbp->IsView())
    return false;

  if (Tdbp->GetAmType() != TYPE_AM_MYSQL) {
    strcpy(g->Message, "View is not MySQL");
    return true;
  } else
    tdbp = (PTDBMY)Tdbp;

  for (cp = Columns; cp; cp = cp->GetNext())
    if (cp->GetAmType() == TYPE_AM_PRX) {
      if ((colp = tdbp->MakeFieldColumn(g, cp->GetName()))) {
        ((PPRXCOL)cp)->Colp = colp;        
        ((PPRXCOL)cp)->To_Val = colp->GetValue();
      } else
  			return true;

      } // endif Type

	Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL));

	for (i = 0, pn = Colist; i < Mult; i++, pn += (strlen(pn) + 1))
		if (!(Col[i] = tdbp->MakeFieldColumn(g, pn))) {
		  // Column not found in table                                       
		  sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname);
			return true;
			} // endif Col

	return false;
	} // end of ViewColumnList
Exemple #19
0
bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am)
  {
  int   poff = 0;

  Name = (PSZ)PlugSubAlloc(g, NULL, strlen(name) + 1);
  strcpy(Name, name);
  Cat = cat;
  Catfunc = GetFuncID(Cat->GetStringCatInfo(g, "Catfunc", NULL));
  Elemt = cat->GetIntCatInfo("Elements", 0);
  Multiple = cat->GetIntCatInfo("Multiple", 0);
  Degree = cat->GetIntCatInfo("Degree", 0);
  Read_Only = cat->GetBoolCatInfo("ReadOnly", false);
  const char *data_charset_name= cat->GetStringCatInfo(g, "Data_charset", NULL);
  m_data_charset= data_charset_name ?
                  get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, 0):
                  NULL;

  // Get The column definitions
  if ((poff = cat->GetColCatInfo(g, this)) < 0)
    return true;

  // Do the definition of AM specific fields
  return DefineAM(g, am, poff);
  } // end of Define
Exemple #20
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
Exemple #21
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
Exemple #22
0
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
  {
  char    *p, *query, *colname, *skc, buf[64];
  int      rc, ndif, nblin, w = 0;
  bool     b = false;
  PVAL     valp;   
  PQRYRES  qrp;
  PCOLRES *pcrp, crp, fncrp = NULL;

  // Save stack and allocation environment and prepare error return
  if (g->jump_level == MAX_JUMP) {
    strcpy(g->Message, MSG(TOO_MANY_JUMPS));
    return NULL;
    } // endif jump_level

  if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
    goto err;
    } // endif rc

  // Are there columns to skip?
  if (Skcol) {
    uint n = strlen(Skcol);

    skc = (char*)PlugSubAlloc(g, NULL, n + 2);
    strcpy(skc, Skcol);
    skc[n + 1] = 0;

    // Replace ; by nulls in skc
    for (p = strchr(skc, ';'); p; p = strchr(p, ';'))
      *p++ = 0;

  } else
    skc = NULL;

  if (!Tabsrc && Tabname) {
    // Locate the  query
    query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26);
    sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname);
  } else if (!Tabsrc) {
    strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
    return NULL;
  } else
    query = Tabsrc;

  // Open a MySQL connection for this table
  if (Myc.Open(g, Host, Database, User, Pwd, Port))
    return NULL;
  else
    b = true;

  // Send the source command to MySQL
  if (Myc.ExecSQL(g, query, &w) == RC_FX)
    goto err;

  // We must have a storage query to get pivot column values
  if (!(Qryp = Myc.GetResult(g, true)))
    goto err;

  if (!Fncol) {
    for (crp = Qryp->Colresp; crp; crp = crp->Next)
      if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc))
        Fncol = crp->Name;
  
    if (!Fncol) {
      strcpy(g->Message, MSG(NO_DEF_FNCCOL));
      goto err;
      } // endif Fncol
  
    } // endif Fncol
  
  if (!Picol) {
    // Find default Picol as the last one not equal to Fncol
    for (crp = Qryp->Colresp; crp; crp = crp->Next)
      if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc))
        Picol = crp->Name;
  
    if (!Picol) {
      strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
      goto err;
      } // endif Picol
  
    } // endif picol
  
  // Prepare the column list
  for (pcrp = &Qryp->Colresp; crp = *pcrp; )
    if (SkipColumn(crp, skc)) {
      // Ignore this column
      *pcrp = crp->Next;
    } else if (!stricmp(Picol, crp->Name)) {
      if (crp->Nulls) {
        sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
        goto err;
        } // endif Nulls

      Rblkp = crp->Kdata;
      *pcrp = crp->Next;
    } else if (!stricmp(Fncol, crp->Name)) {
      fncrp = crp;
      *pcrp = crp->Next;
    } else
      pcrp = &crp->Next;

  if (!Rblkp) {
    strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
    goto err;
  } else if (!fncrp) {
    strcpy(g->Message, MSG(NO_DEF_FNCCOL));
    goto err;
  } // endif

  if (Tabsrc) {
    Myc.Close();
    b = false;

    // Before calling sort, initialize all
    nblin = Qryp->Nblin;

    Index.Size = nblin * sizeof(int);
    Index.Sub = TRUE;                  // Should be small enough

    if (!PlgDBalloc(g, NULL, Index))
      return NULL;

    Offset.Size = (nblin + 1) * sizeof(int);
    Offset.Sub = TRUE;                 // Should be small enough

    if (!PlgDBalloc(g, NULL, Offset))
      return NULL;

    ndif = Qsort(g, nblin);

    if (ndif < 0)           // error
      return NULL;

  } else {
    // The query was limited, we must get pivot column values
    query = (char*)PlugSubAlloc(g, NULL, 0);
    sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname);
    PlugSubAlloc(g, NULL, strlen(query) + 1);
    Myc.FreeResult();

    // Send the source command to MySQL
    if (Myc.ExecSQL(g, query, &w) == RC_FX)
      goto err;

    // We must have a storage query to get pivot column values
    if (!(qrp = Myc.GetResult(g, true)))
      goto err;

    Myc.Close();
    b = false;

    // Get the column list
    crp = qrp->Colresp;
    Rblkp = crp->Kdata;
    ndif = qrp->Nblin;
  } // endif Tabsrc

  // Allocate the Value used to retieve column names
  if (!(valp = AllocateValue(g, Rblkp->GetType(),
                                Rblkp->GetVlen(),
                                Rblkp->GetPrec())))
    return NULL;

  // Now make the functional columns
  for (int i = 0; i < ndif; i++) {
    if (i) {
      crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
      memcpy(crp, fncrp, sizeof(COLRES));
    } else
      crp = fncrp;

    // Get the value that will be the generated column name
    if (Tabsrc)
      valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
    else
      valp->SetValue_pvblk(Rblkp, i);

    colname = valp->GetCharString(buf);
    crp->Name = (char*)PlugSubAlloc(g, NULL, strlen(colname) + 1);
    strcpy(crp->Name, colname);
    crp->Flag = 1;

    // Add this column
    *pcrp = crp;
    crp->Next = NULL;
    pcrp = &crp->Next;
    } // endfor i

  // We added ndif columns and removed 2 (picol and fncol)
  Qryp->Nbcol += (ndif - 2);
  return Qryp;

err:
  if (b)
    Myc.Close();

  return NULL;
  } // end of MakePivotColumns
Exemple #23
0
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, 
                                        const char *name, bool& info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT,  TYPE_STRING, TYPE_INT,
                   TYPE_INT,    TYPE_SHORT,  TYPE_SHORT,  TYPE_SHORT,
                   TYPE_STRING, TYPE_STRING, TYPE_STRING};
  XFLD fldtyp[] = {FLD_NAME,   FLD_TYPE,  FLD_TYPENAME, FLD_PREC,
                   FLD_LENGTH, FLD_SCALE, FLD_RADIX,    FLD_NULL,
                   FLD_REM,    FLD_NO,    FLD_CHARSET};
  unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
  char        *fld, *colname, *chset, *fmt, v;
  int          i, n, ncol = sizeof(buftyp) / sizeof(int);
  int          prec, len, type, scale;
  int          zconv = GetConvSize();
  bool         mysql;
  TABLE_SHARE *s = NULL;
  Field*      *field;
  Field       *fp;
  PQRYRES      qrp;
  PCOLRES      crp;

  if (!info) {
    if (!(s = GetTableShare(g, thd, db, name, mysql))) {
      return NULL;
    } else if (s->is_view) {
      strcpy(g->Message, "Use MYSQL type to see columns from a view");
      info = true;       // To tell caller name is a view
      free_table_share(s);
      return NULL;
    } else
      n = s->fieldnames.count;

  } 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 10: crp->Name = "Date_fmt";  break;
      case 11: crp->Name = "Collation"; break;
      } // endswitch i

  if (info)
    return qrp;

  /**********************************************************************/
  /*  Now get the results into blocks.                                  */
  /**********************************************************************/
  for (i = 0, field= s->field; *field; field++) {
    fp= *field;

    // Get column name
    crp = qrp->Colresp;                    // Column_Name
    colname = (char *)fp->field_name;
    crp->Kdata->SetValue(colname, i);

    chset = (char *)fp->charset()->name;
    v = (!strcmp(chset, "binary")) ? 'B' : 0;

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

      sprintf(g->Message, "Column %s unsupported type", colname);
      qrp = NULL;
      break;
      } // endif type

      if (v == 'X') {
        len = zconv;
        sprintf(g->Message, "Column %s converted to varchar(%d)",
                colname, len);
        push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
        } // endif v

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

    if (fp->flags & ZEROFILL_FLAG)
      crp->Nulls[i] = 'Z';
    else if (fp->flags & UNSIGNED_FLAG)
      crp->Nulls[i] = 'U';
    else                  // X means TEXT field
      crp->Nulls[i] = (v == 'X') ? 'V' : v;

    crp = crp->Next;                       // Type_Name
    crp->Kdata->SetValue(GetTypeName(type), i);
    fmt = NULL;

    if (type == TYPE_DATE) {
      // When creating tables we do need info about date columns
      if (mysql) {
        fmt = MyDateFmt(fp->type());
        prec = len = strlen(fmt);
      } else {
        fmt = (char*)fp->option_struct->dateformat;
        prec = len = fp->field_length;
      } // endif mysql

    } else if (v != 'X') {
      if (type == TYPE_DECIM)
        prec = ((Field_new_decimal*)fp)->precision;
      else
        prec = fp->field_length;
//      prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length;

      len = fp->char_length();
    } else
      prec = len = zconv;

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

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

    crp = crp->Next;                       // Scale
    scale = (type == TYPE_DOUBLE || type == TYPE_DECIM) ? fp->decimals()
                                                        : 0;
    crp->Kdata->SetValue(scale, i);

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

    crp = crp->Next;                       // Nullable
    crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i);

    crp = crp->Next;                       // Remark

    // For Valgrind
    if (fp->comment.length > 0 && (fld = fp->comment.str))
      crp->Kdata->SetValue(fld, fp->comment.length, i);
    else
      crp->Kdata->Reset(i);

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

    crp = crp->Next;                       // New (charset)
    fld = (char *)fp->charset()->name;
    crp->Kdata->SetValue(fld, i);

    // Add this item
    qrp->Nblin++;
    i++;                                   // Can be skipped
    } // endfor field

  /**********************************************************************/
  /*  Return the result pointer for use by GetData routines.            */
  /**********************************************************************/
  if (s)
	  free_table_share(s);
	  
  return qrp;
  } // end of TabColumns
Exemple #24
0
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, 
                       const char *ocr, const char *rank)
  {
  char   *pn, *colist;
  int     i, k, m, n = 0, c = 0;
  bool    rk, b = false;
  PCOLRES crp, rcrp, *pcrp;

  if (!col || !*col) {
    strcpy(g->Message, "Missing colist");
    return true;
    } // endif col

  // Prepare the column list
  colist = PlugDup(g, col);
  m = PrepareColist(colist);

  if ((rk = (rank && *rank)))
    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      n = MY_MAX(n, (signed)strlen(pn));
             
  // Default occur column name is the 1st colist column name
  if (!ocr || !*ocr)
    ocr = colist;

  /**********************************************************************/
  /*  Replace the columns of the colist by the rank and occur columns.  */
  /**********************************************************************/
  for (i = 0, pcrp = &qrp->Colresp; crp = *pcrp; ) {
    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      if (!stricmp(pn, crp->Name))
        break;

    if (k < m) {
      // This column belongs to colist
      c++;

      if (!b) {
        if (rk) {
          // Add the rank column here
          rcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
          memset(rcrp, 0, sizeof(COLRES));
          rcrp->Next = crp;
          rcrp->Name = (char*)rank;
          rcrp->Type = TYPE_STRING;
          rcrp->Length = n;
          rcrp->Ncol = ++i;
          *pcrp = rcrp;
        } // endif rk

        // First remaining listed column, will be the occur column
        crp->Name = (char*)ocr;
        b = true;
      } else {
        *pcrp = crp->Next;     // Remove this column
        continue;
      } // endif b

      } // endif k

    crp->Ncol = ++i;
    pcrp = &crp->Next;
    } // endfor pcrp

  // Check whether all columns of the list where found
  if (c < m) {
    strcpy(g->Message, "Some colist columns are not in the source table");
    return true;
    } // endif crp

  /**********************************************************************/
  /*  Set the number of columns of the table.                           */
  /**********************************************************************/
  qrp->Nblin = i;
  return false;
  } // end of OcrSrcCols
Exemple #25
0
PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
{
  IWbemLocator *loc;
  char         *p;
  HRESULT       res;
  PWMIUT        wp = (PWMIUT)PlugSubAlloc(g, NULL, sizeof(WMIUTIL));

  if (trace)
    htrc("WMIColumns class %s space %s\n", SVP(classname), SVP(nsp));

  /*********************************************************************/
  /*  Set default values for the namespace and class name.             */
  /*********************************************************************/
  if (!nsp)
    nsp = "root\\cimv2";

  if (!classname) {
    if (!stricmp(nsp, "root\\cimv2"))
      classname = "ComputerSystemProduct";
    else if (!stricmp(nsp, "root\\cli"))
      classname = "Msft_CliAlias";
    else {
      strcpy(g->Message, "Missing class name");
      return NULL;
      } // endif classname

    } // endif classname

  /*********************************************************************/
  /*  Initialize WMI.                                                  */
  /*********************************************************************/
//res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

  if (FAILED(res)) {
    sprintf(g->Message, "Failed to initialize COM library. " 
            "Error code = %p", res);
    return NULL;
    } // endif res

#if 0 // irrelevant for a DLL
  res = CoInitializeSecurity(NULL, -1, NULL, NULL,
                       RPC_C_AUTHN_LEVEL_CONNECT,
                       RPC_C_IMP_LEVEL_IMPERSONATE,
                       NULL, EOAC_NONE, NULL);
  
  if (res != RPC_E_TOO_LATE && FAILED(res)) {
    sprintf(g->Message, "Failed to initialize security. " 
            "Error code = %p", res);
    CoUninitialize();
    return NULL;
    }  // endif Res
#endif // 0

  res = CoCreateInstance(CLSID_WbemLocator, NULL, 
                         CLSCTX_INPROC_SERVER, IID_IWbemLocator, 
                         (void**) &loc);
  if (FAILED(res)) {
    sprintf(g->Message, "Failed to create Locator. " 
            "Error code = %p", res);
    CoUninitialize();
    return NULL;
    }  // endif res
    
  res = loc->ConnectServer(_bstr_t(nsp), 
                    NULL, NULL, NULL, 0, NULL, NULL, &wp->Svc);

  if (FAILED(res)) {
    sprintf(g->Message, "Could not connect. Error code = %p", res); 
    loc->Release();     
    CoUninitialize();
    return NULL;
    }  // endif res

  loc->Release();

  if (trace)
    htrc("Successfully connected to namespace.\n");

  /*********************************************************************/
  /*  Perform a full class object retrieval.                           */
  /*********************************************************************/
  p = (char*)PlugSubAlloc(g, NULL, strlen(classname) + 7);

  if (strchr(classname, '_'))
    strcpy(p, classname);
  else
    strcat(strcpy(p, "Win32_"), classname);

  res = wp->Svc->GetObject(bstr_t(p), 0, 0, &wp->Cobj, 0);

  if (FAILED(res)) {
    sprintf(g->Message, "failed GetObject %s in %s\n", classname, nsp);
    wp->Svc->Release();
    wp->Svc = NULL;    // MUST be set to NULL  (why?)
    return NULL;
    }  // endif res

  return wp;
} // end of InitWMI
void INICOL::AllocBuf(PGLOBAL g)
  {
  if (!Valbuf)
    Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);

  } // end of AllocBuf
Exemple #27
0
MULAR::MULAR(PGLOBAL g, int n) : CSORT(FALSE)
  {
  Narray = n;
  Pars = (PARRAY*)PlugSubAlloc(g, NULL, n * sizeof(PARRAY));
  } // end of MULAR constructor
Exemple #28
0
bool TDBFMT::OpenDB(PGLOBAL g)
  {
  Linenum = 0;

  if (Mode == MODE_INSERT || Mode == MODE_UPDATE) {
    sprintf(g->Message, MSG(FMT_WRITE_NIY), "FMT");
    return true;                    // NIY
    } // endif Mode

  if (Use != USE_OPEN && Columns) {
    // Make the formats used to read records
    PSZ     pfm;
    int     i, n;
    PCSVCOL colp;
    PCOLDEF cdp;
    PDOSDEF tdp = (PDOSDEF)To_Def;

    for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
      if (!colp->IsSpecial() && !colp->IsVirtual())  // a true column
        Fields = MY_MAX(Fields, (int)colp->Fldnum);

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

    To_Fld = PlugSubAlloc(g, NULL, Lrecl + 1);
    FldFormat = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
    memset(FldFormat, 0, sizeof(PSZ) * Fields);
    FmtTest = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
    memset(FmtTest, 0, sizeof(int) * Fields);

    // Get the column formats
    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      if (!cdp->IsVirtual() && (i = cdp->GetOffset() - 1) < Fields) {
        if (!(pfm = cdp->GetFmt())) {
          sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name);
          return true;
          } // endif pfm

        // Roughly check the Fmt format
        if ((n = strlen(pfm) - 2) < 4) {
          sprintf(g->Message, MSG(BAD_FLD_FORMAT), i + 1, Name);
          return true;
          } // endif n

        FldFormat[i] = (PSZ)PlugSubAlloc(g, NULL, n + 5);
        strcpy(FldFormat[i], pfm);

        if (!strcmp(pfm + n, "%m")) {
          // This is a field that can be missing. Flag it so it can
          // be handled with special processing.
          FldFormat[i][n+1] = 'n';  // To have sscanf normal processing
          FmtTest[i] = 2;
        } else if (i+1 < Fields && strcmp(pfm + n, "%n")) {
          // There are trailing characters after the field contents
          // add a marker for the next field start position.
          strcat(FldFormat[i], "%n");
          FmtTest[i] = 1;
        } // endif's

        } // endif i

    } // endif Use

  return TDBCSV::OpenDB(g);
  } // end of OpenDB
Exemple #29
0
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
                   int hdr, int mxr, bool info)
  {
  static int  buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
                          TYPE_INT,   TYPE_INT, TYPE_SHORT};
  static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,   FLD_TYPENAME,
                          FLD_PREC, FLD_LENGTH, FLD_SCALE};
  static unsigned int length[] = {6, 6, 8, 10, 10, 6};
  char   *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
  int     i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
  int     ncol = sizeof(buftyp) / sizeof(int);
  int     num_read = 0, num_max = 10000000;     // Statistics
  int     len[MAXCOL], typ[MAXCOL], prc[MAXCOL];
  FILE   *infile;
  PQRYRES qrp;
  PCOLRES crp;

  if (info) {
    imax = hmax = 0;
    length[0] = 128;
    goto skipit;
    } // endif info

//      num_max = atoi(p+1);             // Max num of record to test
#if defined(WIN32)
  if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
    dechar = '.';
  else
    dechar = ',';
#else   // !WIN32
  dechar = '.';
#endif  // !WIN32

  if (trace)
    htrc("File %s sep=%c q=%c hdr=%d mxr=%d\n",
          SVP(fn), sep, q, hdr, mxr);

  if (!fn) {
    strcpy(g->Message, MSG(MISSING_FNAME));
    return NULL;
    } // endif fn

  imax = hmax = nerr = 0;
  mxr = MY_MAX(0, mxr);

  for (i = 0; i < MAXCOL; i++) {
    colname[i] = NULL;
    len[i] = 0;
    typ[i] = TYPE_UNKNOWN;
    prc[i] = 0;
    } // endfor i

  /*********************************************************************/
  /*  Open the input file.                                             */
  /*********************************************************************/
  PlugSetPath(filename, fn, PlgGetDataPath(g));

  if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r")))
    return NULL;

  if (hdr) {
    /*******************************************************************/
    /*  Make the column names from the first line.                     */
    /*******************************************************************/
    phase = 0;

    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf) + 1;
      buf[n - 2] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 3] == '\r')
        buf[n - 3] = 0;
#endif   // UNIX
      p = (char*)PlugSubAlloc(g, NULL, n);
      memcpy(p, buf, n);

      //skip leading blanks
      for (; *p == ' '; p++) ;

      if (q && *p == q) {
        // Header is quoted
        p++;
        phase = 1;
        } // endif q

      colname[0] = p;
    } else {
      sprintf(g->Message, MSG(FILE_IS_EMPTY), fn);
      goto err;
    } // endif's

    for (i = 1; *p; p++)
      if (phase == 1 && *p == q) {
        *p = '\0';
        phase = 0;
      } else if (*p == sep && !phase) {
        *p = '\0';

        //skip leading blanks
        for (; *(p+1) == ' '; p++) ;

        if (q && *(p+1) == q) {
          // Header is quoted
          p++;
          phase = 1;
          } // endif q

        colname[i++] = p + 1;
        } // endif sep

    num_read++;
    imax = hmax = i;

    for (i = 0; i < hmax; i++)
      length[0] = MY_MAX(length[0], strlen(colname[i]));

    } // endif hdr

  for (num_read++; num_read <= num_max; num_read++) {
    /*******************************************************************/
    /*  Now start the reading process. Read one line.                  */
    /*******************************************************************/
    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf);
      buf[n - 1] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 2] == '\r')
        buf[n - 2] = 0;
#endif   // UNIX
    } else if (feof(infile)) {
      sprintf(g->Message, MSG(EOF_AFTER_LINE), num_read -1);
      break;
    } else {
      sprintf(g->Message, MSG(ERR_READING_REC), num_read, fn);
      goto err;
    } // endif's

    /*******************************************************************/
    /*  Make the test for field lengths.                               */
    /*******************************************************************/
    i = n = phase = blank = digit = dec = 0;

    for (p = buf; *p; p++)
      if (*p == sep) {
        if (phase != 1) {
          if (i == MAXCOL - 1) {
            sprintf(g->Message, MSG(TOO_MANY_FIELDS), num_read, fn);
            goto err;
            } // endif i

          if (n) {
            len[i] = MY_MAX(len[i], n);
            type = (digit || (dec && n == 1)) ? TYPE_STRING
                 : (dec) ? TYPE_DOUBLE : TYPE_INT;
            typ[i] = MY_MIN(type, typ[i]);
            prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
            } // endif n

          i++;
          n = phase = blank = digit = dec = 0;
        } else          // phase == 1
          n++;

      } else if (*p == ' ') {
        if (phase < 2)
          n++;

        if (blank)
          digit = 1;

      } else if (*p == q) {
        if (phase == 0) {
          if (blank)
            if (++nerr > mxr) {
              sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
              goto err;
            } else
              goto skip;

          n = 0;
          phase = digit = 1;
        } else if (phase == 1) {
          if (*(p+1) == q) {
            // This is currently not implemented for CSV tables
//          if (++nerr > mxr) {
//            sprintf(g->Message, MSG(QUOTE_IN_QUOTE), num_read);
//            goto err;
//          } else
//            goto skip;

            p++;
            n++;
          } else
            phase = 2;

        } else if (++nerr > mxr) {      // phase == 2
          sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
          goto err;
        } else
          goto skip;

      } else {
        if (phase == 2)
          if (++nerr > mxr) {
            sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
            goto err;
          } else
            goto skip;

        // isdigit cannot be used here because of debug assert
        if (!strchr("0123456789", *p)) {
          if (!digit && *p == dechar)
            dec = 1;                    // Decimal point found
          else if (blank || !(*p == '-' || *p == '+'))
            digit = 1;

        } else if (dec)
          dec++;                        // More decimals

        n++;
        blank = 1;
      } // endif's *p

    if (phase == 1)
      if (++nerr > mxr) {
        sprintf(g->Message, MSG(UNBALANCE_QUOTE), num_read);
        goto err;
      } else
        goto skip;

    if (n) {
      len[i] = MY_MAX(len[i], n);
      type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
           : (dec) ? TYPE_DOUBLE : TYPE_INT;
      typ[i] = MY_MIN(type, typ[i]);
      prc[i]  = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
      } // endif n

    imax = MY_MAX(imax, i+1);
   skip: ;                  // Skip erroneous line
    } // endfor num_read

  if (trace) {
    htrc("imax=%d Lengths:", imax);

    for (i = 0; i < imax; i++)
      htrc(" %d", len[i]);

    htrc("\n");
  } // endif trace

  fclose(infile);

 skipit:
  if (trace)
    htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
                      imax, hmax, length[0]);

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

  qrp->Nblin = imax;

  /*********************************************************************/
  /*  Now get the results into blocks.                                 */
  /*********************************************************************/
  for (i = 0; i < imax; i++) {
    if (i >= hmax) {
      sprintf(buf, "COL%.3d", i+1);
      p = buf;
    } else
      p = colname[i];

    if (typ[i] == TYPE_UNKNOWN)            // Void column
      typ[i] = TYPE_STRING;

    crp = qrp->Colresp;                    // Column Name
    crp->Kdata->SetValue(p, i);
    crp = crp->Next;                       // Data Type
    crp->Kdata->SetValue(typ[i], i);
    crp = crp->Next;                       // Type Name
    crp->Kdata->SetValue(GetTypeName(typ[i]), i);
    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Length
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Scale (precision)
    crp->Kdata->SetValue(prc[i], i);
    } // endfor i

  /*********************************************************************/
  /*  Return the result pointer for use by GetData routines.           */
  /*********************************************************************/
  return qrp;

 err:
  fclose(infile);
  return NULL;
  } // end of CSVCColumns
Exemple #30
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