diff --git a/src/connection.cpp b/src/connection.cpp index e0d0b8c..437fec5 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -283,22 +283,6 @@ int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, ExecuteBaton case OutParam::OCCIBLOB: stmt->registerOutParam(index, oracle::occi::OCCIBLOB); break; - case OutParam::OCCIVECTOR: - // OCCIVECTOR is supported only as an IN param. - if(!outParam->_inOut.hasInParam) { - ostringstream oss; - oss << "SetValuesOnStatement: Unknown OutParam type: " << outParamType; - baton->error = new std::string(oss.str()); - return -2; - } - - //if (outParam->_inOut.collectionValues == NULL) - //throw NodeOracleException("OutParam::OCCIVECTOR has empty collection"); - - stmt->setDatabaseNCHARParam(index, true); - stmt->setDataBufferArray(index, outParam->_inOut.collectionValues, outParam->_inOut.elemetnsType, outParam->_inOut.collectionLength, - &outParam->_inOut.collectionLength, outParam->_inOut.elementsSize, outParam->_inOut.elementLength, NULL, NULL); - break; default: { ostringstream oss; @@ -527,8 +511,6 @@ void Connection::ExecuteStatement(ExecuteBaton* baton, oracle::occi::Statement* break; case OutParam::OCCINUMBER: output->numberVal = stmt->getNumber(output->index); - break; - case OutParam::OCCIVECTOR: break; default: { @@ -863,10 +845,6 @@ void Connection::handleResult(ExecuteBaton* baton, Handle (&argv)[2]) { case OutParam::OCCINUMBER: obj->Set(String::New(returnParam.c_str()), Number::New(output->numberVal)); break; - case OutParam::OCCIVECTOR: - //in vector - obj->Set(String::New(returnParam.c_str()), String::New("in OCCIVECTOR was here")); - break; default: { ostringstream oss; diff --git a/src/executeBaton.cpp b/src/executeBaton.cpp index c3726cb..358302c 100644 --- a/src/executeBaton.cpp +++ b/src/executeBaton.cpp @@ -45,6 +45,16 @@ void ExecuteBaton::ResetValues() { case VALUE_TYPE_TIMESTAMP: delete (oracle::occi::Timestamp*)val->value; break; + case VALUE_TYPE_ARRAY: + if (val->value != NULL && val->elemetnsType == oracle::occi::OCCI_SQLT_STR) + delete (char*)val->value; + else if (val->value != NULL && val->elemetnsType == oracle::occi::OCCI_SQLT_NUM) + delete (char*)val->value; + + if (val->elementLength != NULL) + delete val->elementLength; + + break; } delete val; } @@ -236,8 +246,12 @@ void ExecuteBaton::GetVectorParam(ExecuteBaton* baton, value_t *value, LocalIsNumber()) { - // Allocate memory and copy the ints. - double* intArr = new double[arr->Length()]; + value->elemetnsType = oracle::occi::OCCI_SQLT_NUM; + + // Allocate memory for the numbers array, Number in Oracle is 21 bytes + unsigned char* numArr = new unsigned char[arr->Length() * 21]; + value->elementLength = new ub2[arr->Length()]; + for(unsigned int i = 0; i < arr->Length(); i++) { Local currVal = arr->Get(i); if(!currVal->IsNumber()) { @@ -247,13 +261,25 @@ void ExecuteBaton::GetVectorParam(ExecuteBaton* baton, value_t *value, LocalToNumber()->Value(); + // JS numbers can exceed oracle numbers, make sure this is not the case. + double d = currVal->ToNumber()->Value(); + if (d > 9.99999999999999999999999999999999999999*std::pow(10, 125) || d < -9.99999999999999999999999999999999999999*std::pow(10, 125)) { + std::ostringstream message; + message << "Input array has number that is out of the range of Oracle numbers, check the number at index " << i; + baton->error = new std::string(message.str()); + return; + } + + // Convert the JS number into Oracle Number and get its bytes representation + oracle::occi::Number n = d; + oracle::occi::Bytes b = n.toBytes(); + value->elementLength[i] = b.length (); + b.getBytes(&numArr[i*21], b.length()); } - value->value = intArr; + value->value = numArr; value->collectionLength = arr->Length(); - value->elementsSize = sizeof(double); - value->elemetnsType = oracle::occi::OCCIFLOAT; + value->elementsSize = 21; } // Unsupported type