/**********************************************************************
// @@@ 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 @@@
//********************************************************************/
/* -*-C++-*-
 *****************************************************************************
 *
 * File:         NATableSt.cpp
 * Description:
 *
 * Created:      2/06/2012
 * Language:     C++
 *
 *****************************************************************************
 */

#include "NATable.h"
#include "NATableSt.h"
#include "SchemaDB.h"
#include "CmpErrors.h"
#include "CmpMain.h"
#include "Globals.h"
#include "Context.h"

//-----------------------------------------------------------------------
// NATableCacheStoredProcedure is a class that contains functions used by
// the NATableCache virtual table, whose purpose is to serve as an interface
// to the SQL/MX NATable cache statistics. This table is implemented as
// an internal stored procedure.
//-----------------------------------------------------------------------

SP_STATUS NATableCacheStatStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "NATableCache");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
     //column as input parameter for ISP, specifiy cache of metadata or user context
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance char(16)  not null");
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location char(16)  not null"); 
     return SP_SUCCESS;
}

const Lng32 NUM_OF_OUTPUT = 7;

SP_STATUS NATableCacheStatStoredProcedure::sp_NumOutputFields(
  Lng32 *numFields,
  SP_COMPILE_HANDLE spCompileObj,
  SP_HANDLE spObj,
  SP_ERROR_STRUCT *error)
{
  *numFields = NUM_OF_OUTPUT;
  return SP_SUCCESS;
}

SP_STATUS NATableCacheStatStoredProcedure::sp_OutputFormat(
  SP_FIELDDESC_STRUCT *format,
  SP_KEYDESC_STRUCT keyFields[],
  Lng32 *numKeyFields,
  SP_HANDLE spCompileObj,
  SP_HANDLE spObj,
  SP_ERROR_STRUCT *error)
{
  strcpy(&((format++)->COLUMN_DEF[0]), "Context          CHAR(8) CHARACTER SET ISO88591");
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_lookups      INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cache_hits   INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_entries   INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Current_cache_size   INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "High_watermark   INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Max_cache_size   INT UNSIGNED");

  return SP_SUCCESS;
}

SP_STATUS NATableCacheStatStoredProcedure::sp_Process(
     SP_PROCESS_ACTION action,
     SP_ROW_DATA inputData,
     SP_EXTRACT_FUNCPTR eFunc,
     SP_ROW_DATA outputData,
     SP_FORMAT_FUNCPTR fFunc,
     SP_KEY_VALUE keys,
     SP_KEYVALUE_FUNCPTR kFunc,
     SP_PROCESS_HANDLE *spProcHandle,
     SP_HANDLE spObj,
     SP_ERROR_STRUCT *error)
{
  if (action == SP_PROC_OPEN) {
  
    NATableCacheStatsISPIterator * it = new (GetCliGlobals()->exCollHeap()) 
      NATableCacheStatsISPIterator(inputData, eFunc, error,
                                   GetCliGlobals()->currContext()->getCmpContextInfo(), 
                                   GetCliGlobals()->exCollHeap());
    *spProcHandle = it;
    return SP_SUCCESS;
  }

  if (action == SP_PROC_FETCH) {
    NATableCacheStatsISPIterator* it = (NATableCacheStatsISPIterator *)(*spProcHandle);

    if (!it) {
      return SP_FAIL;
    }

    NATableCacheStats stats;
    if(!it->getNext(stats))
       return SP_SUCCESS;

    fFunc(0, outputData, sizeof(stats.contextType), &(stats.contextType), 0);
    fFunc(1, outputData, sizeof(ULng32), &(stats.numLookups), 0);
    fFunc(2, outputData, sizeof(ULng32), &(stats.numCacheHits), 0);
    fFunc(3, outputData, sizeof(ULng32), &(stats.numEntries), 0);
    fFunc(4, outputData, sizeof(ULng32), &(stats.currentCacheSize), 0);
    fFunc(5, outputData, sizeof(ULng32), &(stats.highWaterMark), 0);
    fFunc(6, outputData, sizeof(ULng32), &(stats.maxCacheSize), 0);
    return SP_MOREDATA;
  }

  
  if (action == SP_PROC_CLOSE) {
    if (*spProcHandle)
      NADELETEBASIC((NATableCacheStatsISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
    return SP_SUCCESS;
  }

  return SP_SUCCESS;
}

void NATableCacheStatStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("NATABLECACHE",
          sp_Compile,
          sp_InputFormat,
          0,
          sp_NumOutputFields,
          sp_OutputFormat,
          sp_Process,
          0,
	  CMPISPVERSION);
}


SP_STATUS NATableCacheEntriesStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "NATableCacheEntries");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
     //column as input parameter for ISP, specifiy cache of metadata or user context
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance char(16)  not null");
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location char(16)  not null"); 
     return SP_SUCCESS;
}


