From fea5141a8e2dc9bc62889a7d814109877e68ac80 Mon Sep 17 00:00:00 2001
From: mochizk
Date: Fri, 29 Mar 2019 11:27:34 +0900
Subject: [PATCH 1/6] Add utility function
---
src/Util.cpp | 31 +++++++++++++++++++++++++++++++
src/Util.h | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
create mode 100644 src/Util.cpp
create mode 100644 src/Util.h
diff --git a/src/Util.cpp b/src/Util.cpp
new file mode 100644
index 0000000..8adacba
--- /dev/null
+++ b/src/Util.cpp
@@ -0,0 +1,31 @@
+/*
+ Copyright (c) 2017 TOSHIBA Digital Solutions Corporation.
+
+ Licensed 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.
+*/
+
+#include "Util.h"
+
+namespace griddb {
+
+ /**
+ * @brief Allocate new memory and setup string data from source string data for the new memory
+ * @param **to A pointer variable that refers to new string data
+ * @param *from A pointer stores source string data
+ */
+ void Util::strdup(const GSChar** const to, const GSChar* from) {
+ GSChar* temp = new char[strlen(from) + 1]();
+ strcpy(temp, from);
+ *to = temp;
+ }
+}
diff --git a/src/Util.h b/src/Util.h
new file mode 100644
index 0000000..5217469
--- /dev/null
+++ b/src/Util.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2017 TOSHIBA Digital Solutions Corporation.
+
+ Licensed 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.
+*/
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include
+#include "GSException.h"
+
+using namespace std;
+
+namespace griddb {
+
+class Util {
+ public:
+ static void strdup(const GSChar** const to, const GSChar* from);
+};
+
+}
+
+#endif
\ No newline at end of file
From 4ffa90525d5c867f2aa3f58de86e254d6ba340e8 Mon Sep 17 00:00:00 2001
From: mochizk
Date: Fri, 29 Mar 2019 11:28:04 +0900
Subject: [PATCH 2/6] Move Field class implementation from header file to cpp
file
---
src/Field.cpp | 106 ++++++++++++++++++++++++++++++++++++++++
src/Field.h | 133 +++-----------------------------------------------
2 files changed, 112 insertions(+), 127 deletions(-)
create mode 100644 src/Field.cpp
diff --git a/src/Field.cpp b/src/Field.cpp
new file mode 100644
index 0000000..365e416
--- /dev/null
+++ b/src/Field.cpp
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2017 TOSHIBA Digital Solutions Corporation.
+
+ Licensed 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.
+*/
+
+#include "Field.h"
+
+namespace griddb {
+
+ /**
+ * @brief Constructor a new Field:: Field object
+ */
+ Field::Field() : type(GS_TYPE_STRING) {
+ memset(&value, 0, sizeof(GSValue));
+ };
+
+ Field::~Field() {
+ switch (type) {
+ case GS_TYPE_STRING:
+ if (value.asString) {
+ delete [] value.asString;
+ value.asString = NULL;
+ }
+ break;
+ case GS_TYPE_BLOB:
+ if (value.asBlob.data) {
+ delete [] value.asBlob.data;
+ value.asBlob.data = NULL;
+ }
+ break;
+ case GS_TYPE_INTEGER_ARRAY:
+ if (value.asArray.elements.asInteger) {
+ delete [] value.asArray.elements.asInteger;
+ value.asArray.elements.asInteger = NULL;
+ }
+ break;
+ case GS_TYPE_STRING_ARRAY:
+ if (value.asArray.elements.asString) {
+ for (int j = 0; j < value.asArray.length; j++) {
+ if (value.asArray.elements.asString[j]) {
+ delete [] value.asArray.elements.asString[j];
+ }
+ }
+ delete [] value.asArray.elements.asString;
+ value.asArray.elements.asString = NULL;
+ }
+ break;
+ case GS_TYPE_BOOL_ARRAY:
+ if (value.asArray.elements.asBool) {
+ delete [] value.asArray.elements.asBool;
+ value.asArray.elements.asBool = NULL;
+ }
+ break;
+ case GS_TYPE_BYTE_ARRAY:
+ if (value.asArray.elements.asByte) {
+ delete [] value.asArray.elements.asByte;
+ value.asArray.elements.asByte = NULL;
+ }
+ break;
+ case GS_TYPE_SHORT_ARRAY:
+ if (value.asArray.elements.asShort) {
+ delete [] value.asArray.elements.asShort;
+ value.asArray.elements.asShort = NULL;
+ }
+ break;
+ case GS_TYPE_LONG_ARRAY:
+ if (value.asArray.elements.asLong) {
+ delete [] value.asArray.elements.asLong;
+ value.asArray.elements.asLong = NULL;
+ }
+ break;
+ case GS_TYPE_FLOAT_ARRAY:
+ if (value.asArray.elements.asFloat) {
+ delete [] value.asArray.elements.asFloat;
+ value.asArray.elements.asFloat = NULL;
+ }
+ break;
+ case GS_TYPE_DOUBLE_ARRAY:
+ if (value.asArray.elements.asDouble) {
+ delete [] value.asArray.elements.asDouble;
+ value.asArray.elements.asDouble = NULL;
+ }
+ break;
+ case GS_TYPE_TIMESTAMP_ARRAY:
+ if (value.asArray.elements.asTimestamp) {
+ delete [] value.asArray.elements.asTimestamp;
+ value.asArray.elements.asTimestamp = NULL;
+ }
+ break;
+ default:
+ //not need to free allocation
+ break;
+ }
+ }
+}
diff --git a/src/Field.h b/src/Field.h
index b921e0b..15e3f36 100644
--- a/src/Field.h
+++ b/src/Field.h
@@ -26,133 +26,12 @@ using namespace std;
namespace griddb {
-struct Field {
- GSType type;
- GSValue value;
- Field() : type(GS_TYPE_STRING) {
- memset(&value, 0, sizeof(GSValue));
- };
-
- ~Field() {
- switch (type) {
- case GS_TYPE_STRING:
- if (value.asString) {
- free(const_cast(value.asString));
- }
- break;
- case GS_TYPE_BLOB:
- if (value.asBlob.data) {
- free(const_cast(value.asBlob.data));
- }
- break;
-#if GS_COMPATIBILITY_VALUE_1_1_106
- case GS_TYPE_INTEGER_ARRAY:
- if (value.asIntegerArray.elements) {
- free(const_cast (value.asIntegerArray.elements));
- }
- break;
- case GS_TYPE_STRING_ARRAY:
- if (value.asStringArray.elements) {
- for (int j = 0; j < value.asStringArray.size; j++) {
- if (value.asStringArray.elements[j]) {
- free(const_cast (value.asStringArray.elements[j]));
- }
- }
- free(const_cast (value.asStringArray.elements));
- }
- break;
- case GS_TYPE_BOOL_ARRAY:
- if (value.asBoolArray.elements) {
- free(const_cast (value.asBoolArray.elements));
- }
- break;
- case GS_TYPE_BYTE_ARRAY:
- if (value.asByteArray.elements) {
- free(const_cast (value.asByteArray.elements));
- }
- break;
- case GS_TYPE_SHORT_ARRAY:
- if (value.asShortArray.elements) {
- free(const_cast (value.asShortArray.elements));
- }
- break;
- case GS_TYPE_LONG_ARRAY:
- if (value.asLongArray.elements) {
- free(const_cast (value.asLongArray.elements));
- }
- break;
- case GS_TYPE_FLOAT_ARRAY:
- if (value.asFloatArray.elements) {
- free(const_cast (value.asFloatArray.elements));
- }
- break;
- case GS_TYPE_DOUBLE_ARRAY:
- if (value.asDoubleArray.elements) {
- free(const_cast (value.asDoubleArray.elements));
- }
- break;
- case GS_TYPE_TIMESTAMP_ARRAY:
- if (value.asTimestampArray.elements) {
- free(const_cast (value.asTimestampArray.elements));
- }
- break;
-#else
- case GS_TYPE_INTEGER_ARRAY:
- if (value.asArray.elements.asInteger) {
- free(const_cast (value.asArray.elements.asInteger));
- }
- break;
- case GS_TYPE_STRING_ARRAY:
- if (value.asArray.elements.asString) {
- for (int j = 0; j < value.asArray.length; j++) {
- if (value.asArray.elements.asString[j]) {
- free(const_cast (value.asArray.elements.asString[j]));
- }
- }
- free(const_cast (value.asArray.elements.asString));
- }
- break;
- case GS_TYPE_BOOL_ARRAY:
- if (value.asArray.elements.asBool) {
- free(const_cast (value.asArray.elements.asBool));
- }
- break;
- case GS_TYPE_BYTE_ARRAY:
- if (value.asArray.elements.asByte) {
- free(const_cast (value.asArray.elements.asByte));
- }
- break;
- case GS_TYPE_SHORT_ARRAY:
- if (value.asArray.elements.asShort) {
- free(const_cast (value.asArray.elements.asShort));
- }
- break;
- case GS_TYPE_LONG_ARRAY:
- if (value.asArray.elements.asLong) {
- free(const_cast (value.asArray.elements.asLong));
- }
- break;
- case GS_TYPE_FLOAT_ARRAY:
- if (value.asArray.elements.asFloat) {
- free(const_cast (value.asArray.elements.asFloat));
- }
- break;
- case GS_TYPE_DOUBLE_ARRAY:
- if (value.asArray.elements.asDouble) {
- free(const_cast (value.asArray.elements.asDouble));
- }
- break;
- case GS_TYPE_TIMESTAMP_ARRAY:
- if (value.asArray.elements.asTimestamp) {
- free(const_cast (value.asArray.elements.asTimestamp));
- }
- break;
-#endif
- default:
- //not need to free allocation
- break;
- }
- }
+class Field {
+ public:
+ GSType type;
+ GSValue value;
+ Field();
+ ~Field();
};
}
From af26e3b76921dc8db88654b56d3f6b0d732fbfb9 Mon Sep 17 00:00:00 2001
From: mochizk
Date: Fri, 29 Mar 2019 11:31:41 +0900
Subject: [PATCH 3/6] Store error info of C client in exception constructor
---
src/GSException.h | 173 ++++++++++++++++++++++++++++++++--------------
1 file changed, 121 insertions(+), 52 deletions(-)
diff --git a/src/GSException.h b/src/GSException.h
index f388ccc..e06d457 100644
--- a/src/GSException.h
+++ b/src/GSException.h
@@ -25,6 +25,7 @@
using namespace std;
#define DEFAULT_ERROR_CODE -1
+#define DEFAULT_ERROR_STACK_SIZE 1
namespace griddb {
@@ -38,65 +39,54 @@ class GSException : public exception {
string mMessage;
void *mResource;
+ bool hasInnerError;
+ size_t mInnerErrStackSize;
+ GSResult* mInnerErrCodeStack;
+ string* mInnerMessagesStack;
+ string* mInnerErrorLocationStack;
+
public:
- GSException(int32_t code) : exception(), mCode(code), mResource(NULL) {
- mMessage = "Error with number " + to_string((long long int)mCode);
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
- mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
- mIsTimeout = false;
- }
- }
GSException(const char* message) : exception(),
mCode(DEFAULT_ERROR_CODE), mMessage(message), mResource(NULL) {
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
- mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
- mIsTimeout = false;
- }
+ hasInnerError = false;
+ mInnerErrStackSize = 0;
+ mInnerErrCodeStack = NULL;
+ mInnerMessagesStack = NULL;
+ mInnerErrorLocationStack = NULL;
+ mIsTimeout = false;
}
GSException(void *resource, const char* message) : exception(),
mCode(DEFAULT_ERROR_CODE), mMessage(message), mResource(resource) {
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
- mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
- mIsTimeout = false;
- }
+ hasInnerError = false;
+ mInnerErrStackSize = 0;
+ mInnerErrCodeStack = NULL;
+ mInnerMessagesStack = NULL;
+ mInnerErrorLocationStack = NULL;
+ mIsTimeout = false;
}
GSException(void *resource, int32_t code) : exception(),
mCode(code), mResource(resource) {
mMessage = "Error with number " + to_string((long long int)mCode);
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
- mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
- mIsTimeout = false;
- }
- }
- GSException(int32_t code, const char* message) : exception(),
- mCode(code), mMessage(message), mResource(NULL) {
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
+ if (mCode != DEFAULT_ERROR_CODE && mResource != NULL) {
+ //Case exception with error code from c layer
mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
- mIsTimeout = false;
- }
- }
- GSException(void *resource, int32_t code, const char* message) : exception(),
- mCode(code), mMessage(message), mResource(resource) {
- if (mCode != DEFAULT_ERROR_CODE) {
- //Case exception with error code.
- mIsTimeout = gsIsTimeoutError(mCode);
- }
- else {
+ // Store error stack
+ hasInnerError = true;
+ mInnerErrStackSize = get_error_stack_size_from_lower_layer();
+ mInnerErrCodeStack = new GSResult[mInnerErrStackSize]();
+ mInnerMessagesStack = new string[mInnerErrStackSize]();
+ mInnerErrorLocationStack = new string[mInnerErrStackSize]();
+ for (int i = 0; i < mInnerErrStackSize; i++) {
+ mInnerErrCodeStack[i] = get_error_code_from_lower_layer(i);
+ mInnerMessagesStack[i] = get_message_from_lower_layer(i);
+ mInnerErrorLocationStack[i] = get_location_from_lower_layer(i);
+ }
+ } else {
+ hasInnerError = false;
+ mInnerErrStackSize = 0;
+ mInnerErrCodeStack = NULL;
+ mInnerMessagesStack = NULL;
+ mInnerErrorLocationStack = NULL;
mIsTimeout = false;
}
}
@@ -105,8 +95,42 @@ class GSException : public exception {
mIsTimeout = exception->mIsTimeout;
mMessage = exception->mMessage;
mResource = exception->mResource;
+ hasInnerError = exception->hasInnerError;
+ if (hasInnerError == true) {
+ mInnerErrStackSize = exception->mInnerErrStackSize;
+ mInnerErrCodeStack = new GSResult[mInnerErrStackSize]();
+ mInnerMessagesStack = new string[mInnerErrStackSize]();
+ mInnerErrorLocationStack = new string[mInnerErrStackSize]();
+ for (int i = 0; i < mInnerErrStackSize; i++) {
+ mInnerErrCodeStack[i] = exception->mInnerErrCodeStack[i];
+ mInnerMessagesStack[i] = exception->mInnerMessagesStack[i];
+ mInnerErrorLocationStack[i] = exception->mInnerErrorLocationStack[i];
+ }
+ } else {
+ mInnerErrStackSize = 0;
+ mInnerErrCodeStack = NULL;
+ mInnerMessagesStack = NULL;
+ mInnerErrorLocationStack = NULL;
+ }
+ }
+ ~GSException() throw() {
+ close();
+ }
+
+ void close() {
+ if (mInnerErrCodeStack != NULL) {
+ delete[] mInnerErrCodeStack;
+ mInnerErrCodeStack = NULL;
+ }
+ if (mInnerMessagesStack != NULL) {
+ delete[] mInnerMessagesStack;
+ mInnerMessagesStack = NULL;
+ }
+ if (mInnerErrorLocationStack != NULL) {
+ delete[] mInnerErrorLocationStack;
+ mInnerErrorLocationStack = NULL;
+ }
}
- ~GSException() throw() {}
int32_t get_code() {
return mCode;
}
@@ -123,18 +147,63 @@ class GSException : public exception {
* Get error stack size. Convert from C-API: gsGetErrorStackSize.
*/
size_t get_error_stack_size() {
- return gsGetErrorStackSize(mResource);
+ if (hasInnerError == false) {
+ return DEFAULT_ERROR_STACK_SIZE;
+ }
+ return mInnerErrStackSize;
}
/**
* Get error code. Convert from C-API: gsGetErrorCode.
*/
GSResult get_error_code(size_t stack_index) {
- return gsGetErrorCode(mResource, stack_index);
+ if (hasInnerError == false) {
+ if (stack_index == 0) return mCode;
+ return 0;
+ } else {
+ if (stack_index >= mInnerErrStackSize) return 0;
+ return mInnerErrCodeStack[stack_index];
+ }
}
/**
* Get error message. Convert from C-API: gsFormatErrorMessage.
*/
string get_message(size_t stack_index, size_t buf_size = 1024) {
+ if (hasInnerError == false) {
+ if (stack_index == 0) return mMessage;
+ return "";
+ } else {
+ if (stack_index >= mInnerErrStackSize) return "";
+ return mInnerMessagesStack[stack_index];
+ }
+ }
+ /**
+ * Get error location. Convert from C-API: gsFormatErrorLocation.
+ */
+ string get_location(size_t stack_index, size_t buf_size = 1024) {
+ if (hasInnerError == false) {
+ return "";
+ } else {
+ if (stack_index >= mInnerErrStackSize) return "";
+ return mInnerErrorLocationStack[stack_index];
+ }
+ }
+ private:
+ /**
+ * Get error stack size. Convert from C-API: gsGetErrorStackSize.
+ */
+ size_t get_error_stack_size_from_lower_layer() {
+ return gsGetErrorStackSize(mResource);
+ }
+ /**
+ * Get error code. Convert from C-API: gsGetErrorCode.
+ */
+ GSResult get_error_code_from_lower_layer(size_t stack_index) {
+ return gsGetErrorCode(mResource, stack_index);
+ }
+ /**
+ * Get error message. Convert from C-API: gsFormatErrorMessage.
+ */
+ string get_message_from_lower_layer(size_t stack_index, size_t buf_size = 1024) {
char* strBuf = new char[buf_size];
size_t stringSize = gsFormatErrorMessage(mResource, stack_index, strBuf, buf_size);
string ret(strBuf, stringSize);
@@ -144,7 +213,7 @@ class GSException : public exception {
/**
* Get error location. Convert from C-API: gsFormatErrorLocation.
*/
- string get_location(size_t stack_index, size_t buf_size = 1024) {
+ string get_location_from_lower_layer(size_t stack_index, size_t buf_size = 1024) {
char* strBuf = new char[buf_size];
size_t stringSize = gsFormatErrorLocation(mResource, stack_index, strBuf, buf_size);
string ret(strBuf, stringSize);
From 7a0cb00069c137bd953ee68ed2ab2fca21779d83 Mon Sep 17 00:00:00 2001
From: mochizk
Date: Fri, 29 Mar 2019 11:34:08 +0900
Subject: [PATCH 4/6] Refactor and fix bugs of cpp files
---
src/AggregationResult.cpp | 12 +-
src/AggregationResult.h | 3 +-
src/Container.cpp | 227 +++++++++++++++++++-----------
src/Container.h | 6 +-
src/ContainerInfo.cpp | 265 ++++++++++++++++++++++++-----------
src/ContainerInfo.h | 3 +
src/EnumValue.h | 8 +-
src/PartitionController.cpp | 40 ++++--
src/PartitionController.h | 2 +-
src/Query.cpp | 78 +++++++----
src/Query.h | 2 +
src/QueryAnalysisEntry.cpp | 128 +++++++++++------
src/QueryAnalysisEntry.h | 2 +
src/RowKeyPredicate.cpp | 149 ++++++++++++++------
src/RowKeyPredicate.h | 2 +
src/RowSet.cpp | 130 ++++++++++++-----
src/RowSet.h | 2 +
src/Store.cpp | 184 ++++++++++++++++++------
src/Store.h | 1 +
src/StoreFactory.cpp | 85 +++++++----
src/StoreFactory.h | 2 +-
src/TimeSeriesProperties.cpp | 51 +++++--
22 files changed, 964 insertions(+), 418 deletions(-)
diff --git a/src/AggregationResult.cpp b/src/AggregationResult.cpp
index d34c1c6..ad8b2c0 100644
--- a/src/AggregationResult.cpp
+++ b/src/AggregationResult.cpp
@@ -18,6 +18,10 @@
namespace griddb {
+ /**
+ * @brief Constructor a new Aggregation Result:: Aggregation Result object
+ * @param aggResult Stores the result of an aggregation operation
+ */
AggregationResult::AggregationResult(GSAggregationResult* aggResult) :
mAggResult(aggResult), timestamp_output_with_float(false) {
}
@@ -27,7 +31,7 @@ namespace griddb {
}
/**
- * Release AggregationResult resource
+ * @brief Release AggregationResult resource
*/
void AggregationResult::close() {
if (mAggResult != NULL) {
@@ -37,9 +41,12 @@ namespace griddb {
}
/**
- * Obtains the result of aggregating numeric-type values.
+ * @brief Obtains the result of aggregating numeric-type values.
+ * @param type Column type
+ * @param *agValue aggregation result
*/
void AggregationResult::get(GSType type, griddb::Field *agValue) {
+ assert(agValue != NULL);
void *value;
agValue->type = type;
switch (type) {
@@ -62,4 +69,5 @@ namespace griddb {
"Value cannot be retrieved from Aggregation result");
}
}
+
} /* namespace griddb */
diff --git a/src/AggregationResult.h b/src/AggregationResult.h
index c0bcaec..3db594f 100644
--- a/src/AggregationResult.h
+++ b/src/AggregationResult.h
@@ -17,6 +17,8 @@
#ifndef _AGGREGATIONRESULT_H_
#define _AGGREGATIONRESULT_H_
+#include
+
#include "GSException.h"
#include "Field.h"
#include "gridstore.h"
@@ -35,7 +37,6 @@ class AggregationResult {
bool timestamp_output_with_float;
~AggregationResult();
void close();
-
void get(GSType type, griddb::Field *agValue);
AggregationResult(GSAggregationResult* aggResult);
diff --git a/src/Container.cpp b/src/Container.cpp
index 864f86f..8bdc1c0 100644
--- a/src/Container.cpp
+++ b/src/Container.cpp
@@ -1,4 +1,4 @@
-/*
+ /*
Copyright (c) 2017 TOSHIBA Digital Solutions Corporation.
Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,155 +16,192 @@
#include "Container.h"
+#include
+
namespace griddb {
Container::Container(GSContainer *container, GSContainerInfo* containerInfo) : mContainer(container),
mContainerInfo(NULL), mRow(NULL), mTypeList(NULL), timestamp_output_with_float(false) {
+ assert(container != NULL);
+ assert(containerInfo != NULL);
GSResult ret = gsCreateRowByContainer(mContainer, &mRow);
- if (ret != GS_RESULT_OK) {
- throw GSException(ret, "can not create row from Container");
+ if (!GS_SUCCEEDED(ret)) {
+ throw GSException(mContainer, ret);
}
+ GSColumnInfo* columnInfoList;
//create local mContainerInfo: there is issue from C-API about using share memory that
// make GSContainerInfo* pointer error in case : create gsRow, get GSContainerInfo from gsRow, set field of gs Row
- mContainerInfo = (GSContainerInfo*) malloc(sizeof(GSContainerInfo));
- (*mContainerInfo) = (*containerInfo); // this is for set for normal data (int, float, double..)
- GSColumnInfo* columnInfoList = (GSColumnInfo *) malloc(sizeof (GSColumnInfo) * containerInfo->columnCount);
- for (int i = 0; i < containerInfo->columnCount; i++) {
- columnInfoList[i].type = containerInfo->columnInfoList[i].type;
- if (containerInfo->columnInfoList[i].name) {
- columnInfoList[i].name = strdup(containerInfo->columnInfoList[i].name);
- } else {
- columnInfoList[i].name = NULL;
+ try {
+ mContainerInfo = new GSContainerInfo();
+ (*mContainerInfo) = (*containerInfo); // this is for set for normal data (int, float, double..)
+ mContainerInfo->name = NULL;
+ if (containerInfo->name) {
+ Util::strdup(&(mContainerInfo->name), containerInfo->name);
}
-#if GS_COMPATIBILITY_SUPPORT_1_5
- columnInfoList[i].indexTypeFlags = containerInfo->columnInfoList[i].indexTypeFlags;
-#if GS_COMPATIBILITY_SUPPORT_3_5
- columnInfoList[i].options = containerInfo->columnInfoList[i].options;
-#endif
-#endif
- }
- mContainerInfo->name = NULL;
- if (containerInfo->name) {
- mContainerInfo->name = strdup(containerInfo->name);
+
+ columnInfoList = new GSColumnInfo[containerInfo->columnCount]();
+ mContainerInfo->columnInfoList = columnInfoList;
+
+ for (int i = 0; i < containerInfo->columnCount; i++) {
+ columnInfoList[i].type = containerInfo->columnInfoList[i].type;
+ if (containerInfo->columnInfoList[i].name) {
+ Util::strdup(&(columnInfoList[i].name), containerInfo->columnInfoList[i].name);
+ } else {
+ columnInfoList[i].name = NULL;
+ }
+
+ columnInfoList[i].indexTypeFlags = containerInfo->columnInfoList[i].indexTypeFlags;
+ columnInfoList[i].options = containerInfo->columnInfoList[i].options;
+ }
+
+ mTypeList = new GSType[mContainerInfo->columnCount]();
+ } catch (bad_alloc& ba) {
+ //Memory allocation error
+ freeMemoryContainer();
+ throw GSException(mContainer, "Memory allocation error");
}
- mContainerInfo->columnInfoList = columnInfoList;
+
mContainerInfo->timeSeriesProperties = NULL;
mContainerInfo->triggerInfoList = NULL;
mContainerInfo->dataAffinity = NULL;
- mTypeList = (GSType*) malloc(sizeof(GSType) * mContainerInfo->columnCount);
- for (int i = 0; i < mContainerInfo->columnCount; i++){
- mTypeList[i] = mContainerInfo->columnInfoList[i].type;
+
+ if (mTypeList && mContainerInfo->columnInfoList) {
+ for (int i = 0; i < mContainerInfo->columnCount; i++){
+ mTypeList[i] = mContainerInfo->columnInfoList[i].type;
+ }
}
}
Container::~Container() {
- gsCloseRow(&mRow);
+
// allRelated = FALSE, since all row object is managed by Row class
close(GS_FALSE);
+ }
+ void Container::freeMemoryContainer() {
if (mContainerInfo) {
for (int i = 0; i < mContainerInfo->columnCount; i++) {
- free((void*)mContainerInfo->columnInfoList[i].name);
+ if (mContainerInfo->columnInfoList && mContainerInfo->columnInfoList[i].name) {
+ delete[] mContainerInfo->columnInfoList[i].name;
+ }
}
- free((void*) mContainerInfo->columnInfoList);
- free((void*) mContainerInfo->name);
- free((void*) mContainerInfo);
+ if (mContainerInfo->columnInfoList) {
+ delete[] mContainerInfo->columnInfoList;
+ }
+ if (mContainerInfo->name) {
+ delete[] mContainerInfo->name;
+ }
+ delete mContainerInfo;
+ mContainerInfo = NULL;
+ }
+ if (mTypeList) {
+ delete[] mTypeList;
+ mTypeList = NULL;
}
- free((void*) mTypeList);
}
/**
- * Close container.
+ * @brief Release Container resource
+ * @param allRelated Indicates whether all unclosed resources in the lower resources related to the specified GSContainer will be closed or not
*/
void Container::close(GSBool allRelated) {
+ if (mRow != NULL) {
+ gsCloseRow(&mRow);
+ mRow = NULL;
+ }
+
//Release container and all related resources
if (mContainer != NULL) {
gsCloseContainer(&mContainer, allRelated);
mContainer = NULL;
}
+ freeMemoryContainer();
}
/**
- * Removes the specified type of index among indexes on the specified Column.
+ * @brief Removes the specified type of index among indexes on the specified Column
+ * @param *column_name Column name
+ * @param index_type Flag value which shows index classification
+ * @param *name Index name
*/
void Container::drop_index(const char* column_name, GSIndexTypeFlags index_type, const char *name) {
GSResult ret = GS_RESULT_OK;
-#if GS_COMPATIBILITY_SUPPORT_3_5
+
if (name) {
GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER;
indexInfo.name = name;
indexInfo.type = index_type;
indexInfo.columnName = column_name;
ret = gsDropIndexDetail(mContainer, &indexInfo);
- }
- else {
+ } else {
ret = gsDropIndex(mContainer, column_name, index_type);
}
-#else
- ret = gsDropIndex(mContainer, column_name, index_type);
-#endif
- if (ret != GS_RESULT_OK) {
+
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
- /*
- * Creates a specified type of index on the specified Column.
+ /**
+ * @brief Creates a specified type of index on the specified Column
+ * @param *column_name Column name
+ * @param index_type Flag value which shows index classification
+ * @param *name Index name
*/
void Container::create_index(const char *column_name, GSIndexTypeFlags index_type, const char *name) {
GSResult ret = GS_RESULT_OK;
-#if GS_COMPATIBILITY_SUPPORT_3_5
+
if (name){
GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER;
indexInfo.name = name;
indexInfo.type = index_type;
indexInfo.columnName = column_name;
ret = gsCreateIndexDetail(mContainer, &indexInfo);
- }
- else {
+ } else {
ret = gsCreateIndex(mContainer, column_name, index_type);
}
-#else
- ret = gsCreateIndex(mContainer, column_name, index_type);
-#endif
- if (ret != GS_RESULT_OK) {
+
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Writes the results of earlier updates to a non-volatile storage medium, such as SSD, so as to prevent the data from being lost even if all cluster nodes stop suddenly.
+ * @brief Writes the results of earlier updates to a non-volatile storage medium, such as SSD, so as to prevent the data from being lost even if all cluster nodes stop suddenly.
*/
void Container::flush() {
GSResult ret = gsFlush(mContainer);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Put row to database.
+ * @brief Put row to database.
+ * @param *row A Row object representing the content of a Row to be put to database
+ * @return Return bool value to indicate row exist or not
*/
- bool Container::put(GSRow *rowContainer) {
+ bool Container::put(GSRow *row) {
GSBool bExists;
GSResult ret = gsPutRow(mContainer, NULL, mRow, &bExists);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
return bExists;
}
/**
- * Get current container type
+ * @brief Get current container type
+ * @return Return container type
*/
GSContainerType Container::get_type() {
GSContainerType containerType;
GSResult ret = gsGetContainerType(mContainer, &containerType);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
@@ -172,56 +209,69 @@ namespace griddb {
}
/**
- * Rolls back the result of the current transaction and starts a new transaction in the manual commit mode.
+ * @brief Rolls back the result of the current transaction and starts a new transaction in the manual commit mode.
*/
void Container::abort() {
GSResult ret = gsAbort(mContainer);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Create query from input string.
+ * @brief Create query from input string.
+ * @param *query TQL statement
+ * @return Return a Query object
*/
Query* Container::query(const char* query) {
GSQuery *pQuery;
GSResult ret = gsQuery(mContainer, query, &pQuery);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
- return new Query(pQuery, mContainerInfo, mRow);
+ try {
+ Query* queryObj = new Query(pQuery, mContainerInfo, mRow);
+ return queryObj;
+ } catch(bad_alloc& ba) {
+ gsCloseQuery(&pQuery);
+ throw GSException(mContainer, "Memory allocation error");
+ }
}
/**
- * Set auto commit to true or false.
+ * @brief Set auto commit to true or false.
+ * @param enabled Indicates whether container enables auto commit mode or not
*/
void Container::set_auto_commit(bool enabled){
GSBool gsEnabled;
gsEnabled = (enabled == true ? GS_TRUE:GS_FALSE);
GSResult ret = gsSetAutoCommit(mContainer, gsEnabled);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Commit changes to database when autocommit is set to false.
+ * @brief Commit changes to database when autocommit is set to false.
*/
void Container::commit() {
GSResult ret = gsCommit(mContainer);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Returns the content of a Row.
+ * @brief Returns the content of a Row.
+ * @param *keyFields The variable to store the target Row key
+ * @param *rowdata The Row object to store the contents of target Row to be obtained
+ * @return Return bool value to indicate row exist or not
*/
GSBool Container::get(Field* keyFields, GSRow *rowdata) {
+ assert(keyFields != NULL);
GSBool exists;
GSResult ret;
void *key = NULL;
@@ -234,7 +284,7 @@ namespace griddb {
break;
case GS_TYPE_INTEGER:
if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) {
- throw GSException("wrong type of rowKey");
+ throw GSException("wrong type of rowKey integer");
}
key = &keyFields->value.asInteger;
break;
@@ -246,7 +296,7 @@ namespace griddb {
break;
case GS_TYPE_TIMESTAMP:
if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) {
- throw GSException("wrong type of rowKey");
+ throw GSException("wrong type of rowKey timestamp");
}
key = &keyFields->value.asTimestamp;
break;
@@ -255,24 +305,26 @@ namespace griddb {
}
ret = gsGetRow(mContainer, key, mRow, &exists);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
return exists;
}
- /*
- * Deletes a Row corresponding to Row key
+ /**
+ * @brief Deletes a Row corresponding to Row key
+ * @param *keyFields The variable to store the target Row key
+ * @return Return bool value to indicate row exist or not
*/
bool Container::remove(Field* keyFields) {
+ assert(keyFields != NULL);
GSBool exists = GS_FALSE;
GSResult ret;
-#if GS_COMPATIBILITY_SUPPORT_3_5
+
if (keyFields->type == GS_TYPE_NULL) {
ret = gsDeleteRow(mContainer, NULL, &exists);
} else {
-#endif
switch (keyFields->type) {
case GS_TYPE_STRING:
if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) {
@@ -282,7 +334,7 @@ namespace griddb {
break;
case GS_TYPE_INTEGER:
if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) {
- throw GSException("wrong type of rowKey");
+ throw GSException("wrong type of rowKey integer");
}
ret = gsDeleteRow(mContainer, &keyFields->value.asInteger, &exists);
break;
@@ -294,18 +346,16 @@ namespace griddb {
break;
case GS_TYPE_TIMESTAMP:
if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) {
- throw GSException("wrong type of rowKey");
+ throw GSException("wrong type of rowKey timestamp");
}
ret = gsDeleteRow(mContainer, &keyFields->value.asTimestamp, &exists);
break;
default:
throw GSException("wrong type of rowKey field");
}
-#if GS_COMPATIBILITY_SUPPORT_3_5
}
-#endif
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
@@ -313,7 +363,9 @@ namespace griddb {
}
/**
- * Multiput data
+ * @brief Put multi row data to database
+ * @param **listRowdata The array of row to be put to data base
+ * @param rowCount The number of row to be put to database
*/
void Container::multi_put(GSRow** listRowdata, int rowCount) {
GSResult ret;
@@ -321,31 +373,38 @@ namespace griddb {
//data for each container
ret = gsPutMultipleRows(mContainer, (const void * const *) listRowdata,
rowCount, &bExists);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mContainer, ret);
}
}
/**
- * Support Store::multi_put
+ * @brief Get GSContainer of Container object to support Store::multi_put
+ * @return Return a pointer which store GSContainer of container
*/
GSContainer* Container::getGSContainerPtr(){
return mContainer;
}
/**
- * Support put row
+ * @brief Get GSType of Container object to support put row
+ * @return Return a pointer which store type the list of column of row in container
*/
GSType* Container::getGSTypeList(){
return mTypeList;
}
+ /**
+ * @brief Get GSRow of Container object to support put row
+ * @return Return a pointer which store GSRow of container
+ */
GSRow* Container::getGSRowPtr(){
return mRow;
}
/**
- * Support put row
+ * @brief Get number of column of row in container
+ * @return Return number of column of row in container
*/
int Container::getColumnCount(){
return mContainerInfo->columnCount;
diff --git a/src/Container.h b/src/Container.h
index 783fab0..74f7f47 100644
--- a/src/Container.h
+++ b/src/Container.h
@@ -17,9 +17,12 @@
#ifndef _CONTAINER_H_
#define _CONTAINER_H_
+#include
+
#include "Field.h"
#include "Query.h"
#include "GSException.h"
+#include "Util.h"
using namespace std;
@@ -42,7 +45,7 @@ class Container {
GSContainerType get_type();
void create_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT, const char* name=NULL);
void drop_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT, const char* name=NULL);
- bool put(GSRow *rowContainer);
+ bool put(GSRow *row);
Query* query(const char *query);
void abort();
void flush();
@@ -58,6 +61,7 @@ class Container {
private:
Container(GSContainer *container, GSContainerInfo* containerInfo);
+ void freeMemoryContainer();
};
} /* namespace griddb */
diff --git a/src/ContainerInfo.cpp b/src/ContainerInfo.cpp
index cb1fcb0..7fd2ba4 100644
--- a/src/ContainerInfo.cpp
+++ b/src/ContainerInfo.cpp
@@ -18,36 +18,73 @@
namespace griddb {
+ /**
+ * @brief Constructor a new ContainerInfo::ContainerInfo object
+ * @param *containerInfo Stores the information about a specific Container
+ */
ContainerInfo::ContainerInfo(GSContainerInfo *containerInfo) {
+ assert(containerInfo != NULL);
init(containerInfo->name, containerInfo->type,
containerInfo->columnInfoList, containerInfo->columnCount,
containerInfo->rowKeyAssigned, NULL);
//Assign values from argument to mContainer
GSTimeSeriesProperties* gsProps = NULL;
+ GSTriggerInfo* triggerInfoList = NULL;
+
+ try {
+ if (containerInfo->timeSeriesProperties) {
+ gsProps = new GSTimeSeriesProperties();
+ }
+
+ if (containerInfo->triggerInfoList) {
+ triggerInfoList = new GSTriggerInfo();
+ }
+
+ if (containerInfo->dataAffinity) {
+ Util::strdup(&mContainerInfo.dataAffinity, containerInfo->dataAffinity);
+ } else {
+ mContainerInfo.dataAffinity = NULL;
+ }
+ } catch (bad_alloc& ba) {
+ //case allocation memory error
+ if (gsProps) {
+ delete gsProps;
+ }
+ if (triggerInfoList) {
+ delete triggerInfoList;
+ }
+ if (mContainerInfo.dataAffinity) {
+ delete[] mContainerInfo.dataAffinity;
+ }
+ throw GSException("Memory allocation error");
+ }
+
if (containerInfo->timeSeriesProperties) {
- gsProps = (GSTimeSeriesProperties*) malloc(sizeof(GSTimeSeriesProperties));
memcpy(gsProps, containerInfo->timeSeriesProperties, sizeof(GSTimeSeriesProperties));
}
mContainerInfo.timeSeriesProperties = gsProps;
- GSTriggerInfo* triggerInfoList = NULL;
+
if (containerInfo->triggerInfoList) {
- triggerInfoList = (GSTriggerInfo*) malloc(sizeof(GSTriggerInfo));
memcpy(triggerInfoList, containerInfo->triggerInfoList, sizeof(GSTriggerInfo));
}
+
mContainerInfo.triggerInfoList = triggerInfoList;
-#if GS_COMPATIBILITY_SUPPORT_2_1
- if (containerInfo->dataAffinity) {
- mContainerInfo.dataAffinity = strdup(containerInfo->dataAffinity);
- } else {
- mContainerInfo.dataAffinity = NULL;
- }
-#endif
+
mContainerInfo.columnOrderIgnorable = containerInfo->columnOrderIgnorable;
mContainerInfo.triggerInfoCount = containerInfo->triggerInfoCount;
mColumnInfoList.columnInfo = NULL;
mColumnInfoList.size = 0;
}
+ /**
+ * @brief Constructor a new ContainerInfo::ContainerInfo object
+ * @param *name The name of Container
+ * @param *props Stores the information about the schema of a Column
+ * @param propsCount Number of columns
+ * @param type The type of Container
+ * @param row_key The boolean value indicating whether the Row key Column is assigned
+ * @param *expiration Stores the information about option of TimeSeries configuration
+ */
ContainerInfo::ContainerInfo(const GSChar* name, const GSColumnInfo* props, int propsCount,
GSContainerType type, bool row_key, ExpirationInfo* expiration) {
init(name, type, props, propsCount, row_key, expiration);
@@ -63,30 +100,51 @@ namespace griddb {
GSChar* containerName = NULL;
GSTimeSeriesProperties* timeProps = NULL;
- if (propsCount > 0 && props != NULL) {
- columnInfoList = (GSColumnInfo *) malloc(propsCount*sizeof(GSColumnInfo));
- //Copy memory of GSColumnInfo list
- memcpy(columnInfoList, props, propsCount*sizeof(GSColumnInfo));
- //Copy memory of columns name
- for (int i = 0; i < propsCount; i++) {
- if (props[i].name != NULL) {
- columnInfoList[i].name = strdup(props[i].name);
- } else {
- columnInfoList[i].name = NULL;
+ try {
+ if (propsCount > 0 && props != NULL) {
+ columnInfoList = new GSColumnInfo[propsCount]();
+ //Copy memory of GSColumnInfo list
+ memcpy(columnInfoList, props, propsCount*sizeof(GSColumnInfo));
+ //Copy memory of columns name
+ for (int i = 0; i < propsCount; i++) {
+ if (props[i].name != NULL) {
+ Util::strdup(&(columnInfoList[i].name), props[i].name);
+ } else {
+ columnInfoList[i].name = NULL;
+ }
}
}
+
+ if (expiration != NULL) {
+ timeProps = new GSTimeSeriesProperties();
+ }
+
+ //Container name memory is copied via strdup function
+ if (name != NULL) {
+ Util::strdup((const GSChar**)&containerName, name);
+ }
+ } catch (bad_alloc& ba) {
+ if (columnInfoList) {
+ for (int i = 0; i < propsCount; i++) {
+ if (columnInfoList[i].name) {
+ delete[] columnInfoList[i].name;
+ }
+ }
+ delete[] columnInfoList;
+ }
+ if (containerName) {
+ delete[] containerName;
+ }
+ if (timeProps) {
+ delete timeProps;
+ }
+ throw GSException("Memory allocation error");
}
if (expiration != NULL) {
- timeProps = (GSTimeSeriesProperties*) malloc(sizeof(GSTimeSeriesProperties));
memcpy(timeProps, expiration->gs_ts(), sizeof(GSTimeSeriesProperties));
}
- //Container name memory is copied via strdup function
- if (name != NULL) {
- containerName = strdup(name);
- }
-
mContainerInfo = {containerName, type, (size_t)propsCount, columnInfoList, rowKeyAssigned};
if (timeProps != NULL) {
mContainerInfo.timeSeriesProperties = timeProps;
@@ -99,7 +157,7 @@ namespace griddb {
ContainerInfo::~ContainerInfo() {
//Free memory for the copy of container name
if (mContainerInfo.name) {
- free((void*) mContainerInfo.name);
+ delete[] mContainerInfo.name;
}
//Free memory for the copy of ColumnInfo list
@@ -107,122 +165,160 @@ namespace griddb {
//Free memory of columns name
for(int i = 0; i < mContainerInfo.columnCount; i++) {
if(mContainerInfo.columnInfoList[i].name) {
- free((void *) mContainerInfo.columnInfoList[i].name);
+ delete[] mContainerInfo.columnInfoList[i].name;
}
}
- free((void *) mContainerInfo.columnInfoList);
+ delete[] mContainerInfo.columnInfoList;
}
//Free memory of TimeSeriesProperties if existed
if (mContainerInfo.timeSeriesProperties) {
- free((void *) mContainerInfo.timeSeriesProperties);
+ delete mContainerInfo.timeSeriesProperties;
}
//Free memory of dataAffinity if existed
-#if GS_COMPATIBILITY_SUPPORT_2_1
if (mContainerInfo.dataAffinity) {
- free((void *) mContainerInfo.dataAffinity);
+ delete[] mContainerInfo.dataAffinity;
}
-#endif
+
//Free memory of triggerInfoList if existed
if(mContainerInfo.triggerInfoList) {
- free((void *) mContainerInfo.triggerInfoList);
+ delete mContainerInfo.triggerInfoList;
}
if (mExpInfo != NULL) {
delete mExpInfo;
}
}
- /*
- * Set attribute: mContainerInfo.name
+
+ /**
+ * @brief Set name of Container which is stored in ContainerInfo
+ * @param *containerName Stores the name of Container
*/
void ContainerInfo::set_name(GSChar* containerName) {
if (mContainerInfo.name) {
- free((void*) mContainerInfo.name);
+ delete[] mContainerInfo.name;
}
if (containerName == NULL) {
mContainerInfo.name = NULL;
} else {
- mContainerInfo.name = strdup(containerName);
+ try {
+ Util::strdup(&(mContainerInfo.name), containerName);
+ } catch (bad_alloc& ba) {
+ throw GSException("Memory allocation error");
+ }
}
}
- /*
- * Set attribute: mContainerInfo.type
+
+ /**
+ * @brief Set type of Container which is stored in ContainerInfo
+ * @param containerType The type of Container
*/
void ContainerInfo::set_type(GSContainerType containerType) {
mContainerInfo.type = containerType;
}
- /*
- * Set attribute: mContainerInfo.rowKeyAssigned
+
+ /**
+ * @brief Set rowKeyAssigned for ContainerInfo
+ * @param rowKeyAssigned The boolean value indicating whether the Row key Column is assigned
*/
void ContainerInfo::set_row_key_assigned(bool rowKeyAssigned) {
mContainerInfo.rowKeyAssigned = rowKeyAssigned;
}
- /*
- * Get attribute: mContainerInfo.name
+
+ /**
+ * @brief Get name of Container which is stored in ContainerInfo
+ * @return The name of Container
*/
const GSChar* ContainerInfo::get_name() {
return mContainerInfo.name;
}
- /*
- * Get attribute: mContainerInfo.type
+
+ /**
+ * @brief Get type of Container which is stored in ContainerInfo
+ * @return The type of Container
*/
GSContainerType ContainerInfo::get_type() {
return mContainerInfo.type;
}
- /*
- * Get attribute: mContainerInfo.columnInfoList
+
+ /**
+ * @brief Get columnInfo which is stored in ContainerInfo
+ * @param column The number of column
+ * @return The information of column which is stored in ContainerInfo
*/
GSColumnInfo ContainerInfo::get_column_info(size_t column) {
+ if (column >= mContainerInfo.columnCount) {
+ throw GSException("Index out of bound error");
+ }
return mContainerInfo.columnInfoList[column];
}
- /*
- * Get attribute: mContainerInfo.rowKeyAssigned
+
+ /**
+ * @brief Get rowKeyAssigned value of ContainerInfo
+ * @return The boolean value indicating whether the Row key Column is assigned
*/
bool ContainerInfo::get_row_key_assigned() {
return mContainerInfo.rowKeyAssigned;
}
/**
- * Return GSContainerInfo variable
+ * @brief Get all information of Container
+ * @return A pointer which store all information of Container
*/
GSContainerInfo* ContainerInfo::gs_info() {
return &mContainerInfo;
}
/**
- * Set attribute :column_info_list
+ * @brief Set information of column stored in ContainerInfo
+ * @param columnInfoList A struct which store information of column
*/
void ContainerInfo::set_column_info_list(ColumnInfoList columnInfoList) {
//Free current stored ColumnInfo list
if (mContainerInfo.columnInfoList) {
//Free memory of columns name
for(int i = 0; i < mContainerInfo.columnCount; i++) {
- free((void *) mContainerInfo.columnInfoList[i].name);
+ delete[] mContainerInfo.columnInfoList[i].name;
}
- free((void*) mContainerInfo.columnInfoList);
+ delete[] mContainerInfo.columnInfoList;
}
- //Copy memory of new ColumnInfo list
- GSColumnInfo* tmpColumnInfoList = NULL;
- if (columnInfoList.size > 0 && columnInfoList.columnInfo != NULL) {
- tmpColumnInfoList = (GSColumnInfo *) malloc(columnInfoList.size*sizeof(GSColumnInfo));
- //Copy memory of GSColumnInfo list
- memcpy(tmpColumnInfoList, columnInfoList.columnInfo, columnInfoList.size*sizeof(GSColumnInfo));
- //Copy memory of columns name
- for (int i = 0; i < columnInfoList.size; i++) {
- if (columnInfoList.columnInfo[i].name) {
- tmpColumnInfoList[i].name = strdup(columnInfoList.columnInfo[i].name);
- } else {
- tmpColumnInfoList[i].name = NULL;
+ mContainerInfo.columnCount = columnInfoList.size;
+ mContainerInfo.columnInfoList = NULL;
+
+ if (columnInfoList.size == 0 || columnInfoList.columnInfo == NULL) {
+ return;
+ }
+
+ GSColumnInfo* tmpColumnInfoList;
+ try {
+ tmpColumnInfoList = new GSColumnInfo[columnInfoList.size]();
+ } catch (bad_alloc& ba) {
+ throw GSException("Memory allocation error");
+ }
+
+ //Copy memory of GSColumnInfo list
+ memcpy(tmpColumnInfoList, columnInfoList.columnInfo, columnInfoList.size*sizeof(GSColumnInfo));
+ //Copy memory of columns name
+ for (int i = 0; i < columnInfoList.size; i++) {
+ if (columnInfoList.columnInfo[i].name) {
+ try {
+ Util::strdup(&(tmpColumnInfoList[i].name), columnInfoList.columnInfo[i].name);
+ } catch (bad_alloc& ba) {
+ delete[] tmpColumnInfoList;
+ tmpColumnInfoList = NULL;
+ throw GSException("Memory allocation error");
}
+ } else {
+ tmpColumnInfoList[i].name = NULL;
}
}
mContainerInfo.columnInfoList = tmpColumnInfoList;
- mContainerInfo.columnCount = columnInfoList.size;
}
/**
- * Get attribute :column_info_list
+ * @brief Get information of column stored in ContainerInfo
+ * @return A struct which store information of column
*/
ColumnInfoList ContainerInfo::get_column_info_list() {
mColumnInfoList.columnInfo = (GSColumnInfo*) mContainerInfo.columnInfoList;
@@ -230,25 +326,32 @@ namespace griddb {
return mColumnInfoList;
}
- /*
- * Set attribute: expiration
+ /**
+ * @brief Set expirationInfo for timeseries container which is stored in ContainerInfo
+ * @param *expirationInfo A ExpirationInfo object which store the information about optional configuration settings used for newly creating or updating a TimeSeries
*/
void ContainerInfo::set_expiration_info(ExpirationInfo* expirationInfo) {
-#if GS_COMPATIBILITY_SUPPORT_1_5
if (mContainerInfo.timeSeriesProperties != NULL) {
- free((void*) mContainerInfo.timeSeriesProperties);
+ delete mContainerInfo.timeSeriesProperties;
+ mContainerInfo.timeSeriesProperties = NULL;
}
if (expirationInfo) {
- GSTimeSeriesProperties* ts = (GSTimeSeriesProperties*) malloc(sizeof(GSTimeSeriesProperties));
+ GSTimeSeriesProperties* ts;
+ try {
+ ts = new GSTimeSeriesProperties();
+ } catch (bad_alloc& ba) {
+ throw GSException("Memory allocation error");
+ }
+
memcpy(ts, expirationInfo->gs_ts(), sizeof(GSTimeSeriesProperties));
mContainerInfo.timeSeriesProperties = ts;
}
-#endif
}
- /*
- * Get attribute: expiration
+ /**
+ * @brief Get expirationInfo for timeseries container which is stored in ContainerInfo
+ * @return A ExpirationInfo object which store the information about optional configuration settings used for newly creating or updating a TimeSeries
*/
ExpirationInfo* ContainerInfo::get_expiration_info() {
if (mContainerInfo.timeSeriesProperties != NULL){
@@ -257,9 +360,13 @@ namespace griddb {
mExpInfo->set_time_unit(mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit);
mExpInfo->set_division_count(mContainerInfo.timeSeriesProperties->expirationDivisionCount);
} else {
- mExpInfo = new ExpirationInfo(mContainerInfo.timeSeriesProperties->rowExpirationTime,
- mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit,
- mContainerInfo.timeSeriesProperties->expirationDivisionCount);
+ try {
+ mExpInfo = new ExpirationInfo(mContainerInfo.timeSeriesProperties->rowExpirationTime,
+ mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit,
+ mContainerInfo.timeSeriesProperties->expirationDivisionCount);
+ } catch (bad_alloc& ba) {
+ throw GSException("Memory allocation error");
+ }
}
} else {
mExpInfo = NULL;
diff --git a/src/ContainerInfo.h b/src/ContainerInfo.h
index af4bd57..045a249 100644
--- a/src/ContainerInfo.h
+++ b/src/ContainerInfo.h
@@ -20,9 +20,12 @@
#include
#include
#include
+#include
+
#include "TimeSeriesProperties.h"
#include "ExpirationInfo.h"
#include "GSException.h"
+#include "Util.h"
//Support column_info_list attribute
struct ColumnInfoList {
diff --git a/src/EnumValue.h b/src/EnumValue.h
index 237ca00..dfbffbd 100644
--- a/src/EnumValue.h
+++ b/src/EnumValue.h
@@ -45,7 +45,6 @@ class RowSetType {
class FetchOption {
public:
static const int LIMIT = 0;
-#if GS_COMPATIBILITY_SUPPORT_1_5
#if GS_INTERNAL_DEFINITION_VISIBLE
#if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE
@@ -56,8 +55,6 @@ class FetchOption {
#if GS_COMPATIBILITY_SUPPORT_4_0
static const int PARTIAL_EXECUTION = (LIMIT + 2);
#endif
-
-#endif
};
// Represents the time unit(s) used in TimeSeries data operation.
class TimeUnit {
@@ -93,10 +90,9 @@ class Type {
static const int FLOAT_ARRAY = 17;
static const int DOUBLE_ARRAY = 18;
static const int TIMESTAMP_ARRAY = 19;
-#if GS_COMPATIBILITY_SUPPORT_3_5
- // Can't use NULL because it is keyword of C language
+
+ // Can't use NULL because it is keyword of C language
static const int NULL_TYPE = -1;
-#endif
};
// Sum of bits of value of the flag indicating the option setting for Column.
class TypeOption {
diff --git a/src/PartitionController.cpp b/src/PartitionController.cpp
index 7cf9a44..639b0fc 100644
--- a/src/PartitionController.cpp
+++ b/src/PartitionController.cpp
@@ -18,49 +18,69 @@
namespace griddb {
+ /**
+ * @brief Constructor a new PartitionController::PartitionController object
+ * @param *controller A pointer for acquiring and processing the partition status
+ */
PartitionController::PartitionController(GSPartitionController *controller) :
mController(controller) {
}
+
/**
- * Destructor. Convert from C-API:gsClosePartitionController
+ * @brief Destructor to free resources for a PartitionController object
*/
PartitionController::~PartitionController() {
close();
}
+
+ /**
+ * @brief Release PartitionController resource
+ */
void PartitionController::close() {
if (mController != NULL) {
gsClosePartitionController(&mController);
mController = NULL;
}
}
+
/**
- * Get partition count. Convert from C-Api: gsGetPartitionCount
+ * @brief Get partition count
+ * @return The number of partitions in the target GridDB cluster
*/
int32_t PartitionController::get_partition_count() {
int32_t value;
GSResult ret = gsGetPartitionCount(mController, &value);
// Check ret, if error, throw exception
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mController, ret);
}
return value;
}
+
/**
- * Get container partition count. Convert from C-Api: gsGetPartitionContainerCount
+ * @brief Get container partition count
+ * @param partition_index The partition index, from 0 to the number of partitions minus one
+ * @return The number of Container
*/
int64_t PartitionController::get_container_count(int32_t partition_index) {
int64_t value;
GSResult ret = gsGetPartitionContainerCount(mController, partition_index, &value);
// Check ret, if error, throw exception
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mController, ret);
}
return value;
}
+
/**
- * Get list partition container names case there is limit. Convert from C-Api: gsGetPartitionContainerNames
+ * @brief Get a list of the Container names belonging to a specified partition.
+ * @param partition_index The partition index, from 0 to the number of partitions minus one
+ * @param start The start position of the acquisition range. A value must be greater than or equal to 0
+ * @param ***stringList The pointer to a pointer variable to store the array list of Container name
+ * @param *size The pointer to a variable to store the number of array elements of the Container name list
+ * @param limit The upper limit of the number of cases acquired
*/
void PartitionController::get_container_names(int32_t partition_index, int64_t start,
const GSChar * const ** stringList, size_t *size, int64_t limit) {
@@ -72,20 +92,22 @@ namespace griddb {
}
GSResult ret = gsGetPartitionContainerNames(mController, partition_index, start, limitPtr, stringList, size);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mController, ret);
}
}
/**
- * Get get_partition index of container. Convert from C-Api: gsGetPartitionIndexOfContainer
+ * @brief Get the partition index corresponding to the specified Container name.
+ * @param *container_name Container name
+ * @return The partition index
*/
int32_t PartitionController::get_partition_index_of_container(const GSChar* container_name) {
int32_t value;
GSResult ret = gsGetPartitionIndexOfContainer(mController, container_name, &value);
// Check ret, if error, throw exception
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mController, ret);
}
return value;
diff --git a/src/PartitionController.h b/src/PartitionController.h
index 6945e3a..cead4d5 100644
--- a/src/PartitionController.h
+++ b/src/PartitionController.h
@@ -34,7 +34,7 @@ class PartitionController {
int32_t get_partition_count();
int64_t get_container_count(int32_t partition_index);
void get_container_names(int32_t partition_index, int64_t start,
- const GSChar * const ** stringList, size_t *size, int64_t limit = -1);
+ const GSChar * const ** stringList , size_t *size , int64_t limit = -1);
int32_t get_partition_index_of_container(const GSChar *container_name);
private:
diff --git a/src/Query.cpp b/src/Query.cpp
index 10bae12..da07678 100644
--- a/src/Query.cpp
+++ b/src/Query.cpp
@@ -18,14 +18,22 @@
namespace griddb {
+ /**
+ * @brief Constructor a new Query::Query object
+ * @param *query A pointer holding the information about a query related to a specific GSContainer
+ * @param *containerInfo A pointer holding the information about a specific GSContainer
+ * @param *gsRow A pointer holding the information about a row related to a specific GSContainer
+ */
Query::Query(GSQuery *query, GSContainerInfo *containerInfo, GSRow *gsRow) : mQuery(query),
mContainerInfo(containerInfo), mRow(gsRow) {
}
+
Query::~Query() {
close();
}
+
/**
- * Release all resources created by this Query object.
+ * @brief Release Query resource
*/
void Query::close() {
if (mQuery) {
@@ -33,65 +41,79 @@ namespace griddb {
mQuery = NULL;
}
}
+
/**
- * Fetch data from query result.
+ * @brief Fetch data from query result.
+ * @param for_update Indicates whether it requests a lock for update or not
+ * @return The pointer to a pointer variable to store GSRowSet instance
*/
RowSet* Query::fetch(bool for_update) {
- GSRowSet *rowSet;
+ GSRowSet *gsRowSet;
// Call method from C-Api.
GSBool gsForUpdate = (for_update == true ? GS_TRUE:GS_FALSE);
- GSResult ret = gsFetch(mQuery, gsForUpdate, &rowSet);
+ GSResult ret = gsFetch(mQuery, gsForUpdate, &gsRowSet);
// Check ret, if error, throw exception
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mQuery, ret);
}
- return new RowSet(rowSet, mContainerInfo, mRow);
+ try {
+ RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow);
+ return rowset;
+ } catch (bad_alloc& ba) {
+ gsCloseRowSet(&gsRowSet);
+ throw GSException(mQuery, "Memory allocation error");
+ }
}
+
/**
- * Get row set. Convert from C-Api: gsGetRowSet
+ * @brief Get row set.
+ * @return The pointer to a pointer variable to store GSRowSet instance
*/
RowSet* Query::get_row_set() {
- GSRowSet *rowSet;
- GSResult ret = gsGetRowSet(mQuery, &rowSet);
+ GSRowSet *gsRowSet;
+ GSResult ret = gsGetRowSet(mQuery, &gsRowSet);
// Check ret, if error, throw exception
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mQuery, ret);
}
- return new RowSet(rowSet, mContainerInfo, mRow);
+ try {
+ RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow);
+ return rowset;
+ } catch (bad_alloc& ba) {
+ gsCloseRowSet(&gsRowSet);
+ throw GSException(mQuery, "Memory allocation error");
+ }
}
/**
- * Get raw pointer of GSQuery
+ * @brief Get raw pointer of GSQuery
+ * @return A pointer store raw pointer of GSQuery
*/
GSQuery* Query::gs_ptr() {
return mQuery;
}
+
/**
- * Set fetch limit option
+ * @brief Set fetch limit option for a result acquisition.
+ * @param limit The maximum number of Rows to be fetched.
+ * @param partial The option value for GSFetchOption
*/
void Query::set_fetch_options(int limit, bool partial){
- GSFetchOption fetchOption;
GSResult ret;
- if (limit >= 0) {
- fetchOption = GS_FETCH_LIMIT;
- ret = gsSetFetchOption(mQuery, fetchOption, &limit, GS_TYPE_INTEGER);
- if (ret != GS_RESULT_OK) {
- throw GSException(mQuery, ret);
- }
+ ret = gsSetFetchOption(mQuery, GS_FETCH_LIMIT, &limit, GS_TYPE_INTEGER);
+ if (!GS_SUCCEEDED(ret)) {
+ throw GSException(mQuery, ret);
}
- if (partial == true) {
#if GS_COMPATIBILITY_SUPPORT_4_0
- fetchOption = GS_FETCH_PARTIAL_EXECUTION;
- //Need to call gsSetFetchOption as many as the number of options
- ret = gsSetFetchOption(mQuery, fetchOption, &partial, GS_TYPE_BOOL);
- if (ret != GS_RESULT_OK) {
- throw GSException(mQuery, ret);
- }
-#endif
+ //Need to call gsSetFetchOption as many as the number of options
+ ret = gsSetFetchOption(mQuery, GS_FETCH_PARTIAL_EXECUTION, &partial, GS_TYPE_BOOL);
+ if (!GS_SUCCEEDED(ret)) {
+ throw GSException(mQuery, ret);
}
+#endif
}
}
diff --git a/src/Query.h b/src/Query.h
index e7d180d..3500886 100644
--- a/src/Query.h
+++ b/src/Query.h
@@ -18,6 +18,7 @@
#define _QUERY_H_
#include
+
#include "gridstore.h"
#include "RowSet.h"
#include "GSException.h"
@@ -28,6 +29,7 @@ namespace griddb {
/**
* Convert from GSQuery
*/
+
class Query {
friend class Container;
private:
diff --git a/src/QueryAnalysisEntry.cpp b/src/QueryAnalysisEntry.cpp
index a3e377c..daffdf0 100644
--- a/src/QueryAnalysisEntry.cpp
+++ b/src/QueryAnalysisEntry.cpp
@@ -16,87 +16,129 @@
#include "QueryAnalysisEntry.h"
+#include
+
namespace griddb {
+ /**
+ * @brief Constructor a new QueryAnalysisEntry::QueryAnalysisEntry object
+ * @param *queryAnalysis Represents one of information entries composing a query plan and the results of analyzing a query operation.
+ */
QueryAnalysisEntry::QueryAnalysisEntry(GSQueryAnalysisEntry* queryAnalysis) : mQueryAnalysis(NULL) {
- if (queryAnalysis) {
+ if (!queryAnalysis) {
+ return;
+ }
+
+ try {
if (!mQueryAnalysis) {
- mQueryAnalysis = (GSQueryAnalysisEntry*) malloc(sizeof(GSQueryAnalysisEntry));
+ mQueryAnalysis = new GSQueryAnalysisEntry();
}
- //Copy value which queryAnalysis point to
- mQueryAnalysis->id = queryAnalysis->id;
- mQueryAnalysis->depth = queryAnalysis->depth;
+
+ mQueryAnalysis->statement = NULL;
+ mQueryAnalysis->type = NULL;
+ mQueryAnalysis->value = NULL;
+ mQueryAnalysis->valueType = NULL;
+
if (queryAnalysis->statement) {
- mQueryAnalysis->statement = strdup(queryAnalysis->statement);
- } else {
- mQueryAnalysis->statement = NULL;
+ Util::strdup(&(mQueryAnalysis->statement), queryAnalysis->statement);
}
+
if (queryAnalysis->type) {
- mQueryAnalysis->type = strdup(queryAnalysis->type);
- } else {
- mQueryAnalysis->type = NULL;
+ Util::strdup(&(mQueryAnalysis->type), queryAnalysis->type);
}
+
if (queryAnalysis->value) {
- mQueryAnalysis->value = strdup(queryAnalysis->value);
- } else {
- mQueryAnalysis->value = NULL;
+ Util::strdup(&(mQueryAnalysis->value), queryAnalysis->value);
}
+
if (queryAnalysis->valueType) {
- mQueryAnalysis->valueType = strdup(queryAnalysis->valueType);
- } else {
- mQueryAnalysis->valueType = NULL;
+ Util::strdup(&(mQueryAnalysis->valueType), queryAnalysis->valueType);
}
+ } catch (bad_alloc& ba) {
+ this->freeMemory();
+ throw GSException(mQueryAnalysis, "Memory allocation error");
}
+
+ //Copy value which queryAnalysis point to
+ mQueryAnalysis->id = queryAnalysis->id;
+ mQueryAnalysis->depth = queryAnalysis->depth;
}
QueryAnalysisEntry::~QueryAnalysisEntry() {
this->close();
}
+ /**
+ * @brief Release QueryAnalysisEntry resource
+ */
void QueryAnalysisEntry::close() {
+ this->freeMemory();
+ if (mQueryAnalysis) {
+ mQueryAnalysis = NULL;
+ }
+ }
+
+ void QueryAnalysisEntry::freeMemory() {
if (mQueryAnalysis) {
if (mQueryAnalysis->statement) {
- free((void*) mQueryAnalysis->statement);
+ delete[] mQueryAnalysis->statement;
}
if (mQueryAnalysis->type) {
- free((void*) mQueryAnalysis->type);
+ delete[] mQueryAnalysis->type;
}
if (mQueryAnalysis->value) {
- free((void*) mQueryAnalysis->value);
+ delete[] mQueryAnalysis->value;
}
if (mQueryAnalysis->valueType) {
- free((void*) mQueryAnalysis->valueType);
+ delete[] mQueryAnalysis->valueType;
}
- free((void *) mQueryAnalysis);
- mQueryAnalysis = NULL;
+ delete mQueryAnalysis;
}
}
/**
- * get QueryAnalysisEntry data
+ * @brief get QueryAnalysisEntry data
+ * @param *queryAnalysis Represents one of information entries composing a query plan and the results of analyzing a query operation.
*/
void QueryAnalysisEntry::get(GSQueryAnalysisEntry* queryAnalysis) {
+ assert(queryAnalysis != NULL);
queryAnalysis->id = mQueryAnalysis->id;
queryAnalysis->depth = mQueryAnalysis->depth;
- if (mQueryAnalysis->statement) {
- queryAnalysis->statement = strdup(mQueryAnalysis->statement);
- } else {
- queryAnalysis->statement = NULL;
- }
- if (mQueryAnalysis->type) {
- queryAnalysis->type = strdup(mQueryAnalysis->type);
- } else {
- queryAnalysis->type = NULL;
- }
- if (mQueryAnalysis->value) {
- queryAnalysis->value = strdup(mQueryAnalysis->value);
- } else {
- queryAnalysis->value = NULL;
- }
- if (mQueryAnalysis->valueType) {
- queryAnalysis->valueType = strdup(mQueryAnalysis->valueType);
- } else {
- queryAnalysis->valueType = NULL;
+ queryAnalysis->statement = NULL;
+ queryAnalysis->type = NULL;
+ queryAnalysis->value = NULL;
+ queryAnalysis->valueType = NULL;
+
+ try {
+ if (mQueryAnalysis->statement) {
+ Util::strdup(&(queryAnalysis->statement), mQueryAnalysis->statement);
+ }
+
+ if (mQueryAnalysis->type) {
+ Util::strdup(&(queryAnalysis->type), mQueryAnalysis->type);
+ }
+
+ if (mQueryAnalysis->value) {
+ Util::strdup(&(queryAnalysis->value), mQueryAnalysis->value);
+ }
+
+ if (mQueryAnalysis->valueType) {
+ Util::strdup(&(queryAnalysis->valueType), mQueryAnalysis->valueType);
+ }
+ } catch (bad_alloc& ba) {
+ if (queryAnalysis->statement) {
+ delete[] queryAnalysis->statement;
+ }
+ if (queryAnalysis->type) {
+ delete[] queryAnalysis->type;
+ }
+ if (queryAnalysis->value) {
+ delete[] queryAnalysis->value;
+ }
+ if (queryAnalysis->valueType) {
+ delete[] queryAnalysis->valueType;
+ }
+ throw GSException(mQueryAnalysis, "Memory allocation error");
}
}
}
diff --git a/src/QueryAnalysisEntry.h b/src/QueryAnalysisEntry.h
index 6925307..107839b 100644
--- a/src/QueryAnalysisEntry.h
+++ b/src/QueryAnalysisEntry.h
@@ -22,6 +22,7 @@
#include "gridstore.h"
#include "GSException.h"
+#include "Util.h"
using namespace std;
@@ -30,6 +31,7 @@ namespace griddb {
class QueryAnalysisEntry {
private:
GSQueryAnalysisEntry* mQueryAnalysis;
+ void freeMemory();
public:
QueryAnalysisEntry(GSQueryAnalysisEntry* queryAnalysis);
diff --git a/src/RowKeyPredicate.cpp b/src/RowKeyPredicate.cpp
index 5aa1120..2370426 100644
--- a/src/RowKeyPredicate.cpp
+++ b/src/RowKeyPredicate.cpp
@@ -18,17 +18,24 @@
namespace griddb {
+ /**
+ * @brief Constructor a new RowSet::RowSet object
+ * @param *predicate Represents the condition that a row key satisfies.
+ * @param type The type of Row key used as a matching condition
+ */
RowKeyPredicate::RowKeyPredicate(GSRowKeyPredicate *predicate, GSType type): mPredicate(predicate), mType(type),
timestamp_output_with_float(false){
}
+
/**
- * Destructor. Call close methods to release resource
+ * @brief Destructor to free resource of RowKeyPredicate object
*/
RowKeyPredicate::~RowKeyPredicate() {
close();
}
+
/**
- * Convert from C-API: gsCloseRowKeyPredicate
+ * @brief Release RowKeyPredicate resource
*/
void RowKeyPredicate::close() {
if (mPredicate != NULL) {
@@ -38,29 +45,39 @@ namespace griddb {
}
/**
- * Get key type. Convert from C-API: gsGetPredicateKeyType
+ * @brief Get key type
+ * @return The type of Row key used as a matching condition
*/
GSType RowKeyPredicate::get_key_type() {
return mType;
}
- /*
- * Returns the value of Row key at the start and end position of the range condition
+
+ /**
+ * @brief Get the value of Row key at the start and end position of the range condition
+ * @param *startField The pointer to a variable to store the value of the Row key at the starting position
+ * @param *finishField The pointer to a variable to store the value of the Row key at the end position
*/
void RowKeyPredicate::get_range(Field* startField, Field* finishField) {
+ assert(startField != NULL);
+ assert(finishField != NULL);
startField->type = -1; // for all versions which do not support GS_TYPE_NULL
finishField->type = -1; // for all versions which do not support GS_TYPE_NULL
GSType key_type = get_key_type();
const GSValue *startKey = NULL;
const GSValue *endKey = NULL;
GSResult ret = gsGetPredicateStartKeyGeneral(mPredicate, &startKey);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
if (startKey != NULL) {
startField->type = key_type;
if (startField->type == GS_TYPE_STRING) {
if (startKey->asString) {
- startField->value.asString = strdup(startKey->asString);
+ try {
+ Util::strdup(&(startField->value.asString), startKey->asString);
+ } catch (bad_alloc& ba) {
+ throw GSException(mPredicate, "Memory allocation error");
+ }
} else {
startField->value.asString = NULL;
}
@@ -69,9 +86,9 @@ namespace griddb {
}
}
ret = gsGetPredicateFinishKeyGeneral(mPredicate, &endKey);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
if (startField->type == GS_TYPE_STRING && startField->value.asString) {
- free((void*) startField->value.asString);
+ delete[] startField->value.asString;
}
throw GSException(mPredicate, ret);
}
@@ -79,7 +96,14 @@ namespace griddb {
finishField->type = key_type;
if (finishField->type == GS_TYPE_STRING) {
if (endKey->asString) {
- finishField->value.asString = strdup(endKey->asString);
+ try {
+ Util::strdup(&(finishField->value.asString), endKey->asString);
+ } catch (bad_alloc& ba) {
+ if (startField->type == GS_TYPE_STRING && startField->value.asString) {
+ delete[] startField->value.asString;
+ }
+ throw GSException(mPredicate, "Memory allocation error");
+ }
} else {
finishField->value.asString = NULL;
}
@@ -88,53 +112,58 @@ namespace griddb {
}
}
}
- /*
- * Sets the value of Row key as the start and end position of the range conditions
+
+ /**
+ * @brief Sets the value of Row key as the start and end position of the range conditions
+ * @param *startKey The pointer to a variable to store the value of the Row key at the starting position
+ * @param *finishKey The pointer to a variable to store the value of the Row key at the end position
*/
void RowKeyPredicate::set_range(Field* startKey, Field* finishKey) {
+ assert(startKey != NULL);
+ assert(finishKey != NULL);
GSType key_type = get_key_type();
GSResult ret;
switch (key_type) {
case GS_TYPE_LONG:
ret = gsSetPredicateStartKeyByLong(mPredicate, (int64_t*)&startKey->value.asLong);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
ret = gsSetPredicateFinishKeyByLong(mPredicate, (int64_t *) &finishKey->value.asLong);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
case GS_TYPE_INTEGER:
ret = gsSetPredicateStartKeyByInteger(mPredicate, (const int32_t *) &startKey->value.asInteger);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
ret = gsSetPredicateFinishKeyByInteger(mPredicate, (const int32_t *)&finishKey->value.asInteger);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
case GS_TYPE_STRING:
ret = gsSetPredicateStartKeyByString(mPredicate, startKey->value.asString);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
ret = gsSetPredicateFinishKeyByString(mPredicate, finishKey->value.asString);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
case GS_TYPE_TIMESTAMP:
ret = gsSetPredicateStartKeyByTimestamp(mPredicate,
(const GSTimestamp *) &(startKey->value.asTimestamp));
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
ret = gsSetPredicateFinishKeyByTimestamp(mPredicate,
(const GSTimestamp *) &(finishKey->value.asTimestamp));
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
@@ -143,38 +172,44 @@ namespace griddb {
break;
}
}
- /*
- * Adds the value of Row key as one of the elements in the individual condition
+
+ /**
+ * @brief Adds the value of Row key as one of the elements in the individual condition
+ * @param *keys The value of Row key to be added as one of the elements in the individual condition
+ * @param keyCount Number of distinct key
*/
void RowKeyPredicate::set_distinct_keys(const Field *keys, size_t keyCount) {
+ assert(keys != NULL);
GSType key_type = get_key_type();
GSResult ret;
for (size_t i = 0; i < keyCount; i++) {
const Field* key = keys + i;
+ assert(key != NULL);
switch (key_type) {
case GS_TYPE_LONG:
ret = gsAddPredicateKeyByLong(mPredicate, key->value.asLong);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
case GS_TYPE_INTEGER:
ret = gsAddPredicateKeyByInteger(mPredicate,
key->value.asInteger);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
case GS_TYPE_STRING:
ret = gsAddPredicateKeyByString(mPredicate, key->value.asString);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
+
break;
case GS_TYPE_TIMESTAMP:
ret = gsAddPredicateKeyByTimestamp(mPredicate,
key->value.asTimestamp);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mPredicate, ret);
}
break;
@@ -184,39 +219,63 @@ namespace griddb {
}
}
}
- /*
- * Returns a set of the values of the Row keys that configure the individual condition.
+
+ /**
+ * @brief Get a set of the values of the Row keys that configure the individual condition.
+ * @param **keys A pointer refers to list of Row key value
+ * @param *keyCount A pointer stores number of distinct key
*/
void RowKeyPredicate::get_distinct_keys(Field **keys, size_t* keyCount) {
+ assert(keys != NULL);
+ assert(keyCount != NULL);
+
size_t size;
GSType key_type = get_key_type();
GSValue * keyList;
GSResult ret = gsGetPredicateDistinctKeysGeneral(mPredicate, (const GSValue **)&keyList, &size);
+ if (!GS_SUCCEEDED(ret)) {
+ throw GSException(mPredicate, ret);
+ }
*keyCount = size;
- Field* keyFields = new Field[size];
- for(int i = 0; i < size; i++) {
- keyFields[i].type = key_type;
- switch(key_type) {
- case GS_TYPE_STRING:
- if (keyList[i].asString) {
- keyFields[i].value.asString = strdup(keyList[i].asString);
- } else {
- keyFields[i].value.asString = NULL;
+ Field* keyFields;
+ try {
+ keyFields = new Field[size](); //will be free in typemap out
+ for (int i = 0; i < size; i++) {
+ keyFields[i].type = key_type;
+ switch(key_type) {
+ case GS_TYPE_STRING:
+ if (keyList[i].asString) {
+ Util::strdup(&(keyFields[i].value.asString), keyList[i].asString);
+ } else {
+ keyFields[i].value.asString = NULL;
+ }
+ break;
+ default:
+ keyFields[i].value = keyList[i];
+ break;
}
- break;
- default:
- keyFields[i].value = keyList[i];
- break;
}
- }
+ *keys = keyFields;
+ } catch (bad_alloc& ba) {
+ if (keyFields) {
+ for (int i = 0; i < size; i++) {
+ if (keyFields[i].type == GS_TYPE_STRING && keyFields[i].value.asString) {
+ delete[] keyFields[i].value.asString;
+ }
+ }
+ delete[] keyFields;
+ }
- *keys = keyFields;
- if (ret != GS_RESULT_OK) {
- throw GSException(mPredicate, ret);
+ throw GSException(mPredicate, "Memory allocation error");
}
+
}
+ /**
+ * @brief Get GSRowKeyPredicate data in RowKeyPredicate object
+ * @return A pointer stores GSRowKeyPredicate data in RowKeyPredicate object
+ */
GSRowKeyPredicate* RowKeyPredicate::gs_ptr() {
return mPredicate;
}
diff --git a/src/RowKeyPredicate.h b/src/RowKeyPredicate.h
index 59876a6..0134a17 100644
--- a/src/RowKeyPredicate.h
+++ b/src/RowKeyPredicate.h
@@ -19,11 +19,13 @@
#include
#include
+#include
#include
#include "gridstore.h"
#include "Field.h"
#include "GSException.h"
+#include "Util.h"
using namespace std;
diff --git a/src/RowSet.cpp b/src/RowSet.cpp
index 6d28e9c..b0ce22e 100644
--- a/src/RowSet.cpp
+++ b/src/RowSet.cpp
@@ -18,6 +18,12 @@
namespace griddb {
+ /**
+ * @brief Constructor a new RowSet::RowSet object
+ * @param *rowSet A pointer manages a set of Rows obtained by a query
+ * @param *containerInfo A pointer holding the information about a specific GSContainer
+ * @param *gsRow A pointer holding the information about a row related to a specific GSContainer
+ */
RowSet::RowSet(GSRowSet *rowSet, GSContainerInfo *containerInfo, GSRow *gsRow) :
mRowSet(rowSet), mContainerInfo(containerInfo), mRow(gsRow),
timestamp_output_with_float(false), typeList(NULL) {
@@ -27,8 +33,10 @@ namespace griddb {
throw GSException(mRowSet, "mRowSet is NULL");
}
}
+
/**
- * Check if RowSet has next row data. Convert from gsHasNextRow.
+ * @brief Check if RowSet has next row data.
+ * @return Returns whether a Row set has at least one Row ahead of the current cursor position
*/
bool RowSet::has_next() {
GSRowSetType type;
@@ -38,55 +46,67 @@ namespace griddb {
case (GS_ROW_SET_AGGREGATION_RESULT):
case (GS_ROW_SET_QUERY_ANALYSIS):
return (bool) gsHasNextRow(mRowSet);
- break;
default:
return false;
- break;
}
}
+
RowSet::~RowSet() {
close();
if (typeList) {
- free(typeList);
+ delete[] typeList;
}
}
+
/**
- * Close rowset.
+ * @brief Release RowSet resource
*/
void RowSet::close() {
if (mRowSet != NULL) {
gsCloseRowSet(&mRowSet);
mRowSet = NULL;
}
-
}
+
/**
- * Update current row from RowSet
+ * @brief Update current row from RowSet
+ * @param *row A Row object representing the content of a Row to be put to database
*/
void RowSet::update(GSRow* row) {
GSResult ret = gsUpdateCurrentRow(mRowSet, mRow);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mRowSet, ret);
}
}
+
/**
- * Get next row data. Convert from gsGetNextRow.
+ * @brief Get next row data.
+ * @param *hasNextRow Indicate whether there is any row in RowSet or not
*/
void RowSet::next_row(bool* hasNextRow) {
*hasNextRow = this->has_next();
if (*hasNextRow) {
GSResult ret = gsGetNextRow(mRowSet, mRow);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mRowSet, ret);
}
}
}
+
/**
- * Get next row
+ * @brief Get next row or queryAnalysis or aggResult corresponding query command
+ * @param *type The type of content that can be extracted from GSRowSet.
+ * @param *hasNextRow Indicate whether there is any row in RowSet or not
+ * @param **queryAnalysis Represents one of information entries composing a query plan and the results of analyzing a query operation.
+ * @param **aggResult Stores the result of an aggregation operation.
*/
void RowSet::next(GSRowSetType* type, bool* hasNextRow,
QueryAnalysisEntry** queryAnalysis, AggregationResult** aggResult){
+ assert(type != NULL);
+ assert(hasNextRow != NULL);
+ assert(queryAnalysis != NULL);
+ assert(aggResult != NULL);
*type = this->type();
switch(*type) {
case (GS_ROW_SET_CONTAINER_ROWS):
@@ -104,81 +124,122 @@ namespace griddb {
throw GSException(mRowSet, "type for rowset is not correct");
}
}
+
/**
- * Return size of this rowset
+ * @brief Get size of this rowset
+ * @return Size of this rowset
*/
int32_t RowSet::size() {
return gsGetRowSetSize(mRowSet);
}
/**
- * Delete current row data. Convert from C-API: gsDeleteCurrentRow.
+ * @brief Delete current row data.
*/
void RowSet::remove() {
GSResult ret = gsDeleteCurrentRow(mRowSet);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mRowSet, ret);
}
}
/**
- * Moves to the next Row in a Row set and returns the aggregation result at the moved position.
+ * @brief Moves to the next Row in a Row set and returns the aggregation result at the moved position.
+ * @return A pointer Stores the result of an aggregation operation.
*/
AggregationResult* RowSet::get_next_aggregation() {
GSAggregationResult* pAggResult;
GSResult ret = gsGetNextAggregation(mRowSet, &pAggResult);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mRowSet, ret);
}
- return new AggregationResult(pAggResult);
+ try {
+ AggregationResult* aggResult = new AggregationResult(pAggResult);
+ return aggResult;
+ } catch (bad_alloc& ba) {
+ gsCloseAggregationResult(&pAggResult);
+ throw GSException(mRowSet, "Memory allocation error");
+ }
}
/**
- * Get current row type. Convert from C-API: gsGetRowSetType.
+ * @brief Get current row type.
+ * @return The type of content that can be extracted from GSRowSet.
*/
GSRowSetType RowSet::type(){
return mType;
}
/**
- * Get next query analysis
+ * @brief Get next query analysis
+ * @return Represents one of information entries composing a query plan and the results of analyzing a query operation.
*/
QueryAnalysisEntry* RowSet::get_next_query_analysis(){
- GSQueryAnalysisEntry queryAnalysis = GS_QUERY_ANALYSIS_ENTRY_INITIALIZER;
+ GSQueryAnalysisEntry gsQueryAnalysis = GS_QUERY_ANALYSIS_ENTRY_INITIALIZER;
GSResult ret;
- ret = gsGetNextQueryAnalysis(mRowSet, &queryAnalysis);
- if (ret != GS_RESULT_OK) {
+ ret = gsGetNextQueryAnalysis(mRowSet, &gsQueryAnalysis);
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mRowSet, ret);
}
- return new QueryAnalysisEntry(&queryAnalysis);
+
+ try {
+ QueryAnalysisEntry* queryAnalysis = new QueryAnalysisEntry(&gsQueryAnalysis);
+ return queryAnalysis;
+ } catch (bad_alloc& ba) {
+ throw GSException(mRowSet, "Memory allocation error");
+ }
}
/**
- * Get column name from RowSet. Use in python only.
+ * @brief Get column name from RowSet. Use in python only.
+ * @param ***listName List name of column
+ * @param *num Number of column
*/
void RowSet::get_column_names(char*** listName, int* num){
- if (mContainerInfo){
- //Memory will be free from typemap
- (*listName) = (char **) malloc(mContainerInfo->columnCount * sizeof(char*));
+ assert(listName != NULL);
+ assert(num != NULL);
+ if (!mContainerInfo){
+ return;
+ }
+
+ //Memory will be free from typemap
+ try {
+ (*listName) = new char*[mContainerInfo->columnCount]();
*num = mContainerInfo->columnCount;
for (int i = 0; i < mContainerInfo->columnCount; i++){
if (mContainerInfo->columnInfoList[i].name) {
- (*listName)[i] = strdup(mContainerInfo->columnInfoList[i].name);
+ Util::strdup((const GSChar**)(&((*listName)[i])), mContainerInfo->columnInfoList[i].name);
} else {
(*listName)[i] = NULL;
}
}
+ } catch (bad_alloc& ba) {
+ for (int i = 0; i < mContainerInfo->columnCount; i++){
+ if ((*listName)[i]) {
+ delete[] (*listName)[i];
+ }
+ }
+ if ((*listName)) {
+ delete[] (*listName);
+ }
+ throw GSException(mRowSet, "Memory allocation error");
}
}
/**
- * Support put row
+ * @brief Get list type of column in row
+ * @return A list type of column in row
*/
GSType* RowSet::getGSTypeList(){
- if (typeList == NULL){
- typeList = (GSType*) malloc(sizeof(GSType) * mContainerInfo->columnCount);
+ if (typeList == NULL) {
+ try {
+ typeList = new GSType[mContainerInfo->columnCount]();
+ } catch (bad_alloc& ba) {
+ throw GSException(mRowSet, "Memory allocation error");
+ }
+
for (int i = 0; i < mContainerInfo->columnCount; i++){
typeList[i] = mContainerInfo->columnInfoList[i].type;
}
@@ -187,12 +248,17 @@ namespace griddb {
}
/**
- * Support put row
+ * @brief Get number of column in row
+ * @return Number of column in row
*/
int RowSet::getColumnCount(){
return mContainerInfo->columnCount;
}
+ /**
+ * @brief Get row data in RowSet object
+ * @return A pointer stores row data in RowSet object
+ */
GSRow* RowSet::getGSRowPtr(){
return mRow;
}
diff --git a/src/RowSet.h b/src/RowSet.h
index 84d8286..9dad3d8 100644
--- a/src/RowSet.h
+++ b/src/RowSet.h
@@ -21,12 +21,14 @@
#include
#include
#include
+#include
#include "gridstore.h"
#include "Field.h"
#include "AggregationResult.h"
#include "QueryAnalysisEntry.h"
#include "GSException.h"
+#include "Util.h"
using namespace std;
diff --git a/src/Store.cpp b/src/Store.cpp
index e342184..b6660ba 100644
--- a/src/Store.cpp
+++ b/src/Store.cpp
@@ -18,14 +18,20 @@
namespace griddb {
+ /**
+ * @brief Constructor a new Store::Store object
+ * @param *store A pointer which provides functions to manipulate the entire data managed in one GridDB system.
+ */
Store::Store(GSGridStore *store) : mStore(store), timestamp_output_with_float(false) {
}
+
Store::~Store() {
// allRelated = FALSE, since all container object is managed by Container class
close(GS_FALSE);
}
+
/**
- * Release all resources created by this gridstore object
+ * @brief Release Store resource
*/
void Store::close(GSBool allRelated) {
// close store
@@ -34,55 +40,80 @@ namespace griddb {
mStore = NULL;
}
}
+
/**
- * Delete container with specified name
+ * @brief Delete container with specified name
+ * @param *name Container name
*/
void Store::drop_container(const char* name) {
GSResult ret = gsDropContainer(mStore, name);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
}
+
/**
- * Return information object of a specific container
+ * @brief Get information object of a specific container
+ * @param *name Container name
+ * @return Return a pointer which stores all information of container
*/
ContainerInfo* Store::get_container_info(const char* name) {
- GSContainerInfo containerInfo = GS_CONTAINER_INFO_INITIALIZER;
+ GSContainerInfo gsContainerInfo = GS_CONTAINER_INFO_INITIALIZER;
GSChar bExists;
- GSResult ret = gsGetContainerInfo(mStore, name, &containerInfo, &bExists);
- if (ret != GS_RESULT_OK) {
+ GSResult ret = gsGetContainerInfo(mStore, name, &gsContainerInfo, &bExists);
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
if (bExists == false) {
return NULL;
}
- return new ContainerInfo(&containerInfo);
+
+ try {
+ ContainerInfo* containerInfo = new ContainerInfo(&gsContainerInfo);
+ return containerInfo;
+ } catch (bad_alloc& ba) {
+ throw GSException(mStore, "Memory allocation error");
+ }
}
+
/**
- * Put container. Convert from method gsPutContainerGeneral()
+ * @brief Creates or update a Container with the specified GSContainerInfo.
+ * @param *info A pointer which stores all information of container
+ * @param modifiable Indicates whether the column layout of the existing Container can be modified or not
+ * @return The pointer to a pointer variable to store Container instance
*/
Container* Store::put_container(ContainerInfo* info,
bool modifiable) {
+ if (info == NULL) {
+ throw GSException(mStore, "Invalid input for \"Store::put_container\" method. Argument container info can not be null");
+ }
// Get Container information
GSContainerInfo* gsInfo = info->gs_info();
GSContainer* pContainer = NULL;
// Create new gsContainer
GSResult ret = gsPutContainerGeneral(mStore, gsInfo->name, gsInfo, modifiable, &pContainer);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
- if (pContainer == NULL) {
- return NULL;
+
+ try {
+ Container* container = new Container(pContainer, gsInfo);
+ return container;
+ } catch (bad_alloc& ba) {
+ gsCloseContainer(&pContainer, GS_FALSE);
+ throw GSException(mStore, "Memory allocation error");
}
- return new Container(pContainer, gsInfo);
}
+
/**
- * Get container object with corresponding name
+ * @brief Get container object with corresponding name
+ * @param *name Container name
+ * @return The pointer to a pointer variable to store Container instance
*/
Container* Store::get_container(const char* name) {
GSContainer* pContainer;
GSResult ret = gsGetContainerGeneral(mStore, name, &pContainer);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
if (pContainer == NULL) {
@@ -92,81 +123,141 @@ namespace griddb {
GSContainerInfo containerInfo = GS_CONTAINER_INFO_INITIALIZER;
GSChar bExists;
ret = gsGetContainerInfo(mStore, name, &containerInfo, &bExists);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
+ gsCloseContainer(&pContainer, GS_FALSE);
throw GSException(mStore, ret);
}
- return new Container(pContainer, &containerInfo);
+ try {
+ Container* container = new Container(pContainer, &containerInfo);
+ return container;
+ } catch (bad_alloc& ba) {
+ gsCloseContainer(&pContainer, GS_FALSE);
+ throw GSException(mStore, "Memory allocation error");
+ }
}
+
/**
- * Query execution and fetch is carried out on a specified arbitrary number of Query, with the request unit enlarged as much as possible.
+ * @brief Query execution and fetch is carried out on a specified arbitrary number of Query, with the request unit enlarged as much as possible.
+ * @param **queryList A list of query
+ * @param queryCount Number of element in query list
*/
void Store::fetch_all(GSQuery* const* queryList, size_t queryCount) {
GSResult ret = gsFetchAll(mStore, queryList, queryCount);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
}
+
/**
- * Get Partition controller. Convert from C-API: gsGetPartitionController
+ * @brief Get Partition controller.
+ * @return The pointer to a pointer variable to store PartitionController instance
*/
PartitionController* Store::partition_info() {
- GSPartitionController* partitionController;
+ GSPartitionController* partitionController;
+
GSResult ret = gsGetPartitionController(mStore, &partitionController);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
- return new PartitionController(partitionController);
+ try {
+ PartitionController* partition = new PartitionController(partitionController);
+ return partition;
+ } catch (bad_alloc& ba) {
+ gsClosePartitionController(&partitionController);
+ throw GSException(mStore, "Memory allocation error");
+ }
}
+
/**
- * Create row key predicate. Convert from C-API: gsCreateRowKeyPredicate
+ * @brief Create row key predicate.
+ * @param type The type of Row key used as a matching condition
+ * @return The pointer to a pointer variable to store RowKeyPredicate instance
*/
RowKeyPredicate* Store::create_row_key_predicate(GSType type) {
GSRowKeyPredicate* predicate;
+
GSResult ret = gsCreateRowKeyPredicate(mStore, type, &predicate);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
- return new RowKeyPredicate(predicate, type);
+ try {
+ RowKeyPredicate* rowKeyPredicate = new RowKeyPredicate(predicate, type);
+ return rowKeyPredicate;
+ } catch (bad_alloc& ba) {
+ gsCloseRowKeyPredicate(&predicate);
+ throw GSException(mStore, "Memory allocation error");
+ }
}
+
/**
- * New creation or update operation is carried out on an arbitrary number of rows of multiple Containers, with the request unit enlarged as much as possible.
+ * @brief New creation or update operation is carried out on an arbitrary number of rows of multiple Containers, with the request unit enlarged as much as possible.
+ * @param ***listRow A pointer refers list of row data
+ * @param *listRowContainerCount A array store number of list row for each container
+ * @param **listContainerName list container name
+ * @param containerCount Number of container
*/
void Store::multi_put(GSRow*** listRow, const int *listRowContainerCount,
const char ** listContainerName, size_t containerCount) {
+ assert(listRowContainerCount != NULL);
+ assert(listContainerName != NULL);
GSResult ret;
- GSContainerRowEntry * entryList = (GSContainerRowEntry*) malloc (containerCount * sizeof(GSContainerRowEntry));
+ GSContainerRowEntry* entryList;
+
+ try {
+ entryList = new GSContainerRowEntry[containerCount]();
+ } catch (bad_alloc& ba) {
+ throw GSException(mStore, "Memory allocation error");
+ }
for (int i= 0; i < containerCount; i++) {
entryList[i].containerName = listContainerName[i];
entryList[i].rowCount = listRowContainerCount[i];
entryList[i].rowList = (void* const*) listRow[i];
}
ret = gsPutMultipleContainerRows(mStore, entryList, containerCount);
- free((void*) entryList);
- if (ret != GS_RESULT_OK) {
+ delete[] entryList;
+ if (!GS_SUCCEEDED(ret)) {
throw GSException(mStore, ret);
}
}
+
/**
- * multi_get method. Using gsGetMultipleContainerRows C-API
+ * @brief get multi row from multi container
+ * @param **predicateList A pointer refers list of the specified condition entry by a container for representing the acquisition conditions for a plurality of containers.
+ * @param predicateCount Number of predicate list
+ * @param **entryList A pointer refers to a list of the Row contents entry by a container used when operating collectively a plurality of Rows of a plurality of containers.
+ * @param *containerCount Number of container
+ * @param **colNumList A pointer refers to an array stores number of column of each container
+ * @param ***typeList A pointer refers to an array stores type of column of each container
+ * @param **orderFromInput A pointer refers to an array stores order of each container for output
*/
void Store::multi_get(const GSRowKeyPredicateEntry* const * predicateList,
size_t predicateCount, GSContainerRowEntry **entryList, size_t* containerCount,
int **colNumList, GSType*** typeList, int **orderFromInput) {
+ assert(predicateList != NULL);
+ assert(predicateCount >= 0);
+ assert(colNumList != NULL);
+ assert(typeList != NULL);
+ assert(orderFromInput != NULL);
+ assert(containerCount != NULL);
*colNumList = NULL;
*typeList = NULL;
*orderFromInput = NULL;
*containerCount = 0;
- // get number of column of rows in each container.
- *colNumList = new int[predicateCount]; //will be free in argout
- *orderFromInput = new int[predicateCount]; //will be free in argout
- *typeList = new GSType*[predicateCount]; //will be free in argout
- int length = (int)predicateCount;
- memset(*colNumList, 0, predicateCount * sizeof(int));
- memset(*typeList, 0, predicateCount * sizeof(GSType*));
+ int length = (int) predicateCount;
+
+ try {
+ // get number of column of rows in each container.
+ *colNumList = new int[predicateCount](); //will be free in argout
+ *typeList = new GSType*[predicateCount](); //will be free in argout
+ *orderFromInput = new int[length](); //will be free in argout
+ } catch (bad_alloc& ba) {
+ this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput);
+ throw GSException(mStore, "Memory allocation error");
+ }
bool setNumList = this->setMultiContainerNumList(predicateList,
length, &colNumList, &typeList);
@@ -174,10 +265,11 @@ namespace griddb {
this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput);
throw GSException(mStore, "Set multi containers number list and type list error");
}
+
// Get data for entryList
GSResult ret = gsGetMultipleContainerRows(mStore, predicateList,
predicateCount, (const GSContainerRowEntry**) entryList, containerCount);
- if (ret != GS_RESULT_OK) {
+ if (!GS_SUCCEEDED(ret)) {
this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput);
throw GSException(mStore, ret);
}
@@ -205,7 +297,7 @@ namespace griddb {
if (*typeList) {
for (int i = 0; i < length; i++) {
if ((*typeList)[i]) {
- free((void*) (*typeList)[i]);
+ delete[] (*typeList)[i];
}
}
delete [] *typeList;
@@ -233,8 +325,15 @@ namespace griddb {
return false;
}
(**colNumList)[i] = tmpContainer->getColumnCount();
- (**typeList)[i] = (GSType*) malloc(sizeof(GSType) * (**colNumList)[i]);
- //(**typeList)[i] will be freed in freeMemoryMultiGet() function or argout
+
+ try {
+ //(**typeList)[i] will be freed in freeMemoryMultiGet() function or argout
+ (**typeList)[i] = new GSType[(**colNumList)[i]]();
+ } catch (bad_alloc& ba) {
+ delete tmpContainer;
+ return false;
+ }
+
for (int j = 0; j < (**colNumList)[i]; j++) {
(**typeList)[i][j] = tmpContainer->getGSTypeList()[j];
}
@@ -242,4 +341,5 @@ namespace griddb {
}
return true;
}
+
}
diff --git a/src/Store.h b/src/Store.h
index 27c4e33..7de25c6 100644
--- a/src/Store.h
+++ b/src/Store.h
@@ -19,6 +19,7 @@
#include
+ *
+ *
+ * TIMESTAMP represents milliseconds since the UNIX epoch (January 1, 1970 00:00:00 UTC) with long type.
+ * TIMESTAMP value suports msec. Range of time is from 1/1/1970 to 12/31/9999 (UTC).
+ * There may be more limitation depending on a GridDB cluster configuration. Cannot store a value out of the range.
+ * There is an upper limit for the number of column and the length of column name.
+ * The value has limitations for rage and size. Please refer to appendix of GridDB API Reference for more detail.
+ * Cannot store a value exceeding these limitations.
+ * A limitation about a row key type, presence of column corresponding to a row key,
+ * and availability of row value updates, may differ for each type derived from the container type.
+ * NULL in GridDB rows can be retained unless the NOT NULL constraint is set.
+ * NOT NULL constraint can be set with columnInfoList object in ContainerInfo when put_container() is called.
+ * About transaction, auto commit mode is active as a default.
+ * In the auto commit mode, each transaction is processed sequentially, and cannot be canceled.
+ * For manual commit mode, transactions before a commit is canceled if there is an error on a cluster node during the transaction via Container instances.
+ * Transaction isolation level supports only READ COMMITTED. Lock granularity may differ for each container type.
+ * When a row is updated, added, deleted, and got a lock for updates, a transaction is generated internally.
+ * This transaction has a valid period.
+ * After some period defined by GridDB is passed from the timing of this transaction for Container instance, any same type of transactions will be not accepted.
+ *
+ * Newly creates or update a Row.
+ * If a Column exists which corresponds to the specified Row key, it determines whether to newly create or update a Row, based on the Row key and the state of the Container. If there is no corresponding Row in the Container, it determines to newly create a Row; otherwise, it updates a relevant Row.
+ * If no Column exists which corresponds to the specified Row key, it always creates a new Row.
+ * In the manual commit mode, the target Row is locked.
+ *
+ * @type {Promise}
+ * @param {object[]} row=null - A list object representing the content of a Row to be newly created or updated.
+ * @returns {Promise} True if a Row exists
+ */
put(arr) {
var this_ = this;
return new Promise(function(resolve, reject) {
@@ -221,6 +580,15 @@ class Container {
});
}
+ /**
+ *
+ * Returns the content of a Row corresponding to Row key.
+ *