Пример #1
0
bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
  {
  if (!(Dvalp = AllocateValue(g, TYPE_DATE, len, year, false, fmt)))
    return true;

  return false;
  } // end of SetFormat
Пример #2
0
ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(FALSE)
  {
  int     prec;
  LSTBLK *lp;

  if (par->Type != TYPE_LIST) {
    Type = TYPE_ERROR;
    return;
    } // endif Type

  lp = (LSTBLK*)par->Vblp;

  Nval = par->Nval;
  Ndif = 0;
  Bot = 0;
  Top = 0;
  Size = par->Size;
  Xsize = -1;

  Valblk = lp->Mbvk[k];
  Vblp = Valblk->Vblk;
  Type = Vblp->GetType();
  Len = (Type == TYPE_STRING) ? Vblp->GetVlen() : 0;
  prec = (Type == TYPE_FLOAT) ? 2 : 0;
  Value = AllocateValue(g, Type, Len, prec, NULL);
  Constant = TRUE;
  } // end of ARRAY constructor
Пример #3
0
bool FNCCOL::InitColumn(PGLOBAL g)
{
  // Must have its own value block
  if (InitValue(g))
    return TRUE;

  // Make a value from the column name
  Hval = AllocateValue(g, Name, TYPE_STRING);
  Hval->SetPrec(1);         // Case insensitive

  Xcolp = ((PTDBPIVOT)To_Tdb)->Xcolp;
  AddStatus(BUF_READ);      // All is done here
  return FALSE;
} // end of InitColumn
Пример #4
0
ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec)
     : CSORT(FALSE)
  {
  Nval = 0;
  Ndif = 0;
  Bot = 0;
  Top = 0;
  Size = size;
  Type = type;
  Xsize = -1;
  Len = 1;

  switch (type) {
    case TYPE_STRING:
      Len = length;
    case TYPE_SHORT:
    case TYPE_INT:
    case TYPE_DOUBLE:
    case TYPE_PCHAR:
      Type = type;
      break;
    case TYPE_VOID:
      Type = TYPE_INT;
      break;
#if 0
    case TYPE_TOKEN:
      break;
    case TYPE_LIST:
      Len = 0;
      prec = length;
      break;
#endif // 0
    default:  // This is illegal an causes an ill formed array building
      sprintf(g->Message, MSG(BAD_ARRAY_TYPE), type);
      Type = TYPE_ERROR;
      return;
    } // endswitch type

  Valblk = new(g) MBVALS;

  if (!(Vblp = Valblk->Allocate(g, Type, Len, prec, Size)))
    Type = TYPE_ERROR;
  else if (!Valblk->GetMemp() && Type != TYPE_LIST)
    // The error message was built by PlgDBalloc
    Type = TYPE_ERROR;
  else if (type != TYPE_PCHAR)
    Value = AllocateValue(g, type, Len, prec);

  Constant = TRUE;
  } // end of ARRAY constructor
Пример #5
0
bool COLBLK::InitValue(PGLOBAL g)
  {
  if (Value)
    return false;                       // Already done

  // Unsigned can be set only for valid value types
  int prec = (Unsigned) ? 1 : GetPrecision();

  // Allocate a Value object
  if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
                                 prec, GetDomain())))
    return true;

  AddStatus(BUF_READY);
  Value->SetNullable(Nullable);

#ifdef DEBTRACE
 htrc(" colp=%p type=%d value=%p coluse=%.4X status=%.4X\n",
  this, Buf_Type, Value, ColUse, Status);
#endif

  return false;
  } // end of InitValue
Пример #6
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
Пример #7
0
int ARRAY::Convert(PGLOBAL g, int k, PVAL vp)
  {
  int   i, prec = 0;
  bool  b = FALSE;
  PMBV  ovblk = Valblk;
  PVBLK ovblp = Vblp;

  Type = k;                    // k is the new type
  Valblk = new(g) MBVALS;

  switch (Type) {
    case TYPE_DOUBLE:
      prec = 2;
    case TYPE_SHORT:
    case TYPE_INT:
    case TYPE_DATE:
      Len = 1;
      break;
    default:
      sprintf(g->Message, MSG(BAD_CONV_TYPE), Type);
      return TYPE_ERROR;
    } // endswitch k

  Size = Nval;
  Nval = 0;
  Vblp = Valblk->Allocate(g, Type, Len, prec, Size);

  if (!Valblk->GetMemp())
    // The error message was built by PlgDBalloc
    return TYPE_ERROR;
  else
    Value = AllocateValue(g, Type, Len, prec);

  /*********************************************************************/
  /*  Converting STRING to DATE can be done according to date format.  */
  /*********************************************************************/
  if (Type == TYPE_DATE && ovblp->GetType() == TYPE_STRING && vp)
    if (((DTVAL*)Value)->SetFormat(g, vp))
      return TYPE_ERROR;
    else
      b = TRUE;  // Sort the new array on date internal values

  /*********************************************************************/
  /*  Do the actual conversion.                                        */
  /*********************************************************************/
  for (i = 0; i < Size; i++) {
    Value->SetValue_pvblk(ovblp, i);

    if (AddValue(g, Value))
      return TYPE_ERROR;

    } // endfor i

  /*********************************************************************/
  /*  For sorted arrays, get the initial find values.                  */
  /*********************************************************************/
  if (b)
    Sort(g);

  ovblk->Free();
  return Type;
  } // end of Convert