SP_STATUS
  NATableCacheEntriesStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
						       SP_COMPILE_HANDLE spCompileObj,
						       SP_HANDLE spObj,
						       SP_ERROR_STRUCT *error)
{
  *numFields = 5;
  return SP_SUCCESS;
}

// Specifies the columns of the NATableEntries table and their types
SP_STATUS NATableCacheEntriesStoredProcedure::sp_OutputFormat(
						SP_FIELDDESC_STRUCT* format,
						SP_KEYDESC_STRUCT*  /*keyFields */,
						Lng32*  /*numKeyFields */,
						SP_COMPILE_HANDLE cmpHandle,
						SP_HANDLE /* spHandle */,
						SP_ERROR_STRUCT* /* error */  )
{
  strcpy(&((format++)->COLUMN_DEF[0]), "Row_id        		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Catalog_name 		VARCHAR(128) character set UTF8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Schema_name 		VARCHAR(128) character set UTF8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Object_name 		VARCHAR(128) character set UTF8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Entry_size    		INT");
  return SP_SUCCESS;
}

// Copies information on the NATable cache by the interface provided in
// NATable.h and processes it
SP_STATUS NATableCacheEntriesStoredProcedure::sp_Process(SP_PROCESS_ACTION action,
						       SP_ROW_DATA  inputData ,
						       SP_EXTRACT_FUNCPTR  eFunc ,
						       SP_ROW_DATA outputData ,
						       SP_FORMAT_FUNCPTR fFunc,
						       SP_KEY_VALUE,
						       SP_KEYVALUE_FUNCPTR,
						       SP_PROCESS_HANDLE* spProcHandle,
						       SP_HANDLE /* spHandle */,
						       SP_ERROR_STRUCT*  error )
{

  if (action == SP_PROC_OPEN) {
  
    NATableCacheEntriesISPIterator * it = new (GetCliGlobals()->exCollHeap()) 
      NATableCacheEntriesISPIterator(inputData, eFunc, error,
                                     GetCliGlobals()->currContext()->getCmpContextInfo(), 
                                     GetCliGlobals()->exCollHeap());
    *spProcHandle = it;
    return SP_SUCCESS;
  }

  if (action == SP_PROC_FETCH) {
    NATableCacheEntriesISPIterator* it = (NATableCacheEntriesISPIterator *)(*spProcHandle);

    if (!it) {
      return SP_FAIL;
    }

    NATableEntryDetails details;
    if(!it->getNext(details))
       return SP_SUCCESS;

    fFunc(0,outputData, sizeof(it->rowid()), &(it->rowid()), 0);
    fFunc(1,outputData,(Lng32)strlen(details.catalog),(void*)(details.catalog),1);
    fFunc(2,outputData,(Lng32)strlen(details.schema),(void*)(details.schema),1);
    fFunc(3,outputData,(Lng32)strlen(details.object),(void*)(details.object),1);
    fFunc(4,outputData,(Lng32)sizeof(details.size),  (void*)(&details.size),0);

    return SP_MOREDATA;
  }

  
  if (action == SP_PROC_CLOSE) {
    if (*spProcHandle)
      NADELETEBASIC((NATableCacheEntriesISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
    return SP_SUCCESS;
  }

  return SP_SUCCESS;
}

// Registers the NATableEntries function
void NATableCacheEntriesStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("NATABLECACHEENTRIES",
           sp_Compile,
           sp_InputFormat,
	   0,
           sp_NumOutputFields,
           sp_OutputFormat,
	   sp_Process,
	   0,
	   CMPISPVERSION);
}

//-----------------------------------------------------------------------
// NATableCacheDeleteStoredProcedure is a class that contains functions used
// to delete the contents of the  NATableCache virtual table. The delete 
// function is implemented as an internal stored procedure.
//-----------------------------------------------------------------------


SP_STATUS NATableCacheDeleteStoredProcedure::sp_Process(
  SP_PROCESS_ACTION action,
  SP_ROW_DATA inputData,
  SP_EXTRACT_FUNCPTR eFunc,
  SP_ROW_DATA outputData,
  SP_FORMAT_FUNCPTR fFunc,
  SP_KEY_VALUE keys,
  SP_KEYVALUE_FUNCPTR kFunc,
  SP_PROCESS_HANDLE *spProcHandle,
  SP_HANDLE spObj,
  SP_ERROR_STRUCT *error)
{
  SP_STATUS status = SP_SUCCESS;
  NATableDB * tableDB = NULL;

  switch (action)
  {
  case SP_PROC_OPEN:
    // No inputs to process
    break;

  case SP_PROC_FETCH:
    tableDB = ActiveSchemaDB()->getNATableDB();

    //clear out NATableCache
    tableDB->setCachingOFF();
    tableDB->setCachingON();
    break;

  case SP_PROC_CLOSE:
    break;
  }
  return status;
}

void NATableCacheDeleteStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("NATABLECACHEDELETE",
          sp_Compile,
          sp_InputFormat,
          0,
          sp_NumOutputFields,
          sp_OutputFormat,
          sp_Process,
          0,
	  CMPISPVERSION);
}


