void MADB_CopyMadbTimestamp(MYSQL_TIME *tm, MADB_Desc *Ard, MADB_DescRecord *ArdRecord, int Type, unsigned long RowNumber)
{
  void *DataPtr= GetBindOffset(Ard, ArdRecord, ArdRecord->DataPtr, RowNumber, ArdRecord->OctetLength);

  switch(Type) {
  case SQL_C_TIMESTAMP:
  case SQL_C_TYPE_TIMESTAMP:
    {
      SQL_TIMESTAMP_STRUCT *ts= (SQL_TIMESTAMP_STRUCT *)DataPtr;
      /* if (!tm->year)
      {
        time_t sec_time;
        struct tm * cur_tm;
        sec_time= time(NULL);
        cur_tm= localtime(&sec_time);
        ts->year= 1900 + cur_tm->tm_year;
        ts->month= cur_tm->tm_mon + 1;
        ts->day= cur_tm->tm_mday;
      }
      else */
      {
        ts->year= tm->year;
        ts->month= tm->month;
        ts->day= tm->day;
      }
      ts->hour= tm->hour;
      ts->minute= tm->minute;
      ts->second= tm->second;
      ts->fraction= tm->second_part * 1000;
      if (ts->year + ts->month + ts->day + ts->hour + ts->minute + ts->fraction + ts->second == 0)
        if (ArdRecord->IndicatorPtr)
          *ArdRecord->IndicatorPtr= SQL_NULL_DATA;
    }
    break;
    case SQL_C_TIME:
    case SQL_TYPE_TIME:
    {
      SQL_TIME_STRUCT *ts= (SQL_TIME_STRUCT *)DataPtr;
      ts->hour= tm->hour;
      ts->minute= tm->minute;
      ts->second= tm->second;
       if (ts->hour + ts->minute + ts->second == 0)
        if (ArdRecord->IndicatorPtr)
          *ArdRecord->IndicatorPtr= SQL_NULL_DATA;
    }
    break;
    case SQL_C_DATE:
    case SQL_TYPE_DATE:
    {
      SQL_DATE_STRUCT *ts= (SQL_DATE_STRUCT *)DataPtr;
      ts->year= tm->year;
      ts->month= tm->month;
      ts->day= tm->day;
      if (ts->year + ts->month + ts->day == 0)
        if (ArdRecord->IndicatorPtr)
          *ArdRecord->IndicatorPtr= SQL_NULL_DATA;
    }
    break;
  }
}
Esempio n. 2
0
void MADB_CleanBulkOperData(MADB_Stmt *Stmt, unsigned int ParamOffset)
{
  if (MADB_DOING_BULK_OPER(Stmt))
  {
    MADB_DescRecord *CRec;
    void            *DataPtr= NULL;
    MYSQL_BIND      *MaBind= NULL;
    int             i;

    for (i= ParamOffset; i < MADB_STMT_PARAM_COUNT(Stmt); ++i)
    {
      if (CRec= MADB_DescGetInternalRecord(Stmt->Apd, i, MADB_DESC_READ))
      {
        MaBind= &Stmt->params[i - ParamOffset];
        DataPtr= GetBindOffset(Stmt->Apd, CRec, CRec->DataPtr, 0, CRec->OctetLength);

        if (MaBind->buffer != DataPtr)
        {
          switch (CRec->ConciseType)
          {
          case DATETIME_TYPES:
            if (CanUseStructArrForDatetime(Stmt) == FALSE)
            {
              MADB_FREE(MaBind->buffer);
              break;
            }
            /* Otherwise falling through and do the same as for others */
          case SQL_C_WCHAR:
          case SQL_C_NUMERIC:
          {
            unsigned int i;
            for (i= 0; i < Stmt->Bulk.ArraySize; ++i)
            {
              MADB_FREE(((char**)MaBind->buffer)[i]);
            }
          }
          /* falling through */
          default:
            MADB_FREE(MaBind->buffer);
          }
        }

        MADB_FREE(MaBind->length);

        MADB_FREE(MaBind->u.indicator);
      }
    }
    Stmt->Bulk.ArraySize= 0;
    Stmt->Bulk.HasRowsToSkip= 0;
  }
}
Esempio n. 3
0
/* Checking if column ignored in all bound rows. Should hel*/
BOOL MADB_ColumnIgnoredInAllRows(MADB_Desc *Desc, MADB_DescRecord *Rec)
{
  SQLULEN row;
  SQLLEN *IndicatorPtr;

  for (row= 0; row < Desc->Header.ArraySize; ++row)
  {
    IndicatorPtr= (SQLLEN *)GetBindOffset(Desc, Rec, Rec->IndicatorPtr, row, sizeof(SQLLEN));

    if (IndicatorPtr == NULL || *IndicatorPtr != SQL_COLUMN_IGNORE)
    {
      return FALSE;
    }
  }

  return TRUE;
}
Esempio n. 4
0
int MADB_FindNextDaeParam(MADB_Desc *Desc, int InitialParam, SQLSMALLINT RowNumber)
{
  int             i;
  MADB_DescRecord *Record;

  for (i= InitialParam > -1 ? InitialParam + 1 : 0; i < Desc->Header.Count; i++)
  {
    if ((Record= MADB_DescGetInternalRecord(Desc, i, MADB_DESC_READ)))
    {
      if (Record->OctetLengthPtr)
      {
        /* Stmt->DaeRowNumber is 1 based */
        SQLLEN *OctetLength = (SQLLEN *)GetBindOffset(Desc, Record, Record->OctetLengthPtr, RowNumber > 1 ? RowNumber - 1 : 0, sizeof(SQLLEN));
        if (PARAM_IS_DAE(OctetLength))
        {
          return i;
        }
      }
    }
  }

  return MADB_NOPARAM;
}
/* {{{ MADB_CharToSQLNumeric */
int MADB_CharToSQLNumeric(char *buffer, MADB_Desc *Ard, MADB_DescRecord *ArdRecord, unsigned long RowNumber)
{
  char *p;
  SQL_NUMERIC_STRUCT *number= (SQL_NUMERIC_STRUCT *)GetBindOffset(Ard, ArdRecord, ArdRecord->DataPtr, RowNumber, ArdRecord->OctetLength);
  int ret= 0;

  if (!buffer || !number)
    return ret;

  p= trim(buffer);
  MADB_NumericInit(number, ArdRecord);

  if (!(number->sign= (*p=='-') ? 0 : 1))
    p++;
  if (!*p)
    return FALSE;

  if (number->precision == 0)
  {
    number->precision= MADB_DEFAULT_PRECISION;
  }
   
  while (*p=='0')
    p++;
  if (*p)
  {
    int i;
    int bit, hval, tv, dig, sta, olen;
    int tmp_digit= 0;
    int leading_zeros= 0;
    char *dot= strchr(p, '.');
    char digits[100];
    short digits_count= 0;

    /* Overflow check */
    if (number->precision > 0 && (dot - p) > number->precision)
      return MADB_ERR_22003;
    
    if (dot && number->scale > 0)
    {
      short digits_total= 0, 
            digits_significant= 0;
      digits_count= dot - p;
      memcpy(digits, p, digits_count);
      p= dot + 1;
      while (*p)
      {
        /* ignore non numbers */
        if (!isdigit(*p))
          break;
        digits_total++;
        /* ignore trailing zeros */
        if (*p != '0')
          digits_significant= digits_total;
        p++;
      }
      /* check possible overflow */
      digits_significant= MIN(digits_significant,number->scale);
      if (digits_count + digits_significant > number->precision)
      {
        int i;
        /* if digits are zero there is no overflow */
        for (i=1; i <= digits_significant; i++)
        {
          p= dot + i;
          if (*p != '0')
            return MADB_ERR_22003;
        }
      }
      
      memcpy(digits + digits_count, dot + 1, digits_significant);
      digits_count+= digits_significant;

    } else 
    {
      char *start= p;
      while (*p && isdigit(*p))
        p++;
      /* check overflow */
      if (p - start > number->precision)
      {
        return MADB_ERR_22003;
      }
      digits_count= p - start;
      memcpy(digits, start, digits_count);
      number->scale= ArdRecord->Scale ? ArdRecord->Scale : 0;
    }
    /* Rounding */
    
    if (number->scale < 0)
    {
      int64_t OldVal, Val;
      int64_t RoundNumber= (int64_t)pow(10.0, -number->scale);

      digits[number->precision]= 0;
      Val= _atoi64(digits);
      OldVal= Val;
      Val= (Val + RoundNumber / 2) / RoundNumber * RoundNumber;
      if (OldVal != Val)
        return MADB_ERR_22003;
      _i64toa(Val, digits, 10);
      digits_count= strlen(digits);
      if (digits_count > number->precision)
        return MADB_ERR_22003;
    }
    digits_count= MIN(digits_count, 38);
    for (hval = 0, bit = 1L, sta = 0, olen = 0; sta < digits_count;)
    {
      for (dig = 0, i = sta; i < digits_count; i++)
      {
        tv = dig * 10 + digits[i] - '0';
        dig = tv % 2;
        digits[i] = tv / 2 + '0';
        if (i == sta && tv < 2)
          sta++;
      }
      if (dig > 0)
        hval |= bit;
      bit <<= 1;
      if (bit >= (1L << 8))
      {
        number->val[olen++] = hval;
        hval = 0;
        bit = 1L;
        if (olen >= SQL_MAX_NUMERIC_LEN - 1)
        {
          //number->scale = sta - number->precision;
          //ret= MADB_ERR_22003;
          break;
        }
      } 
    }
    if (hval && olen < SQL_MAX_NUMERIC_LEN - 1)
      number->val[olen++] = hval;
  } 
  return ret;
}
Esempio n. 6
0
/* Assuming that bulk insert can't go with DAE(and that unlikely ever changes). And that it has been checked before this call,
and we can't have DAE here */
SQLRETURN MADB_ExecuteBulk(MADB_Stmt *Stmt, unsigned int ParamOffset)
{
  unsigned int  i, IndIdx= -1;
  unsigned long Dummy;

  for (i= ParamOffset; i < ParamOffset + MADB_STMT_PARAM_COUNT(Stmt); ++i)
  {
    MADB_DescRecord *CRec, *SqlRec;
    SQLLEN          *IndicatorPtr= NULL;
    SQLLEN          *OctetLengthPtr= NULL;
    void            *DataPtr= NULL;
    MYSQL_BIND      *MaBind= &Stmt->params[i - ParamOffset];
    SQLULEN         row, Start= Stmt->ArrayOffset;

    if ((CRec= MADB_DescGetInternalRecord(Stmt->Apd, i, MADB_DESC_READ)) &&
      (SqlRec= MADB_DescGetInternalRecord(Stmt->Ipd, i, MADB_DESC_READ)))
    {
      /* check if parameter was bound */
      if (!CRec->inUse)
      {
        return MADB_SetError(&Stmt->Error, MADB_ERR_07002, NULL, 0);
      }

      if (MADB_ConversionSupported(CRec, SqlRec) == FALSE)
      {
        return MADB_SetError(&Stmt->Error, MADB_ERR_07006, NULL, 0);
      }

      MaBind->length= NULL;
      IndicatorPtr=   (SQLLEN *)GetBindOffset(Stmt->Apd, CRec, CRec->IndicatorPtr, 0, sizeof(SQLLEN));
      OctetLengthPtr= (SQLLEN *)GetBindOffset(Stmt->Apd, CRec, CRec->OctetLengthPtr, 0, sizeof(SQLLEN));
      DataPtr=        GetBindOffset(Stmt->Apd, CRec, CRec->DataPtr, 0, CRec->OctetLength);

      /* If these are the same pointers, setting indicator to NULL to simplify things a bit */
      if (IndicatorPtr == OctetLengthPtr)
      {
        IndicatorPtr= NULL;
      }
      /* Well, specs kinda say, that both values and lenghts arrays should be set(in instruction to param array operations)
         But there is no error/sqlstate for the case if any of those pointers is not set. Thus we assume that is possible */
      if (DataPtr == NULL)
      {
        /* Special case - DataPtr is not set, we treat it as all values are NULL. Setting indicators and moving on next param */
        RETURN_ERROR_OR_CONTINUE(MADB_InitIndicatorArray(Stmt, MaBind, MADB_MapIndicatorValue(SQL_NULL_DATA)));
        continue;
      }

      /* Sets Stmt->Bulk.HasRowsToSkip if needed, since it traverses and checks status array anyway */
      RETURN_ERROR_OR_CONTINUE(MADB_InitBulkOperBuffers(Stmt, CRec, DataPtr, OctetLengthPtr, IndicatorPtr, SqlRec->ConciseType, MaBind));

      if (MaBind->u.indicator != NULL && IndIdx == (unsigned int)-1)
      {
        IndIdx= i - ParamOffset;
      }

      /* Doing it on last parameter - just to do do this once, and to use already allocated indicator array.
         Little stupid optimization. But it's actually even a bit simpler this way */
      if (i == ParamOffset + MADB_STMT_PARAM_COUNT(Stmt) - 1 && Stmt->Bulk.HasRowsToSkip)
      {
        if (IndIdx == (unsigned int)-1)
        {
          IndIdx= 0;
        }

        for (row= Start; row < Start + Stmt->Apd->Header.ArraySize; ++row)
        {
          if (Stmt->Apd->Header.ArrayStatusPtr[row] == SQL_PARAM_IGNORE)
          {
            MADB_SetIndicatorValue(Stmt, &Stmt->params[IndIdx], (unsigned int)row, SQL_PARAM_IGNORE);
          }
        }       
      }

      if (MADB_AppBufferCanBeUsed(CRec->ConciseType, SqlRec->ConciseType))
      {
        /* Everything has been done for such column already */
        continue;
      }

      /* We either have skipped rows or need to convert parameter values/convert array */
      for (row= Start; row < Start + Stmt->Apd->Header.ArraySize; ++row, DataPtr= (char*)DataPtr + CRec->OctetLength)
      {
        void *Buffer= (char*)MaBind->buffer + row*MaBind->buffer_length;
        void **BufferPtr= (void**)Buffer; /* For the case when Buffer points to the pointer already */

        if (Stmt->Apd->Header.ArrayStatusPtr != NULL && Stmt->Apd->Header.ArrayStatusPtr[row] == SQL_PARAM_IGNORE)
        {
          continue;
        }
        if (MaBind->u.indicator && MaBind->u.indicator[row] > STMT_INDICATOR_NONE)
        {
          continue;
        }

        switch (CRec->ConciseType)
        {
        case SQL_C_CHAR:
          if (SqlRec->ConciseType != SQL_BIT)
          {
            break;
          }
        case DATETIME_TYPES:
          if (CanUseStructArrForDatetime(Stmt))
          {
            BufferPtr= &Buffer;
          }
        }

        /* Need &Dummy here as a length ptr, since NULL is not good here.
           It would make MADB_ConvertC2Sql to use MaBind->buffer_length by default */
        if (!SQL_SUCCEEDED(MADB_ConvertC2Sql(Stmt, CRec, DataPtr, MaBind->length != NULL ? MaBind->length[row] : 0,
          SqlRec, MaBind, BufferPtr, MaBind->length != NULL ? MaBind->length + row : &Dummy)))
        {
          /* Perhaps it's better to move to Clean function */
          CRec->InternalBuffer= NULL;
          return Stmt->Error.ReturnValue;
        }
        CRec->InternalBuffer= NULL;
      }
    }
  }

  return MADB_DoExecute(Stmt, FALSE);
}