/* -*-C++-*-
**********************************************************************
*
* File:         LmRoutineC.cpp
* Description:  Base class for C routines
* Created:      05/14/2008
* Language:     C++
*
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/

#include "LmRoutineC.h"
#include "ComVersionDefs.h"

SQLUDR_CHAR *LmRoutineC::host_data_ = NULL;

LmRoutineC::LmRoutineC(const char   *sqlName,
                       const char   *externalName,
                       const char   *librarySqlName,
                       ComUInt32    numSqlParam,
                       char         *routineSig,
                       ComUInt32    maxResultSets,
                       ComRoutineLanguage language,
                       ComRoutineParamStyle paramStyle,
                       ComRoutineTransactionAttributes transactionAttrs,
                       ComRoutineSQLAccess sqlAccessMode,
                       ComRoutineExternalSecurity externalSecurity,
                       Int32        routineOwnerId,
                       const char   *parentQid,
                       ComUInt32    inputParamRowLen,
                       ComUInt32    outputRowLen,
                       const char   *currentUserName,
                       const char   *sessionUserName,
                       LmParameter  *parameters,
                       LmLanguageManagerC *lm,
                       LmHandle     routine,
                       LmContainer  *container,
                       ComDiagsArea *diagsArea)
  : LmRoutine(container, routine, sqlName, externalName, librarySqlName,
              numSqlParam, maxResultSets,
              language, paramStyle, transactionAttrs, sqlAccessMode,
              externalSecurity, 
	      routineOwnerId,
              parentQid, inputParamRowLen, outputRowLen, 
	          currentUserName, sessionUserName, 
	          parameters, lm),
    callType_(SQLUDR_CALLTYPE_INITIAL),
    stateArea_(NULL),
    udrInfo_(NULL),
    finalCallRequired_(FALSE)
{
  // If we ever support C stored procedures, we need to handle the
  // case of 0 inputs and 0 outputs. For functions there is always at
  // least one output.
  LM_ASSERT(numSqlParam_ > 0);
  
  // Allocate (static) host_data_ if it's not already allocated.
  // This will never be deleted and stays until the process dies.
  if (LmRoutineC::host_data_ == NULL)
  {
    LmRoutineC::host_data_ = (SQLUDR_CHAR *)
      malloc(SQLUDR_STATEAREA_BUFFER_SIZE + 128);
    LM_ASSERT(LmRoutineC::host_data_);
    memset((char *)LmRoutineC::host_data_, 0,
           SQLUDR_STATEAREA_BUFFER_SIZE + 128);
  }

  // Allocate the SQLUDR_STATEAREA structure
  stateArea_ = (SQLUDR_STATEAREA *) malloc(sizeof(SQLUDR_STATEAREA) + 32);
  LM_ASSERT(stateArea_);
  memset(stateArea_, 0, sizeof(SQLUDR_STATEAREA) + 32);
  stateArea_->version = SQLUDR_STATEAREA_CURRENT_VERSION;
  
  stateArea_->host_data.data = LmRoutineC::host_data_;
  stateArea_->host_data.length = SQLUDR_STATEAREA_BUFFER_SIZE;;

  stateArea_->stmt_data.data = (SQLUDR_CHAR *)
    malloc(SQLUDR_STATEAREA_BUFFER_SIZE + 128);
  LM_ASSERT(stateArea_->stmt_data.data);
  memset((char *)stateArea_->stmt_data.data, 0,
         SQLUDR_STATEAREA_BUFFER_SIZE + 128);
  stateArea_->stmt_data.length = SQLUDR_STATEAREA_BUFFER_SIZE;
  
  // Allocate SQLUDR_UDRINFO structure
  udrInfo_ = (SQLUDR_UDRINFO *) malloc(sizeof(SQLUDR_UDRINFO) + 32);
  LM_ASSERT(udrInfo_);
  memset(udrInfo_, 0, sizeof(SQLUDR_UDRINFO) + 32);

  udrInfo_->version = SQLUDR_UDRINFO_CURRENT_VERSION;
  udrInfo_->sql_version = 2400;
  udrInfo_->routine_name = sqlName_;
  // udrInfo_->library_name = librarySqlName_;
  
  const char *qid = getParentQid();
  if (qid)
    udrInfo_->query_id = copy_and_pad(qid, strlen(qid), 8);

  // Allocate memory for SQLUDR_PARAM structure.
  // We assume that the inputs come first, followed by outputs
  ComUInt32 num_inputs = 0, num_outputs = 0;
  SQLUDR_PARAM *sqludr_params = (SQLUDR_PARAM *)
    malloc(numSqlParam_ * sizeof(SQLUDR_PARAM) + 32);
  LM_ASSERT(sqludr_params);
  memset(sqludr_params, 0, numSqlParam_ * sizeof(SQLUDR_PARAM) + 32);

  // Initialize the SQLUDR_PARAM structures
  ComUInt32 dataBytes = 0;
  ComUInt32 i;
  for (i = 0; i < numSqlParam_; i++)
  {
    LmParameter &p = lmParams_[i];

    switch (p.direction())
    {
      case COM_INPUT_COLUMN:
	num_inputs++;
        dataBytes = p.inSize();
        break;
      case COM_OUTPUT_COLUMN:
	num_outputs++;
        dataBytes = p.outSize();
        break;
      default:
        LM_ASSERT1(0, "Invalid parameter mode");
        break;
    }
      
    SQLUDR_PARAM &udfParamInfo = sqludr_params[i];
    udfParamInfo.version = SQLUDR_PARAM_CURRENT_VERSION;
    udfParamInfo.datatype =
      (SQLUDR_INT16) getAnsiTypeFromFSType(p.fsType());
    
    udfParamInfo.data_len = (SQLUDR_UINT32) dataBytes;

    // The parameter name seen by the routine body will be a pointer
    // to the LmParameter's copy of the name.
    udfParamInfo.name = (SQLUDR_CHAR *) p.getParamName();

    // Union u1 contains:
    // * character_set
    // * datetime_code
    // * interval_code
    // * scale
    if (p.isCharacter())
    {
      udfParamInfo.u1.character_set =
        (SQLUDR_INT16) p.encodingCharSet();
    }
    else if (p.isDateTime())
    {
      // For datetime types: ANSI type will be SQLTYPECODE_DATETIME and
      // SQLUDR_PARAM stores a code to indicate date, time, or
      // timestamp.
      udfParamInfo.u1.datetime_code =
        (SQLUDR_INT16) p.getDatetimeCode();
    }
    else if (p.isInterval())
    {
      // For interval types: ANSI type will be SQLTYPECODE_INTERVAL and
      // SQLUDR_PARAM stores a code to indicate start and end fields.
      udfParamInfo.u1.interval_code =
        (SQLUDR_INT16) getIntervalCode(p.fsType());
    }
    else
    {
      udfParamInfo.u1.scale = (SQLUDR_INT16) p.scale();
    }

    // Union u2 contains:
    // * precision
    // * collation
    if (p.isTimeOrTimestamp())
    {
      udfParamInfo.u2.precision = (SQLUDR_INT16) p.getTimePrecision();
    }
    else if (p.isCharacter())
    {
      SQLUDR_COLLATION collation = SQLUDR_COLLATION_UNKNOWN;
      switch (p.collation())
      {
        case CharInfo::DefaultCollation:
          collation = SQLUDR_COLLATION_DEFAULT;
          break;
        case CharInfo::CZECH_COLLATION:
          collation = SQLUDR_COLLATION_CZECH;
          break;
        case CharInfo::CZECH_COLLATION_CI:
          collation = SQLUDR_COLLATION_CZECH_CI;
          break;
        case CharInfo::SJIS_COLLATION:
          collation = SQLUDR_COLLATION_SJIS;
          break;
      }
      udfParamInfo.u2.collation = (SQLUDR_INT16) collation;
    }
    else
    {
      udfParamInfo.u2.precision = (SQLUDR_INT16) p.prec();
    }
    
    // Set data offsets and lengths
    if((getParamStyle() == COM_STYLE_SQLROW) ||
       (getParamStyle() == COM_STYLE_SQLROW_TM))
    {
      switch (p.direction())
      {
        case COM_INPUT_COLUMN:
          udfParamInfo.data_offset = (SQLUDR_UINT32) p.inDataOffset();
          udfParamInfo.ind_offset = (SQLUDR_UINT32) p.inNullIndOffset();
          udfParamInfo.vc_ind_offset = (SQLUDR_UINT32) p.inVCLenIndOffset();
          udfParamInfo.vc_ind_len = (SQLUDR_UINT8) p.inVCLenIndSize();
          break;
        case COM_OUTPUT_COLUMN:
          udfParamInfo.data_offset = (SQLUDR_UINT32) p.outDataOffset();
          udfParamInfo.ind_offset = (SQLUDR_UINT32) p.outNullIndOffset();
          udfParamInfo.vc_ind_offset = (SQLUDR_UINT32) p.outVCLenIndOffset();
          udfParamInfo.vc_ind_len = (SQLUDR_UINT8) p.outVCLenIndSize();
          break;
        default:
          LM_ASSERT1(0, "Invalid parameter mode");
          break;
      }

    } // if (getParamStyle() == COM_STYLE_SQLROW)
    
  } // for each param
    
  // Fill in the rest of udrInfo_ structure fields
  udrInfo_->sql_version = (SQLUDR_UINT16) ComVersion_GetMXV();
  udrInfo_->row_format = SQLUDR_ROWFORMAT_EXPLODED;
  udrInfo_->num_inputs = num_inputs;
  udrInfo_->num_return_values = num_outputs;
  udrInfo_->inputs = (num_inputs > 0 ? &sqludr_params[0] : NULL);
  udrInfo_->return_values =
    (num_outputs > 0 ? &sqludr_params[num_inputs] : NULL);
  udrInfo_->in_row_length = inputParamRowLen_;
  udrInfo_->out_row_length = outputRowLen_;

  switch (getParamStyle())
  {
    case COM_STYLE_SQL:
      udrInfo_->param_style = SQLUDR_PARAMSTYLE_SQL;
      udrInfo_->param_style_version = 1;
      break;
    case COM_STYLE_SQLROW:
    case COM_STYLE_SQLROW_TM:
      udrInfo_->param_style = SQLUDR_PARAMSTYLE_SQLROW;
      udrInfo_->param_style_version = 1;
      break;
    case COM_STYLE_CPP_OBJ:
      // udrInfo_ is not used
      break;
    default:
      LM_ASSERT(0);
      break;
  }

  // Fill current user name and session user name 
  
  if (currentUserName)
    udrInfo_->current_user_name = copy_and_pad(currentUserName, strlen(currentUserName), 8);
  
  if (sessionUserName)
    udrInfo_->session_user_name = copy_and_pad(sessionUserName, strlen(sessionUserName), 8);
  
} // LmRoutineC::LmRoutineC

LmRoutineC::~LmRoutineC()
{
  // udrInfo_->return_values is not needed to be deleted. It's
  // all consecutively allocated memory starting from
  // udrInfo_->inputs.
  SQLUDR_PARAM *sqludr_params = udrInfo_->inputs;
  free(sqludr_params);

  if (stateArea_ && stateArea_->stmt_data.data)
    free(stateArea_->stmt_data.data);

  if (stateArea_)
    free(stateArea_);

  if (udrInfo_)
  {
    if (udrInfo_->query_id)
      free(udrInfo_->query_id);
    if (udrInfo_->current_user_name)
      free(udrInfo_->current_user_name);
    if (udrInfo_->session_user_name)
      free(udrInfo_->session_user_name);
    deletePassThroughInputs();
    free(udrInfo_);
  }
}

void
LmRoutineC::setNumPassThroughInputs(ComUInt32 numPassThroughInputs)
{
  deletePassThroughInputs();

  udrInfo_->num_pass_through = numPassThroughInputs;
  udrInfo_->pass_through = NULL;
  
  if (numPassThroughInputs > 0)
  {
    ComUInt32 numBytes = (numPassThroughInputs * sizeof(SQLUDR_BUFFER)) + 32;
    udrInfo_->pass_through = (SQLUDR_BUFFER *) malloc(numBytes);
    LM_ASSERT(udrInfo_->pass_through);
    memset(udrInfo_->pass_through, 0, numBytes);
  }
}

void
LmRoutineC::setPassThroughInput(ComUInt32 index,
	                        void *data,
	                        ComUInt32 dataLen)
{
  SQLUDR_BUFFER &pass_through_buffer = udrInfo_->pass_through[index];

  pass_through_buffer.length = dataLen;

  if (dataLen > 0)
  {
    LM_ASSERT(data);
    pass_through_buffer.data = copy_and_pad((char *) data, dataLen, 32);
  }
  else
  {
    pass_through_buffer.data = copy_and_pad("", 0, 32);
  }
}

void LmRoutineC::deletePassThroughInputs()
{
  if (udrInfo_)
  {
    if (udrInfo_->num_pass_through > 0)
    {
      LM_ASSERT(udrInfo_->pass_through);

      for (ComUInt32 i = 0; i < udrInfo_->num_pass_through; i++)
      {
        SQLUDR_BUFFER &b = udrInfo_->pass_through[i];
        free(b.data);
      }

      free(udrInfo_->pass_through);
    }
    
    udrInfo_->num_pass_through = 0;
    udrInfo_->pass_through = NULL;
  }
}

LmResult LmRoutineC::handleFinalCall(ComDiagsArea *diagsArea)
{
  setFinalCall();
  return invokeRoutine(NULL, NULL, diagsArea);
}

LmResult
LmRoutineC::processReturnStatus(ComSInt32 retcode, ComDiagsArea *diags)
{
  char *returnMsgText = NULL, *noMsgText = NULL;

  if (retcode == SQLUDR_SUCCESS)
    return LM_OK;

  if (msgText_[0] != '\0')
  {
    returnMsgText = msgText_;
  }
  else
  {
    const char *text =
      "No SQL message text was provided by user-defined function ";
    ComUInt32 msgLen = str_len(text) + str_len(getNameForDiags());
    noMsgText = new (collHeap()) char[msgLen + 1];
    sprintf(noMsgText, "%s%s", text, getNameForDiags());

    returnMsgText = noMsgText;
  }

  // Check the returned SQLSTATE value and raise appropriate
  // SQL code. Valid SQLSTATE values begin with "38" except "38000"
  if ((strncmp(sqlState_, "38", 2) == 0) &&
      (strncmp(sqlState_, "38000", 5) != 0))
  {
    Int32 sqlCode = (retcode == SQLUDR_ERROR) ?
      -LME_CUSTOM_ERROR : LME_CUSTOM_WARNING;

    *diags << DgSqlCode(sqlCode)
           << DgString0(returnMsgText)
	   << DgString1(sqlState_);
    *diags << DgCustomSQLState(sqlState_);
  }
  else
  {
    Int32 sqlCode = (retcode == SQLUDR_ERROR) ? -LME_UDF_ERROR : LME_UDF_WARNING;

    *diags << DgSqlCode(sqlCode)
	   << DgString0(getNameForDiags())
           << DgString1(sqlState_)
           << DgString2(returnMsgText);
  }

  if (noMsgText)
    NADELETEBASIC(noMsgText, collHeap());

  return (retcode == SQLUDR_ERROR) ? LM_ERR: LM_OK;
}