NATableCacheStatsISPIterator::NATableCacheStatsISPIterator(
     SP_ROW_DATA  inputData, SP_EXTRACT_FUNCPTR  eFunc, 
     SP_ERROR_STRUCT* error, const NAArray<CmpContextInfo*> & ctxs, 
     CollHeap * h)
: ISPIterator(ctxs, h)
{
    initializeISPCaches(inputData, eFunc, error, ctxs, 
                        contextName_, currCacheIndex_);
}


NABoolean NATableCacheStatsISPIterator::getNext(NATableCacheStats & stats)
{
   //Only for remote tdm_arkcmp with 0 context
   if(currCacheIndex_ == -1)
   {
     const char *cName = "ARKCMP";

     ActiveSchemaDB()->getNATableDB()->getCacheStats(stats);
     memset(stats.contextType, ' ', sizeof(stats.contextType));
     memcpy(stats.contextType, cName, MINOF(sizeof(stats.contextType), strlen(cName)));
     currCacheIndex_ = -2;
     return TRUE;
   }
   
   //fetch QueryCaches of all CmpContexts with name equal to contextName_
   if(currCacheIndex_ > -1 && currCacheIndex_ < ctxInfos_.entries())
   {
      if( !ctxInfos_[currCacheIndex_]->isSameClass(contextName_.data()) //current context name is not equal to contextName_
       && contextName_.compareTo("ALL", NAString::exact)!=0) //and contextName_ is not "ALL"
      {// go to next context in ctxInfos_
          currCacheIndex_++;
          return getNext(stats);
      }
      ctxInfos_[currCacheIndex_]->getCmpContext()->getSchemaDB()->getNATableDB()->getCacheStats(stats);
      const char *cName = ctxInfos_[currCacheIndex_++]->getName();

      memset(stats.contextType, ' ', sizeof(stats.contextType));
      memcpy(stats.contextType, cName, MINOF(sizeof(stats.contextType), strlen(cName)));
      return TRUE;
   }
   //all entries of all caches are fetched, we are done!
   return FALSE;
}


NATableCacheEntriesISPIterator::NATableCacheEntriesISPIterator(
     SP_ROW_DATA  inputData, SP_EXTRACT_FUNCPTR  eFunc, 
     SP_ERROR_STRUCT* error, const NAArray<CmpContextInfo*> & ctxs, 
     CollHeap * h)
: ISPIterator(ctxs, h)
{
    initializeISPCaches(inputData, eFunc, error, ctxs, 
                        contextName_, currCacheIndex_);
    counter_ = 0;
    rowid_ = 0;
}


NABoolean NATableCacheEntriesISPIterator::getNext(NATableEntryDetails & details)
{
  NATableDB* currNATableDB ;
   //Only for remote tdm_arkcmp with 0 context
   if(currCacheIndex_ == -1)
   {
     currNATableDB = ActiveSchemaDB()->getNATableDB();
     if (currNATableDB->empty() || currNATableDB->end() == counter_)
       return FALSE;
     currNATableDB->getEntryDetails(counter_, details);
     counter_++;
     rowid_++;
     return TRUE;
   }
   
   //fetch QueryCaches of all CmpContexts with name equal to contextName_
   while(currCacheIndex_ > -1 && currCacheIndex_ < ctxInfos_.entries())
   {
      if( !ctxInfos_[currCacheIndex_]->isSameClass(contextName_.data()) //current context name is not equal to contextName_
       && contextName_.compareTo("ALL", NAString::exact)!=0) //and contextName_ is not "ALL"
      {// go to next context in ctxInfos_
          currCacheIndex_++;
          return getNext(details);
      }
      currNATableDB = ctxInfos_[currCacheIndex_]->getCmpContext()->getSchemaDB()->getNATableDB();
      if (currNATableDB->empty() || currNATableDB->end() == counter_)
      {
        currCacheIndex_++;
        counter_ = 0;
        continue;
      }
      currNATableDB->getEntryDetails(counter_, details);
      counter_++;
      rowid_++;
      return TRUE;
   }
   //all entries of all caches are fetched, we are done!
   return FALSE;
}

