Пример #1
0
bool ARRAY::GetSubValue(PGLOBAL g, PVAL valp, int *kp)
  {
  PVBLK vblp;

  if (Type != TYPE_LIST) {
    sprintf(g->Message, MSG(NO_SUB_VAL), Type);
    return TRUE;
    } // endif Type

  vblp = ((LSTBLK*)Vblp)->Mbvk[kp[0]]->Vblk;
  valp->SetValue_pvblk(vblp, kp[1]);
  return FALSE;
  } // end of GetSubValue
Пример #2
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
Пример #3
0
void ARRAY::GetNthValue(PVAL valp, int n)
  {
  valp->SetValue_pvblk(Vblp, n);
  } // end of GetNthValue