From 34bde167fd3c0d67e9185be88d40c98ad1d935a2 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:11:13 +0900 Subject: [PATCH 01/22] reflect source code of Python client (0.8.2) --- src/AggregationResult.cpp | 126 +++--- src/AggregationResult.h | 52 +-- src/Container.cpp | 730 +++++++++++++++++++---------------- src/Container.h | 102 ++--- src/ContainerInfo.cpp | 381 +++++++++++++++++- src/ContainerInfo.h | 86 +++-- src/GSException.h | 292 +++++++++++--- src/PartitionController.cpp | 247 +++++------- src/PartitionController.h | 53 ++- src/Query.cpp | 199 ++++++---- src/Query.h | 53 +-- src/RowKeyPredicate.cpp | 582 +++++++++++++--------------- src/RowKeyPredicate.h | 85 ++-- src/RowSet.cpp | 361 ++++++++++++----- src/RowSet.h | 87 +++-- src/Store.cpp | 505 ++++++++++++++++-------- src/Store.h | 88 +++-- src/StoreFactory.cpp | 245 ++++++++---- src/TimeSeriesProperties.cpp | 110 ++++-- src/TimeSeriesProperties.h | 50 +-- src/TimestampUtils.cpp | 73 +--- src/TimestampUtils.h | 39 +- src/griddb.i | 107 +++-- src/gstype.i | 143 +++---- 24 files changed, 2936 insertions(+), 1860 deletions(-) diff --git a/src/AggregationResult.cpp b/src/AggregationResult.cpp index 24ae7ca..ad8b2c0 100644 --- a/src/AggregationResult.cpp +++ b/src/AggregationResult.cpp @@ -1,77 +1,73 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "AggregationResult.h" namespace griddb { - AggregationResult::AggregationResult(GSAggregationResult* aggResult) : Resource(aggResult), mAggResult(aggResult) { - } - - AggregationResult::~AggregationResult() { - close(); - } - - /** - *Obtains the result of aggregating numeric-type values in LONG type (Long). - */ - long AggregationResult::get_long() { - long value; - - GSBool ret = gsGetAggregationValue(mAggResult, &value, GS_TYPE_LONG); - if(ret == GS_FALSE) { - throw GSException("Value with type long cannot be retrieved from Aggregation result"); - } - - return value; - } - - /** - *Obtains the result of aggregating numeric-type values in DOUBLE type (Double). - */ - double AggregationResult::get_double() { - double value; - - GSBool ret = gsGetAggregationValue(mAggResult, &value, GS_TYPE_DOUBLE); - if(ret == GS_FALSE) { - throw GSException("Value with type double cannot be retrieved from Aggregation result"); - } - - return value; - } - - /** - *Obtains the result of aggregating numeric-type values in GSTIMESTAMP type (GSTimestamp). - */ - GSTimestamp AggregationResult::get_timestamp() { - GSTimestamp value; - - GSBool ret = gsGetAggregationValue(mAggResult, &value, GS_TYPE_TIMESTAMP); - if(ret == GS_FALSE) { - throw GSException("Value with type Timestamp cannot be retrieved from Aggregation result"); - } - - return value; - } - - void AggregationResult::close() { - if(mAggResult != NULL) { - gsCloseAggregationResult(&mAggResult); - } - mAggResult = NULL; - } + /** + * @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) { + } + + AggregationResult::~AggregationResult() { + close(); + } + + /** + * @brief Release AggregationResult resource + */ + void AggregationResult::close() { + if (mAggResult != NULL) { + gsCloseAggregationResult(&mAggResult); + } + mAggResult = NULL; + } + + /** + * @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) { + case GS_TYPE_DOUBLE: + value = &agValue->value.asDouble; + break; + case GS_TYPE_LONG: + value = &agValue->value.asLong; + break; + case GS_TYPE_TIMESTAMP: + value = &agValue->value.asTimestamp; + break; + default: + throw GSException(mAggResult, "Not support type from Aggregation result"); + break; + } + GSBool ret = gsGetAggregationValue(mAggResult, value, type); + if (ret == GS_FALSE) { + throw GSException(mAggResult, + "Value cannot be retrieved from Aggregation result"); + } + } } /* namespace griddb */ diff --git a/src/AggregationResult.h b/src/AggregationResult.h index 3bcf470..3db594f 100644 --- a/src/AggregationResult.h +++ b/src/AggregationResult.h @@ -1,42 +1,46 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _AGGREGATIONRESULT_H_ #define _AGGREGATIONRESULT_H_ -#include "Resource.h" +#include + #include "GSException.h" -#include +#include "Field.h" +#include "gridstore.h" using namespace std; namespace griddb { - class AggregationResult : public Resource { - GSAggregationResult* mAggResult; - public: - AggregationResult(GSAggregationResult* aggResult); - ~AggregationResult(); - - long get_long(); - double get_double(); - GSTimestamp get_timestamp(); - private: - void close(); - }; +class AggregationResult { + + GSAggregationResult* mAggResult; + + friend class RowSet; + + public: + bool timestamp_output_with_float; + ~AggregationResult(); + void close(); + void get(GSType type, griddb::Field *agValue); + AggregationResult(GSAggregationResult* aggResult); + +}; } /* namespace griddb */ diff --git a/src/Container.cpp b/src/Container.cpp index f51d2e3..8bdc1c0 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -1,338 +1,412 @@ -/* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + /* + 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 + 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 + 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. + 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 "Container.h" -#include "GSException.h" -namespace griddb { +#include - Container::Container(GSContainer *container) : Resource(container), mContainer(container) { - } - - Container::~Container() { - close(); - } - - /** - * Creates a specified type of index on the specified Column. - */ - void Container::create_index(const char* columnName, - GSIndexTypeFlags indexType) { - GSResult ret = gsCreateIndex(mContainer, columnName, indexType); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Removes the specified type of index among indexes on the specified Column. - */ - void Container::drop_index(const char* columName, GSIndexTypeFlags indexType) { - GSResult ret = gsDropIndex(mContainer, columName, indexType); - - if(ret != GS_RESULT_OK) { - throw GSException(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. - */ - void Container::flush() { - GSResult ret = gsFlush(mContainer); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Create new row. - */ - Row* Container::create_row() { - GSRow *row; - - GSResult ret = gsCreateRowByContainer(mContainer, &row); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new Row(row); - } - - /** - * Put row to database. - */ - bool Container::put_row(Row* row) { - GSBool bExists; - - GSResult ret = gsPutRow(mContainer, NULL, row->gs_ptr(), &bExists); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return bExists; - - } - - /** - * Get current container type - */ - GSContainerType Container::get_type() { - GSContainerType containerType; - GSResult ret = gsGetContainerType(mContainer, &containerType); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return containerType; - } - - /** - * 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) { - throw GSException(ret); - } - } - - /** - * Create query from input string. - */ - Query* Container::query(const char* queryString) { - GSQuery *pQuery; - gsQuery(mContainer, queryString, (&pQuery)); - return new Query(pQuery); - } - - /** - * Set auto commit to true or false. - */ - void Container::set_auto_commit(bool enabled){ - GSBool gsEnabled; - gsEnabled = (enabled == true ? GS_TRUE:GS_FALSE); - gsSetAutoCommit(mContainer, gsEnabled); - } - - /** - * Commit changes to database when autocommit is set to false. - */ - void Container::commit() { - GSResult ret = gsCommit(mContainer); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Returns the content of a Row corresponding to the specified Row key according to the specified option. - */ - bool Container::get_row_by_integer(int32_t key, bool forUpdate, Row* row) { - GSBool exists; - - GSResult ret = gsGetRowByInteger(mContainer, key, row->gs_ptr(), forUpdate, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Returns the content of a Row corresponding to the specified Row key according to the specified option. - */ - bool Container::get_row_by_long(int64_t key, bool forUpdate, Row* row) { - GSBool exists; - - GSResult ret = gsGetRowByLong(mContainer, key, row->gs_ptr(), forUpdate, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Returns the content of a Row corresponding to the specified Row key according to the specified option. - */ - bool Container::get_row_by_timestamp(GSTimestamp key, bool forUpdate, Row* row) { - GSBool exists; - - GSResult ret = gsGetRowByTimestamp(mContainer, key, row->gs_ptr(), forUpdate, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Returns the content of a Row corresponding to the specified Row key according to the specified option. - */ - bool Container::get_row_by_string(const GSChar* key, bool forUpdate, Row* row) { - GSBool exists; - - GSResult ret = gsGetRowByString(mContainer, key, row->gs_ptr(), forUpdate, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Newly creates or updates a Row, based on the specified Row object and also the Row key specified as needed. - */ - bool Container::put_row_by_integer(int32_t key, Row* row) { - GSBool exists = GS_FALSE; - - GSResult ret = gsPutRowByInteger(mContainer, key, row->gs_ptr(), &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Newly creates or updates a Row, based on the specified Row object and also the Row key specified as needed. - */ - bool Container::put_row_by_long(int64_t key, Row* row) { - GSBool exists = GS_FALSE; - - GSResult ret = gsPutRowByLong(mContainer, key, row->gs_ptr(), &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Newly creates or updates a Row, based on the specified Row object and also the Row key specified as needed. - */ - bool Container::put_row_by_timestamp(GSTimestamp key, Row* row) { - GSBool exists = GS_FALSE; - - GSResult ret = gsPutRowByTimestamp(mContainer, key, row->gs_ptr(), &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - * Newly creates or updates a Row, based on the specified Row object and also the Row key specified as needed. - */ - bool Container::put_row_by_string(const GSChar* key, Row* row) { - GSBool exists = GS_FALSE; - - GSResult ret = gsPutRowByString(mContainer, key, row->gs_ptr(), &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return (bool) exists; - } - - /** - *Delete row by integer. Convert from C-API: gsDeleteRowByInteger - */ - bool Container::delete_row_by_integer(int32_t key) { - GSBool exists = GS_FALSE; - - GSResult ret = gsDeleteRowByInteger(mContainer, key, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (bool) exists; - } - - /** - *Delete row by long. Convert from C-API: gsDeleteRowByLong - */ - bool Container::delete_row_by_long(int64_t key) { - GSBool exists; - - GSResult ret = gsDeleteRowByLong(mContainer, key, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (bool) exists; - } - - /** - *Delete row by timestamp. Convert from C-API: gsDeleteRowByTimestamp - */ - bool Container::delete_row_by_timestamp(GSTimestamp key) { - GSBool exists; - - GSResult ret = gsDeleteRowByTimestamp(mContainer, key, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (bool) exists; - } - - /** - *Delete row by string. Convert from C-API: gsDeleteRowByString - */ - bool Container::delete_row_by_string(const GSChar* key) { - GSBool exists; - - GSResult ret = gsDeleteRowByString(mContainer, key, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (bool) exists; - } - - /** - * Newly creates an arbitrary number of Rows together based on the specified Row objects group. - */ - bool Container::put_multi_row(const void* const * rowObjs, size_t rowCount) { - GSBool exists; - - GSResult ret = gsPutMultipleRows(mContainer, rowObjs, rowCount, &exists); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return exists; - } - - /** - * Close container. - */ - void Container::close() { - //Release container and all related resources - if(mContainer != NULL) { - // allRelated = FALSE, since all row object is managed by Row class - gsCloseContainer(&mContainer, GS_FALSE); - mContainer = NULL; - } - } +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 (!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 + 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); + } + + 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->timeSeriesProperties = NULL; + mContainerInfo->triggerInfoList = NULL; + mContainerInfo->dataAffinity = NULL; + + if (mTypeList && mContainerInfo->columnInfoList) { + for (int i = 0; i < mContainerInfo->columnCount; i++){ + mTypeList[i] = mContainerInfo->columnInfoList[i].type; + } + } + } + + Container::~Container() { + + + // 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++) { + if (mContainerInfo->columnInfoList && mContainerInfo->columnInfoList[i].name) { + delete[] mContainerInfo->columnInfoList[i].name; + } + } + if (mContainerInfo->columnInfoList) { + delete[] mContainerInfo->columnInfoList; + } + if (mContainerInfo->name) { + delete[] mContainerInfo->name; + } + delete mContainerInfo; + mContainerInfo = NULL; + } + if (mTypeList) { + delete[] mTypeList; + mTypeList = NULL; + } + } + + /** + * @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(); + } + + /** + * @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 (name) { + GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER; + indexInfo.name = name; + indexInfo.type = index_type; + indexInfo.columnName = column_name; + ret = gsDropIndexDetail(mContainer, &indexInfo); + } else { + ret = gsDropIndex(mContainer, column_name, index_type); + } + + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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 (name){ + GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER; + indexInfo.name = name; + indexInfo.type = index_type; + indexInfo.columnName = column_name; + ret = gsCreateIndexDetail(mContainer, &indexInfo); + } else { + ret = gsCreateIndex(mContainer, column_name, index_type); + } + + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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 *row) { + GSBool bExists; + GSResult ret = gsPutRow(mContainer, NULL, mRow, &bExists); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + return bExists; + } + + /** + * @brief Get current container type + * @return Return container type + */ + GSContainerType Container::get_type() { + GSContainerType containerType; + GSResult ret = gsGetContainerType(mContainer, &containerType); + + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + + return containerType; + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + + try { + Query* queryObj = new Query(pQuery, mContainerInfo, mRow); + return queryObj; + } catch(bad_alloc& ba) { + gsCloseQuery(&pQuery); + throw GSException(mContainer, "Memory allocation error"); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @brief Commit changes to database when autocommit is set to false. + */ + void Container::commit() { + GSResult ret = gsCommit(mContainer); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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; + switch (keyFields->type) { + case GS_TYPE_STRING: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) { + throw GSException("wrong type of rowKey string"); + } + key = &keyFields->value.asString; + break; + case GS_TYPE_INTEGER: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) { + throw GSException("wrong type of rowKey integer"); + } + key = &keyFields->value.asInteger; + break; + case GS_TYPE_LONG: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_LONG) { + throw GSException("wrong type of rowKey long"); + } + key = &keyFields->value.asLong; + break; + case GS_TYPE_TIMESTAMP: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) { + throw GSException("wrong type of rowKey timestamp"); + } + key = &keyFields->value.asTimestamp; + break; + default: + throw GSException("wrong type of rowKey field"); + } + + ret = gsGetRow(mContainer, key, mRow, &exists); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + + return exists; + } + + /** + * @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 (keyFields->type == GS_TYPE_NULL) { + ret = gsDeleteRow(mContainer, NULL, &exists); + } else { + switch (keyFields->type) { + case GS_TYPE_STRING: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) { + throw GSException("wrong type of rowKey string"); + } + ret = gsDeleteRow(mContainer, &keyFields->value.asString, &exists); + break; + case GS_TYPE_INTEGER: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) { + throw GSException("wrong type of rowKey integer"); + } + ret = gsDeleteRow(mContainer, &keyFields->value.asInteger, &exists); + break; + case GS_TYPE_LONG: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_LONG) { + throw GSException("wrong type of rowKey long"); + } + ret = gsDeleteRow(mContainer, &keyFields->value.asLong, &exists); + break; + case GS_TYPE_TIMESTAMP: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) { + 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_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + + return (bool) exists; + } + + /** + * @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; + GSBool bExists; + //data for each container + ret = gsPutMultipleRows(mContainer, (const void * const *) listRowdata, + rowCount, &bExists); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mContainer, ret); + } + } + + /** + * @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; + } + + /** + * @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; + } + + /** + * @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 183ce08..74f7f47 100644 --- a/src/Container.h +++ b/src/Container.h @@ -1,65 +1,69 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _CONTAINER_H_ #define _CONTAINER_H_ -#include -#include "Resource.h" -#include "Row.h" +#include + +#include "Field.h" #include "Query.h" +#include "GSException.h" +#include "Util.h" + using namespace std; namespace griddb { - class Container : public Resource { - - GSContainer *mContainer; - - public: - Container(GSContainer *container); - ~Container(); - - void create_index(const char* columnName, GSIndexTypeFlags indexType); - void drop_index(const char* columName, GSIndexTypeFlags indexType); - void flush(); - Row* create_row(); - bool put_row(Row* row); - bool put_multi_row(const void *const *rowObjs, size_t rowCount); - Query* query(const char *queryString); - GSContainerType get_type(); - void abort(); - void set_auto_commit(bool enabled); - void commit(); - bool get_row_by_integer(int32_t key, bool forUpdate, Row* row); - bool get_row_by_long(int64_t key, bool forUpdate, Row* row); - bool get_row_by_timestamp(GSTimestamp key, bool forUpdate, Row* row); - bool get_row_by_string(const GSChar* key, bool forUpdate, Row* row); - bool put_row_by_integer(int32_t key, Row* row); - bool put_row_by_long(int64_t key, Row* row); - bool put_row_by_timestamp(GSTimestamp key, Row* row); - bool put_row_by_string(const GSChar *key, Row* row); - bool delete_row_by_integer(int32_t key); - bool delete_row_by_long(int64_t key); - bool delete_row_by_timestamp(GSTimestamp key); - bool delete_row_by_string(const GSChar *key); - - private: - void close(); - }; -} +class Container { + + GSContainerInfo* mContainerInfo; + GSContainer *mContainer; + + friend class Store; + + GSRow* mRow; + GSType* mTypeList; + + public: + bool timestamp_output_with_float; + ~Container(); + void close(GSBool allRelated = GS_FALSE); + 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 *row); + Query* query(const char *query); + void abort(); + void flush(); + void set_auto_commit(bool enabled); + void commit(); + GSBool get(Field* keyFields, GSRow *rowdata); + bool remove(Field* keyFields); + void multi_put(GSRow** listRowdata, int rowCount); + GSContainer* getGSContainerPtr(); + GSType* getGSTypeList(); + int getColumnCount(); + GSRow* getGSRowPtr(); + + private: + Container(GSContainer *container, GSContainerInfo* containerInfo); + void freeMemoryContainer(); +}; + +} /* namespace griddb */ #endif /* _CONTAINER_H_ */ diff --git a/src/ContainerInfo.cpp b/src/ContainerInfo.cpp index f1be8e0..7fd2ba4 100644 --- a/src/ContainerInfo.cpp +++ b/src/ContainerInfo.cpp @@ -1,32 +1,377 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "gridstore.h" #include "ContainerInfo.h" namespace griddb { - ContainerInfo::ContainerInfo(GSContainerInfo *containerInfo) : mContainerInfo(*containerInfo){ - } + /** + * @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; - ContainerInfo::~ContainerInfo() { - } + try { + if (containerInfo->timeSeriesProperties) { + gsProps = new GSTimeSeriesProperties(); + } - int ContainerInfo::get_column_count() { - return mContainerInfo.columnCount; - } + 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) { + memcpy(gsProps, containerInfo->timeSeriesProperties, sizeof(GSTimeSeriesProperties)); + } + mContainerInfo.timeSeriesProperties = gsProps; + + if (containerInfo->triggerInfoList) { + memcpy(triggerInfoList, containerInfo->triggerInfoList, sizeof(GSTriggerInfo)); + } + + mContainerInfo.triggerInfoList = triggerInfoList; + + 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); + } + + /** + * Initialize values of Container Info object + */ + void ContainerInfo::init(const GSChar* name, + GSContainerType type, const GSColumnInfo* props, + int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration) { + GSColumnInfo* columnInfoList = NULL; + GSChar* containerName = NULL; + GSTimeSeriesProperties* timeProps = 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) { + memcpy(timeProps, expiration->gs_ts(), sizeof(GSTimeSeriesProperties)); + } + + mContainerInfo = {containerName, type, (size_t)propsCount, columnInfoList, rowKeyAssigned}; + if (timeProps != NULL) { + mContainerInfo.timeSeriesProperties = timeProps; + } + mExpInfo = NULL; + mColumnInfoList.columnInfo = NULL; + mColumnInfoList.size = 0; + } + + ContainerInfo::~ContainerInfo() { + //Free memory for the copy of container name + if (mContainerInfo.name) { + delete[] mContainerInfo.name; + } + + //Free memory for the copy of ColumnInfo list + if (mContainerInfo.columnInfoList) { + //Free memory of columns name + for(int i = 0; i < mContainerInfo.columnCount; i++) { + if(mContainerInfo.columnInfoList[i].name) { + delete[] mContainerInfo.columnInfoList[i].name; + } + } + delete[] mContainerInfo.columnInfoList; + } + + //Free memory of TimeSeriesProperties if existed + if (mContainerInfo.timeSeriesProperties) { + delete mContainerInfo.timeSeriesProperties; + } + + //Free memory of dataAffinity if existed + if (mContainerInfo.dataAffinity) { + delete[] mContainerInfo.dataAffinity; + } + + //Free memory of triggerInfoList if existed + if(mContainerInfo.triggerInfoList) { + delete mContainerInfo.triggerInfoList; + } + if (mExpInfo != NULL) { + delete mExpInfo; + } + } + + /** + * @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) { + delete[] mContainerInfo.name; + } + if (containerName == NULL) { + mContainerInfo.name = NULL; + } else { + try { + Util::strdup(&(mContainerInfo.name), containerName); + } catch (bad_alloc& ba) { + throw GSException("Memory allocation error"); + } + } + } + + /** + * @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; + } + + /** + * @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; + } + + /** + * @brief Get name of Container which is stored in ContainerInfo + * @return The name of Container + */ + const GSChar* ContainerInfo::get_name() { + return mContainerInfo.name; + } + + /** + * @brief Get type of Container which is stored in ContainerInfo + * @return The type of Container + */ + GSContainerType ContainerInfo::get_type() { + return mContainerInfo.type; + } + + /** + * @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]; + } + + /** + * @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; + } + + /** + * @brief Get all information of Container + * @return A pointer which store all information of Container + */ + GSContainerInfo* ContainerInfo::gs_info() { + return &mContainerInfo; + } + + /** + * @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++) { + delete[] mContainerInfo.columnInfoList[i].name; + } + delete[] mContainerInfo.columnInfoList; + } + + 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; + } + + /** + * @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; + mColumnInfoList.size = mContainerInfo.columnCount; + return mColumnInfoList; + } + + /** + * @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 (mContainerInfo.timeSeriesProperties != NULL) { + delete mContainerInfo.timeSeriesProperties; + mContainerInfo.timeSeriesProperties = NULL; + } + if (expirationInfo) { + 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; + } + } + + /** + * @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){ + if (mExpInfo != NULL) { + mExpInfo->set_time(mContainerInfo.timeSeriesProperties->rowExpirationTime); + mExpInfo->set_time_unit(mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit); + mExpInfo->set_division_count(mContainerInfo.timeSeriesProperties->expirationDivisionCount); + } else { + 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; + } + return mExpInfo; + } } /* namespace griddb */ diff --git a/src/ContainerInfo.h b/src/ContainerInfo.h index dc5e077..045a249 100644 --- a/src/ContainerInfo.h +++ b/src/ContainerInfo.h @@ -1,44 +1,80 @@ -/* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + /* + 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 + 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 + 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. + 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 _CONTAINERINFO_H_ #define _CONTAINERINFO_H_ #include -#include "gridstore.h" +#include +#include +#include + +#include "TimeSeriesProperties.h" +#include "ExpirationInfo.h" +#include "GSException.h" +#include "Util.h" + +//Support column_info_list attribute +struct ColumnInfoList { + GSColumnInfo* columnInfo; + size_t size; +}; using namespace std; namespace griddb { class ContainerInfo { - /** - * Contains information about a specific container - */ - GSContainerInfo mContainerInfo; -public: - ContainerInfo(GSContainerInfo *containerInfo); - ~ContainerInfo(); - - int get_column_count(); - -private: - void close(); + /** + * Contains information about a specific container + */ + private: + GSContainerInfo mContainerInfo; + + //tmp attribute to get column info list + ColumnInfoList mColumnInfoList; + + //tmp attribute support get expiration attribute + ExpirationInfo* mExpInfo; + + public: + ContainerInfo(GSContainerInfo *containerInfo); + ContainerInfo(const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type = GS_CONTAINER_COLLECTION, + bool row_key = true, ExpirationInfo* expiration = NULL); + ~ContainerInfo(); + + void set_name(GSChar* containerName); + void set_type(GSContainerType containerType); + void set_row_key_assigned(bool rowKeyAssigned); + const GSChar* get_name(); + GSContainerType get_type(); + GSColumnInfo get_column_info(size_t column); + ColumnInfoList get_column_info_list(); + void set_column_info_list(ColumnInfoList columnInfoList); + ExpirationInfo* get_expiration_info(); + void set_expiration_info(ExpirationInfo* expirationInfo); + bool get_row_key_assigned(); + GSContainerInfo* gs_info(); + + private: + void init(const GSChar* name, GSContainerType type, const GSColumnInfo* props, + int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration); }; } /* namespace griddb */ -#endif /* SRC_CONTAINERINFO_H_ */ +#endif /* Define _CONTAINERINFO_H_ */ diff --git a/src/GSException.h b/src/GSException.h index 2621232..c2090ed 100644 --- a/src/GSException.h +++ b/src/GSException.h @@ -1,72 +1,254 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _GS_EXCEPTION_H_ -#define _GS_EXCEPTION_H_ +#ifndef _GS_EXXCEPTION_H_ +#define _GS_EXXCEPTION_H_ #include #include + #include "gridstore.h" using namespace std; +#define DEFAULT_ERROR_CODE -1 +#define DEFAULT_ERROR_STACK_SIZE 1 + namespace griddb { - /** - * This class creates exception corresponding to error code - */ - class GSException : public exception { - int32_t mCode; - string mMessage; - public: - GSException(int32_t code) : exception(), mCode(code) { - mMessage = "Error with number " + to_string((long long int)mCode); - } - - GSException(const char* message) : exception(), - mCode(-1), mMessage(message) { - } - - GSException(int32_t code, const char* message) : exception(), - mCode(code), mMessage(message) { - } - - ~GSException() throw() {} - - int32_t get_code() { - return mCode; - } - - virtual const char* what() const throw() { - return mMessage.c_str(); - } - - /* - * Check timeout. Convert from C-API: gsIsTimeoutError - */ - bool is_timeout() { - if (mCode != -1) { - //Case exception with error code. - return gsIsTimeoutError(mCode); - } - //Case exception with message only. - return false; - } - }; - -} +/** + * This class creates exception corresponding to error code + */ +class GSException : public exception { + private: + bool mIsTimeout; + int32_t mCode; + string mMessage; + void *mResource; + + bool hasInnerError; + size_t mInnerErrStackSize; + GSResult* mInnerErrCodeStack; + string* mInnerMessagesStack; + string* mInnerErrorLocationStack; + + public: + GSException(const char* message) : exception(), + mCode(DEFAULT_ERROR_CODE), mMessage(message), mResource(NULL) { + 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) { + hasInnerError = false; + mInnerErrStackSize = 0; + mInnerErrCodeStack = NULL; + mInnerMessagesStack = NULL; + mInnerErrorLocationStack = NULL; + mIsTimeout = false; + } + GSException(const GSException&e) : exception() { + mCode = e.mCode; + mResource = e.mResource; + mIsTimeout = e.mIsTimeout; + mMessage = "Error with number " + to_string((long long int)mCode); + if (mCode != DEFAULT_ERROR_CODE && mResource != NULL) { + mIsTimeout = gsIsTimeoutError(mCode); + 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; + } + } + 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 && mResource != NULL) { + //Case exception with error code from c layer + mIsTimeout = gsIsTimeoutError(mCode); + // 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; + } + } + GSException(const GSException* exception) { + mCode = exception->mCode; + 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; + } + } + int32_t get_code() { + return mCode; + } + virtual const char* what() const throw() { + return mMessage.c_str(); + } + /* + * Check timeout. Convert from C-API: gsIsTimeoutError + */ + bool is_timeout() { + return mIsTimeout; + } + /** + * Get error stack size. Convert from C-API: gsGetErrorStackSize. + */ + size_t get_error_stack_size() { + 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) { + 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); + delete [] strBuf; + return ret; + } + /** + * Get error location. Convert from C-API: gsFormatErrorLocation. + */ + 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); + delete [] strBuf; + return ret; + } +}; + +} /* namespace griddb */ #endif diff --git a/src/PartitionController.cpp b/src/PartitionController.cpp index 80638ea..639b0fc 100644 --- a/src/PartitionController.cpp +++ b/src/PartitionController.cpp @@ -1,155 +1,116 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "PartitionController.h" namespace griddb { -PartitionController::PartitionController(GSPartitionController *controller) : - mController(controller) { -} - -/** - * Destructor. Convert from C-API:gsClosePartitionController - */ -PartitionController::~PartitionController() { - if (mController != NULL) { - gsClosePartitionController(&mController); - mController = NULL; - } -} - -/** - * Get partition count. Convert from C-Api: gsGetPartitionCount - */ -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) { - throw GSException(ret); - } - return value; -} - -/** - * Get container partition count. Convert from C-Api: gsGetPartitionContainerCount - */ -int64_t PartitionController::get_partition_container_count( - int32_t partitionIndex) { - int64_t value; - GSResult ret = gsGetPartitionContainerCount(mController, partitionIndex, - &value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return value; -} - -/** - * Get list partition container names case there is limit. Convert from C-Api: gsGetPartitionContainerNames - */ -void PartitionController::get_partition_container_names(int32_t partitionIndex, - int64_t start, const GSChar * const ** stringList, size_t *size, - int64_t limit) { - int64_t* limitPtr; - if (limit > 0) { - limitPtr = &limit; - } else { - limitPtr = NULL; - } - GSResult ret = gsGetPartitionContainerNames(mController, partitionIndex, - start, limitPtr, stringList, size); - - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Get get_partition hosts. Convert from C-Api: gsGetPartitionHosts - */ -void PartitionController::get_partition_hosts(int32_t partitionIndex, - const GSChar * const **stringList, size_t *size) { - GSResult ret = gsGetPartitionHosts(mController, partitionIndex, stringList, - size); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Get get_partition index of container. Convert from C-Api: gsGetPartitionIndexOfContainer - */ -int32_t PartitionController::get_partition_index_of_container( - const GSChar* containerName) { - int32_t value; - GSResult ret = gsGetPartitionIndexOfContainer(mController, containerName, - &value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return value; -} - -/** - * Get get_partition owner host. Convert from C-Api: gsGetPartitionOwnerHost - */ -string PartitionController::get_partition_owner_host( - int32_t partitionIndex) { - const GSChar *address; - GSResult ret = gsGetPartitionOwnerHost(mController, partitionIndex, &address); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return address; -} - -/** - * Get get_partition backup hosts. Convert from C-Api: gsGetPartitionBackupHosts - */ -void PartitionController::get_partition_backup_hosts( - int32_t partitionIndex, const GSChar *const **stringList, size_t *size) { - GSResult ret = gsGetPartitionBackupHosts(mController, partitionIndex, - stringList, size); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Assign host. Convert from C-Api: gsAssignPartitionPreferableHost - */ -void PartitionController::assign_partition_preferable_host( - int32_t partitionIndex, const GSChar* host) { - GSResult ret = gsAssignPartitionPreferableHost(mController, partitionIndex, host); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} + /** + * @brief Constructor a new PartitionController::PartitionController object + * @param *controller A pointer for acquiring and processing the partition status + */ + PartitionController::PartitionController(GSPartitionController *controller) : + mController(controller) { + } + + /** + * @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; + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mController, ret); + } + return value; + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mController, ret); + } + return value; + } + + /** + * @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) { + int64_t* limitPtr; + if (limit >= 0) { + limitPtr = &limit; + } else { + limitPtr = NULL; + } + GSResult ret = gsGetPartitionContainerNames(mController, partition_index, start, limitPtr, stringList, size); + + if (!GS_SUCCEEDED(ret)) { + throw GSException(mController, ret); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mController, ret); + } + return value; + } } /* namespace griddb */ diff --git a/src/PartitionController.h b/src/PartitionController.h index e32a072..6945e3a 100644 --- a/src/PartitionController.h +++ b/src/PartitionController.h @@ -1,17 +1,17 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _PARTITIONCONTROLLER_H_ @@ -19,27 +19,26 @@ #include "gridstore.h" #include "GSException.h" -#include namespace griddb { class PartitionController { - GSPartitionController *mController; -public: - PartitionController(GSPartitionController *controller); - ~PartitionController(); - int32_t get_partition_count(); - int64_t get_partition_container_count(int32_t partitionIndex); - void get_partition_container_names(int32_t partitionIndex, int64_t start, - const GSChar * const ** stringList, size_t *size, int64_t limit=-1); - void get_partition_hosts(int32_t partitionIndex, - const GSChar * const **stringList, size_t *size); - int32_t get_partition_index_of_container(const GSChar *containerName); - string get_partition_owner_host(int32_t partitionIndex); - void get_partition_backup_hosts(int32_t partitionIndex, - const GSChar * const ** stringList, size_t *size); - void assign_partition_preferable_host(int32_t partitionIndex, - const GSChar *host); + friend class Store; + + private: + GSPartitionController *mController; + + public: + ~PartitionController(); + void close(); + 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); + int32_t get_partition_index_of_container(const GSChar *container_name); + + private: + PartitionController(GSPartitionController *controller); }; } /* namespace griddb */ diff --git a/src/Query.cpp b/src/Query.cpp index 09dda2a..8bd596d 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -1,93 +1,126 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "Query.h" namespace griddb { - Query::Query(GSQuery *query) : Resource(query), mQuery(query) { - - } - - Query::~Query() { - close(); - } - - /** - * Fetch data from query result. - */ - RowSet* Query::fetch(bool forUpdate) { - GSRowSet *rowSet; - // Call method from C-Api. - GSBool gsForUpdate = (forUpdate == true ? GS_TRUE:GS_FALSE); - GSResult ret = gsFetch(mQuery, gsForUpdate, &rowSet); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new RowSet(rowSet); - } - - /** - * Get row set. Convert from C-Api: gsGetRowSet - */ - RowSet* Query::get_row_set() { - GSRowSet *rowSet; - GSResult ret = gsGetRowSet(mQuery, &rowSet); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new RowSet(rowSet); - } - - /** - * Sets an fetch option of integer type for a result acquisition. - */ - void Query::set_fetch_option_integer(GSFetchOption fetchOption, int32_t value) { - GSResult ret = gsSetFetchOption(mQuery, fetchOption, &value, GS_TYPE_INTEGER); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Sets an fetch option of long type for a result acquisition. - */ - void Query::set_fetch_option_long(GSFetchOption fetchOption, int64_t value) { - GSResult ret = gsSetFetchOption(mQuery, fetchOption, &value, GS_TYPE_LONG); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Release all resources created by this Query object. - */ - void Query::close() { - if (mQuery) { - gsCloseQuery(&mQuery); - mQuery = NULL; - } - } - - GSQuery* Query::gs_ptr() { - return mQuery; - } + + /** + * @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(); + } + + /** + * @brief Release Query resource + */ + void Query::close() { + if (mQuery) { + gsCloseQuery(&mQuery); + mQuery = NULL; + } + } + + /** + * @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 *gsRowSet; + // Call method from C-Api. + GSBool gsForUpdate = (for_update == true ? GS_TRUE:GS_FALSE); + GSResult ret = gsFetch(mQuery, gsForUpdate, &gsRowSet); + + // Check ret, if error, throw exception + if (!GS_SUCCEEDED(ret)) { + throw GSException(mQuery, ret); + } + + try { + RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow); + return rowset; + } catch (bad_alloc& ba) { + gsCloseRowSet(&gsRowSet); + throw GSException(mQuery, "Memory allocation error"); + } + } + + /** + * @brief Get row set. + * @return The pointer to a pointer variable to store GSRowSet instance + */ + RowSet* Query::get_row_set() { + GSRowSet *gsRowSet; + GSResult ret = gsGetRowSet(mQuery, &gsRowSet); + + // Check ret, if error, throw exception + if (!GS_SUCCEEDED(ret)) { + throw GSException(mQuery, ret); + } + + try { + RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow); + return rowset; + } catch (bad_alloc& ba) { + gsCloseRowSet(&gsRowSet); + throw GSException(mQuery, "Memory allocation error"); + } + } + + /** + * @brief Get raw pointer of GSQuery + * @return A pointer store raw pointer of GSQuery + */ + GSQuery* Query::gs_ptr() { + return mQuery; + } + + /** + * @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 (!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 (!GS_SUCCEEDED(ret)) { + throw GSException(mQuery, ret); + } +#endif + } + } } diff --git a/src/Query.h b/src/Query.h index c4b6753..3500886 100644 --- a/src/Query.h +++ b/src/Query.h @@ -1,24 +1,24 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _QUERY_H_ #define _QUERY_H_ #include -#include "Resource.h" + #include "gridstore.h" #include "RowSet.h" #include "GSException.h" @@ -29,20 +29,27 @@ namespace griddb { /** * Convert from GSQuery */ -class Query : public Resource { - GSQuery *mQuery; -public: - Query(GSQuery *query); - ~Query(); - RowSet* fetch(bool forUpdate); - RowSet* get_row_set(); - void set_fetch_option_integer(GSFetchOption fetchOption, int32_t value); - void set_fetch_option_long(GSFetchOption fetchOption, int64_t value); - void close(); - GSQuery* gs_ptr(); -private: + +class Query { + friend class Container; + private: + GSQuery *mQuery; + GSContainerInfo *mContainerInfo; + GSRow* mRow; + + public: + ~Query(); + void close(); + RowSet* fetch(bool for_update = false); + void set_fetch_options(int limit = -1, bool partial = false); + RowSet* get_row_set(); + GSQuery* gs_ptr(); + + private: + Query(GSQuery *query, GSContainerInfo *containerInfo, GSRow *gsRow); }; + } #endif /* _QUERY_H_ */ diff --git a/src/RowKeyPredicate.cpp b/src/RowKeyPredicate.cpp index 917c557..2370426 100644 --- a/src/RowKeyPredicate.cpp +++ b/src/RowKeyPredicate.cpp @@ -1,323 +1,283 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "RowKeyPredicate.h" -#include "GSException.h" namespace griddb { -RowKeyPredicate::RowKeyPredicate(GSRowKeyPredicate *predicate): Resource(predicate), mPredicate(predicate) { -} - -/** - * Destructor. Convert from C-API: gsCloseRowKeyPredicate - */ -RowKeyPredicate::~RowKeyPredicate() { - if (mPredicate != NULL) { - gsCloseRowKeyPredicate(&mPredicate); - mPredicate = NULL; - } -} - -/** - * Get finish key by string. Convert from C-API: gsSetPredicateFinishKeyByString - */ -const GSChar* RowKeyPredicate::get_finish_key_as_string() { - GSChar *finishKey; - GSResult ret = gsGetPredicateFinishKeyAsString(mPredicate, - (const GSChar **) &finishKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return finishKey; -} - -/** - * Get finish key by int. Convert from C-API: gsGetPredicateFinishKeyAsInteger - */ -int32_t RowKeyPredicate::get_finish_key_as_integer() { - int32_t* finishKeyPtr; - GSResult ret = gsGetPredicateFinishKeyAsInteger(mPredicate, - (const int32_t **) &finishKeyPtr); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *finishKeyPtr; -} - -/** - * Get finish key by long. Convert from C-API: gsGetPredicateFinishKeyAsLong - */ -int64_t RowKeyPredicate::get_finish_key_as_long() { - int64_t* finishKeyPtr; - GSResult ret = gsGetPredicateFinishKeyAsLong(mPredicate, - (const int64_t **) &finishKeyPtr); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *finishKeyPtr; -} - -/** - * Get finish key by timestamp. Convert from C-API: gsGetPredicateFinishKeyAsTimestamp - */ -GSTimestamp RowKeyPredicate::get_finish_key_as_timestamp() { - GSTimestamp* finishKeyPtr; - GSResult ret = gsGetPredicateFinishKeyAsTimestamp(mPredicate, - (const GSTimestamp **) &finishKeyPtr); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *finishKeyPtr; -} - -/** - * Set finish key by string. Convert from C-API: gsSetPredicateFinishKeyByString - */ -void RowKeyPredicate::set_finish_key_by_string(const GSChar* finishKey) { - GSResult ret = gsSetPredicateFinishKeyByString(mPredicate, finishKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set finish key by integer. Convert from C-API: gsSetPredicateFinishKeyByInteger - */ -void RowKeyPredicate::set_finish_key_by_integer(const int32_t finishKey) { - GSResult ret = gsSetPredicateFinishKeyByInteger(mPredicate, &finishKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set finish key by long. Convert from C-API: gsSetPredicateFinishKeyByLong - */ -void RowKeyPredicate::set_finish_key_by_long(const int64_t finishKey) { - GSResult ret = gsSetPredicateFinishKeyByLong(mPredicate, &finishKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set finish key by timestamp. Convert from C-API: gsSetPredicateFinishKeyByTimestamp - */ -void RowKeyPredicate::set_finish_key_by_timestamp(const GSTimestamp finishKey) { - GSResult ret = gsSetPredicateFinishKeyByTimestamp(mPredicate, &finishKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Add key by string. Convert from C-API: gsAddPredicateKeyByString - */ -void RowKeyPredicate::add_key_by_string(const GSChar* key) { - GSResult ret = gsAddPredicateKeyByString(mPredicate, key); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Add key by integer. Convert from C-API: gsAddPredicateKeyByTimestamp - */ -void RowKeyPredicate::add_key_by_integer(int32_t key) { - GSResult ret = gsAddPredicateKeyByInteger(mPredicate, key); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Add key by long. Convert from C-API: gsAddPredicateKeyByLong - */ -void RowKeyPredicate::add_key_by_long(int64_t key) { - GSResult ret = gsAddPredicateKeyByLong(mPredicate, key); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Get key type. Convert from C-API: gsGetPredicateKeyType - */ -GSType RowKeyPredicate::get_key_type() { - GSType key; - GSResult ret = gsGetPredicateKeyType(mPredicate, &key); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return key; -} - -/** - * Get start key by string. Convert from C-API: gsSetPredicateStartKeyByString - */ -const GSChar* RowKeyPredicate::get_start_key_as_string() { - GSChar *startKey; - GSResult ret = gsGetPredicateStartKeyAsString(mPredicate, - (const GSChar **) &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - - return startKey; -} - -/** - * Get start key by int. Convert from C-API: gsGetPredicateStartKeyAsInteger - */ -int32_t RowKeyPredicate::get_start_key_as_integer() { - int32_t* startKey; - GSResult ret = gsGetPredicateStartKeyAsInteger(mPredicate, - (const int32_t **) &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *startKey; -} - -/** - * Get start key by long. Convert from C-API: gsGetPredicateStartKeyAsLong - */ -int64_t RowKeyPredicate::get_start_key_as_long() { - int64_t* startKey; - GSResult ret = gsGetPredicateStartKeyAsLong(mPredicate, - (const int64_t **) &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *startKey; -} - -/** - * Set start key by timestamp. Convert from C-API: gsSetPredicateStartKeyByTimestamp - */ -GSTimestamp RowKeyPredicate::get_start_key_as_timestamp() { - GSTimestamp* startKey; - GSResult ret = gsGetPredicateStartKeyAsTimestamp(mPredicate, - (const GSTimestamp **) &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - return *startKey; -} - -/** - * Set start key by string. Convert from C-API: gsSetPredicateStartKeyByString - */ -void RowKeyPredicate::set_start_key_by_string(const GSChar* startKey) { - GSResult ret = gsSetPredicateStartKeyByString(mPredicate, startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set start key by integer. Convert from C-API: gsSetPredicateStartKeyByInteger - */ -void RowKeyPredicate::set_start_key_by_integer(const int32_t startKey) { - GSResult ret = gsSetPredicateStartKeyByInteger(mPredicate, &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set start key by long. Convert from C-API: gsSetPredicateStartKeyByLong - */ -void RowKeyPredicate::set_start_key_by_long(const int64_t startKey) { - GSResult ret = gsSetPredicateStartKeyByLong(mPredicate, &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Set start key by timestamp. Convert from C-API: gsSetPredicateStartKeyByTimestamp - */ -void RowKeyPredicate::set_start_key_by_timestamp(const GSTimestamp startKey) { - GSResult ret = gsSetPredicateStartKeyByTimestamp(mPredicate, &startKey); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Get predicate key as integer. Convert from C-API: gsGetPredicateDistinctKeysAsInteger - */ -void RowKeyPredicate::get_predicate_distinct_keys_as_integer( - const int **intList, size_t *size) { - GSResult ret = gsGetPredicateDistinctKeysAsInteger(mPredicate, intList, - size); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Get predicate key as long. Convert from C-API: gsGetPredicateDistinctKeysAsLong - */ -void RowKeyPredicate::get_predicate_distinct_keys_as_long(const long **longList, - size_t *size) { - GSResult ret = gsGetPredicateDistinctKeysAsLong(mPredicate, longList, size); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Get predicate key as timestamp. Convert from C-API: gsGetPredicateDistinctKeysAsTimestamp - */ -void RowKeyPredicate::get_predicate_distinct_keys_as_timestamp( - const long **longList, size_t *size) { - GSResult ret = gsGetPredicateDistinctKeysAsTimestamp(mPredicate, longList, - size); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -/** - * Add key by timestamp. Convert from C-API: gsAddPredicateKeyByTimestamp - */ -void RowKeyPredicate::add_key_by_timestamp(GSTimestamp key) { - GSResult ret = gsAddPredicateKeyByTimestamp(mPredicate, key); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } -} - -/** - * Get predicate key as string. Convert from C-API: gsGetPredicateDistinctKeysAsString - */ -void RowKeyPredicate::get_predicate_distinct_keys_as_string( - const GSChar * const ** stringList, size_t *size) { - GSResult ret = gsGetPredicateDistinctKeysAsString(mPredicate, stringList, - size); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } -} - -GSRowKeyPredicate* RowKeyPredicate::gs_ptr() { - return mPredicate; -} + /** + * @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){ + } + + /** + * @brief Destructor to free resource of RowKeyPredicate object + */ + RowKeyPredicate::~RowKeyPredicate() { + close(); + } + + /** + * @brief Release RowKeyPredicate resource + */ + void RowKeyPredicate::close() { + if (mPredicate != NULL) { + gsCloseRowKeyPredicate(&mPredicate); + mPredicate = NULL; + } + } + + /** + * @brief Get key type + * @return The type of Row key used as a matching condition + */ + GSType RowKeyPredicate::get_key_type() { + return mType; + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + if (startKey != NULL) { + startField->type = key_type; + if (startField->type == GS_TYPE_STRING) { + if (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; + } + } else { + startField->value = *startKey; + } + } + ret = gsGetPredicateFinishKeyGeneral(mPredicate, &endKey); + if (!GS_SUCCEEDED(ret)) { + if (startField->type == GS_TYPE_STRING && startField->value.asString) { + delete[] startField->value.asString; + } + throw GSException(mPredicate, ret); + } + if (endKey != NULL) { + finishField->type = key_type; + if (finishField->type == GS_TYPE_STRING) { + if (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; + } + } else { + finishField->value = *endKey; + } + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByLong(mPredicate, (int64_t *) &finishKey->value.asLong); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_INTEGER: + ret = gsSetPredicateStartKeyByInteger(mPredicate, (const int32_t *) &startKey->value.asInteger); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByInteger(mPredicate, (const int32_t *)&finishKey->value.asInteger); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_STRING: + ret = gsSetPredicateStartKeyByString(mPredicate, startKey->value.asString); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByString(mPredicate, finishKey->value.asString); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_TIMESTAMP: + ret = gsSetPredicateStartKeyByTimestamp(mPredicate, + (const GSTimestamp *) &(startKey->value.asTimestamp)); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByTimestamp(mPredicate, + (const GSTimestamp *) &(finishKey->value.asTimestamp)); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + default: + throw GSException(mPredicate, "Not support type"); + break; + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_INTEGER: + ret = gsAddPredicateKeyByInteger(mPredicate, + key->value.asInteger); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_STRING: + ret = gsAddPredicateKeyByString(mPredicate, key->value.asString); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + + break; + case GS_TYPE_TIMESTAMP: + ret = gsAddPredicateKeyByTimestamp(mPredicate, + key->value.asTimestamp); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + default: + throw GSException(mPredicate, "Not support type"); + break; + } + } + } + + /** + * @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; + 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; + } + } + *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; + } + + 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; + } } /* namespace griddb */ diff --git a/src/RowKeyPredicate.h b/src/RowKeyPredicate.h index eb67988..0134a17 100644 --- a/src/RowKeyPredicate.h +++ b/src/RowKeyPredicate.h @@ -1,17 +1,17 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _ROWKEYPREDICATE_H_ @@ -19,49 +19,40 @@ #include #include -#include "Resource.h" +#include +#include + #include "gridstore.h" +#include "Field.h" +#include "GSException.h" +#include "Util.h" using namespace std; namespace griddb { - class RowKeyPredicate : public Resource { - GSRowKeyPredicate *mPredicate; - public: - RowKeyPredicate(GSRowKeyPredicate *predicate); - ~RowKeyPredicate(); - GSType get_key_type(); - const GSChar* get_start_key_as_string(); - const GSChar* get_finish_key_as_string(); - int32_t get_finish_key_as_integer(); - int64_t get_finish_key_as_long(); - int32_t get_start_key_as_integer(); - int64_t get_start_key_as_long(); - GSTimestamp get_start_key_as_timestamp(); - GSTimestamp get_finish_key_as_timestamp(); - void get_predicate_distinct_keys_as_string( - const GSChar * const ** stringList, size_t *size); - void get_predicate_distinct_keys_as_integer(const int **intList, - size_t *size); - void get_predicate_distinct_keys_as_long(const long **longList, - size_t *size); - void get_predicate_distinct_keys_as_timestamp(const long **longList, - size_t *size); - void set_finish_key_by_string(const GSChar *finishKey); - void set_finish_key_by_integer(const int32_t finishKey); - void set_finish_key_by_long(const int64_t finishKey); - void set_finish_key_by_timestamp(const GSTimestamp finishKey); - void set_start_key_by_string(const GSChar *startKey); - void set_start_key_by_integer(const int32_t startKey); - void set_start_key_by_long(const int64_t startKey); - void set_start_key_by_timestamp(const GSTimestamp startKey); - void add_key_by_string(const GSChar *key); - void add_key_by_integer(int32_t key); - void add_key_by_long(int64_t key); - void add_key_by_timestamp(GSTimestamp key); - GSRowKeyPredicate* gs_ptr(); - }; +class RowKeyPredicate { + GSRowKeyPredicate *mPredicate; + GSType mType; + + friend class Store; + + public: + bool timestamp_output_with_float; + ~RowKeyPredicate(); + void close(); + + void get_range(Field* startField, Field* finishField); + void set_range(Field* startKey, Field* finishKey); + void set_distinct_keys(const Field *keys, size_t keyCount); + void get_distinct_keys(Field **keys, size_t* keyCount); + GSRowKeyPredicate* gs_ptr(); + GSType get_key_type(); + + private: + RowKeyPredicate(GSRowKeyPredicate *predicate, GSType type); + +}; } /* namespace griddb */ diff --git a/src/RowSet.cpp b/src/RowSet.cpp index 8abfa05..b0ce22e 100644 --- a/src/RowSet.cpp +++ b/src/RowSet.cpp @@ -1,117 +1,266 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "RowSet.h" -#include "GSException.h" namespace griddb { - RowSet::RowSet(GSRowSet *rowSet): Resource(rowSet), mRowSet(rowSet){ - - } - - /** - * Check if RowSet has next row data. Convert from gsHasNextRow. - */ - bool RowSet::has_next() { - return (bool) gsHasNextRow(mRowSet); - } - - RowSet::~RowSet() { - close(); - } - - void RowSet::update_current(Row* row) { - GSResult ret = gsUpdateCurrentRow(mRowSet, row->gs_ptr()); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - } - - /** - * Get next row data. Convert from gsGetNextRow. - */ - void RowSet::get_next(Row* row) { - GSResult ret = gsGetNextRow(mRowSet, row->gs_ptr()); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - } - - /** - * Return size of this rowset - */ - int32_t RowSet::get_size() { - int32_t size; - size = gsGetRowSetSize(mRowSet); - - return size; - } - - /** - * Delete current row data. Convert from C-API: gsDeleteCurrentRow. - */ - void RowSet::delete_current() { - GSResult ret = gsDeleteCurrentRow(mRowSet); - if (ret != GS_RESULT_OK) { - throw new GSException(ret); - } - } - - /** - * Get current row type. Convert from C-API: gsGetRowSetType. - */ - GSRowSetType RowSet::get_type() { - GSRowSetType ret = gsGetRowSetType(mRowSet); - return ret; - } - - /** - * Moves to the next Row in a Row set and returns the aggregation result at the moved position. - */ - AggregationResult* RowSet::get_next_aggregation() { - GSAggregationResult* pAggResult; - - GSResult ret = gsGetNextAggregation(mRowSet, &pAggResult); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new AggregationResult(pAggResult); - } - - /** - * Get query analysis. Convert from C-APi gsGetNextQueryAnalysis - */ - GSQueryAnalysisEntry RowSet::get_next_query_analysis() { - GSQueryAnalysisEntry queryAnalysis; - GSResult ret = gsGetNextQueryAnalysis(mRowSet, &queryAnalysis); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return queryAnalysis; - } - - /** - * Close rowset. - */ - void RowSet::close() { - if (mRowSet != NULL) { - gsCloseRowSet(&mRowSet); - mRowSet = NULL; - } - } + + /** + * @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) { + if (mRowSet != NULL) { + mType = gsGetRowSetType(mRowSet); + } else { + throw GSException(mRowSet, "mRowSet is NULL"); + } + } + + /** + * @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; + type = this->type(); + switch(type) { + case (GS_ROW_SET_CONTAINER_ROWS): + case (GS_ROW_SET_AGGREGATION_RESULT): + case (GS_ROW_SET_QUERY_ANALYSIS): + return (bool) gsHasNextRow(mRowSet); + default: + return false; + } + } + + RowSet::~RowSet() { + close(); + if (typeList) { + delete[] typeList; + } + } + + /** + * @brief Release RowSet resource + */ + void RowSet::close() { + if (mRowSet != NULL) { + gsCloseRowSet(&mRowSet); + mRowSet = NULL; + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mRowSet, ret); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mRowSet, ret); + } + } + } + + /** + * @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): + this->next_row(hasNextRow); + break; + case (GS_ROW_SET_AGGREGATION_RESULT): + *hasNextRow = this->has_next(); + *aggResult = this->get_next_aggregation(); + break; + case (GS_ROW_SET_QUERY_ANALYSIS): + *queryAnalysis = this->get_next_query_analysis(); + *hasNextRow = true; + break; + default: + throw GSException(mRowSet, "type for rowset is not correct"); + } + } + + /** + * @brief Get size of this rowset + * @return Size of this rowset + */ + int32_t RowSet::size() { + return gsGetRowSetSize(mRowSet); + } + + /** + * @brief Delete current row data. + */ + void RowSet::remove() { + GSResult ret = gsDeleteCurrentRow(mRowSet); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mRowSet, ret); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mRowSet, ret); + } + + try { + AggregationResult* aggResult = new AggregationResult(pAggResult); + return aggResult; + } catch (bad_alloc& ba) { + gsCloseAggregationResult(&pAggResult); + throw GSException(mRowSet, "Memory allocation error"); + } + } + + /** + * @brief Get current row type. + * @return The type of content that can be extracted from GSRowSet. + */ + GSRowSetType RowSet::type(){ + return mType; + } + + /** + * @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 gsQueryAnalysis = GS_QUERY_ANALYSIS_ENTRY_INITIALIZER; + GSResult ret; + ret = gsGetNextQueryAnalysis(mRowSet, &gsQueryAnalysis); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mRowSet, ret); + } + + try { + QueryAnalysisEntry* queryAnalysis = new QueryAnalysisEntry(&gsQueryAnalysis); + return queryAnalysis; + } catch (bad_alloc& ba) { + throw GSException(mRowSet, "Memory allocation error"); + } + } + + /** + * @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){ + 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) { + 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"); + } + } + + /** + * @brief Get list type of column in row + * @return A list type of column in row + */ + GSType* RowSet::getGSTypeList(){ + 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; + } + } + return typeList; + } + + /** + * @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 95e11a8..9dad3d8 100644 --- a/src/RowSet.h +++ b/src/RowSet.h @@ -1,29 +1,34 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _ROWSET_H_ #define _ROWSET_H_ -#include "Resource.h" -#include "gridstore.h" -#include "Row.h" -#include "AggregationResult.h" - #include #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; @@ -32,25 +37,41 @@ namespace griddb { /** * Convert from GSRowSet */ -class RowSet : public Resource { - GSRowSet *mRowSet; -public: - RowSet(GSRowSet *rowSet); - ~RowSet(); - - // Iterator - bool has_next(); - void get_next(Row* row); - void update_current(Row* row); - int32_t get_size(); - void delete_current(); - GSRowSetType get_type(); - AggregationResult* get_next_aggregation(); - GSQueryAnalysisEntry get_next_query_analysis(); - -private: - void close(); +class RowSet { + GSRowSet *mRowSet; + GSContainerInfo *mContainerInfo; + GSRow *mRow; + GSType* typeList; + + friend class Query; + + GSRowSetType mType; + + public: + bool timestamp_output_with_float; + ~RowSet(); + void close(); + int32_t size(); + // Iterator + bool has_next(); + void next(GSRowSetType* type, bool* hasNextRow, + QueryAnalysisEntry** queryAnalysis, AggregationResult** aggResult); + void update(GSRow* row); + void remove(); + GSRowSetType type(); + void get_column_names(char*** listName, int* num); + QueryAnalysisEntry* get_next_query_analysis(); + AggregationResult* get_next_aggregation(); + void next_row(bool* hasNextRow); + GSType* getGSTypeList(); + int getColumnCount(); + + GSRow* getGSRowPtr(); + + private: + RowSet(GSRowSet *rowSet, GSContainerInfo *containerInfo, GSRow *mRow); }; + } #endif /* _ROWSET_H_ */ diff --git a/src/Store.cpp b/src/Store.cpp index 7829947..b6660ba 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -1,180 +1,345 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "Store.h" -#include "GSException.h" namespace griddb { - Store::Store(GSGridStore *store) : Resource(store), mStore(store) { - } - - Store::~Store() { - close(); - } - - /** - * Delete container with specified name - */ - void Store::drop_container(const char* name) { - GSResult ret = gsDropContainer(mStore, name); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Return information object of a specific container - */ - ContainerInfo* Store::get_container_info( - const char* containerName) { - GSContainerInfo containerInfo; - GSChar bExists; - - GSResult ret = gsGetContainerInfo(mStore, containerName, &containerInfo, &bExists); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new ContainerInfo(&containerInfo); - } - - /** - * Put container. Convert from method gsPutContainerGeneral() - */ - Container* Store::put_container(const char* containerName, - const GSColumnInfo* props, int propsCount, GSContainerType containerType, bool modifiable, - GSBool rowKeyAssigned, GSBool columnOrderIgnorable ,int32_t rowExpirationTime , - GSTimeUnit rowExpirationTimeUnit, int32_t expirationDivisionCount) { - - // Create Container information - GSContainerInfo containerInfo = { containerName, - containerType, propsCount, props, - rowKeyAssigned, - columnOrderIgnorable - }; - GSTimeSeriesProperties timeSeriesProp; - if (rowExpirationTime && rowExpirationTimeUnit - && expirationDivisionCount) { - timeSeriesProp = { rowExpirationTime, - rowExpirationTimeUnit, - -1, //compressionWindowSize : unlimited - 0, //compressionWindowSizeUnit - GS_COMPRESSION_NO, //compressionMethod: no compress - 0, //compressionListSize - 0, //compressionList - expirationDivisionCount }; - containerInfo.timeSeriesProperties = (const GSTimeSeriesProperties *) &timeSeriesProp; - } - GSContainer* pContainer; - GSBool gsModifiable = (modifiable == true ? GS_TRUE : GS_FALSE); - GSResult ret = gsPutContainerGeneral(mStore, containerName, &containerInfo, - gsModifiable, &pContainer); - - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new Container(pContainer); - } - - /** - * Get container object with corresponding name - */ - Container* Store::get_container(const char* containerName) { - GSContainer* pContainer; - - GSResult ret = gsGetContainerGeneral(mStore, containerName, &pContainer); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new Container(pContainer); - } - - /** - * Query execution and fetch is carried out on a specified arbitrary number of Query, with the request unit enlarged as much as possible. - */ - void Store::fetch_all(GSQuery* const* queryList, size_t queryCount) { - GSResult ret = gsFetchAll(mStore, queryList, queryCount); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get Partition controller. Convert from C-API: gsGetPartitionController - */ - PartitionController* Store::get_partition_controller() { - GSPartitionController* partitionController; - - GSResult ret = gsGetPartitionController(mStore, &partitionController); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new PartitionController(partitionController); - } - - /** - * Create row key predicate. Convert from C-API: gsCreateRowKeyPredicate - */ - RowKeyPredicate* Store::create_row_key_predicate(GSType keyType) { - GSRowKeyPredicate* predicate; - - GSResult ret = gsCreateRowKeyPredicate(mStore, keyType, &predicate); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new RowKeyPredicate(predicate); - } - - /** - * 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. - */ - void Store::put_multi_container_row(const GSContainerRowEntry* entryList, - size_t entryCount) { - GSResult ret = gsPutMultipleContainerRows(mStore, entryList, entryCount); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - void Store::get_multi_container_row( - const GSRowKeyPredicateEntry* const * predicateList, - size_t predicateCount, - const GSContainerRowEntry **entryList, size_t *entryCount) { - GSResult ret = gsGetMultipleContainerRows(mStore, predicateList, predicateCount, entryList, entryCount); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Release all resources created by this gridstore object - */ - void Store::close() { - if(mStore != NULL) { - gsCloseGridStore(&mStore, GS_FALSE); - mStore = NULL; - } - } + + /** + * @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); + } + + /** + * @brief Release Store resource + */ + void Store::close(GSBool allRelated) { + // close store + if (mStore != NULL) { + gsCloseGridStore(&mStore, allRelated); + mStore = NULL; + } + } + + /** + * @brief Delete container with specified name + * @param *name Container name + */ + void Store::drop_container(const char* name) { + GSResult ret = gsDropContainer(mStore, name); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + } + + /** + * @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 gsContainerInfo = GS_CONTAINER_INFO_INITIALIZER; + GSChar bExists; + GSResult ret = gsGetContainerInfo(mStore, name, &gsContainerInfo, &bExists); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + if (bExists == false) { + return NULL; + } + + try { + ContainerInfo* containerInfo = new ContainerInfo(&gsContainerInfo); + return containerInfo; + } catch (bad_alloc& ba) { + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + + try { + Container* container = new Container(pContainer, gsInfo); + return container; + } catch (bad_alloc& ba) { + gsCloseContainer(&pContainer, GS_FALSE); + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + if (pContainer == NULL) { + //If not found container, return NULL in target language + return NULL; + } + GSContainerInfo containerInfo = GS_CONTAINER_INFO_INITIALIZER; + GSChar bExists; + ret = gsGetContainerInfo(mStore, name, &containerInfo, &bExists); + if (!GS_SUCCEEDED(ret)) { + gsCloseContainer(&pContainer, GS_FALSE); + throw GSException(mStore, ret); + } + try { + Container* container = new Container(pContainer, &containerInfo); + return container; + } catch (bad_alloc& ba) { + gsCloseContainer(&pContainer, GS_FALSE); + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + } + + /** + * @brief Get Partition controller. + * @return The pointer to a pointer variable to store PartitionController instance + */ + PartitionController* Store::partition_info() { + GSPartitionController* partitionController; + + GSResult ret = gsGetPartitionController(mStore, &partitionController); + + if (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + + try { + PartitionController* partition = new PartitionController(partitionController); + return partition; + } catch (bad_alloc& ba) { + gsClosePartitionController(&partitionController); + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + + try { + RowKeyPredicate* rowKeyPredicate = new RowKeyPredicate(predicate, type); + return rowKeyPredicate; + } catch (bad_alloc& ba) { + gsCloseRowKeyPredicate(&predicate); + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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; + + 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); + delete[] entryList; + if (!GS_SUCCEEDED(ret)) { + throw GSException(mStore, ret); + } + } + + /** + * @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; + 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); + if (!setNumList) { + 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 (!GS_SUCCEEDED(ret)) { + this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput); + throw GSException(mStore, ret); + } + + // set data for orderFromInput + for (int i = 0; i < length; i++) { + for (int j = 0; j < length; j++) { + if (strcmp((*predicateList)[i].containerName, (*entryList)[j].containerName) == 0){ + (*orderFromInput)[i] = j; + } + } + } + } + + /** + * Support free memory in multi_get function when exception happen + */ + void Store::freeMemoryMultiGet(int **colNumList, GSType*** typeList, + int length, int **orderFromInput) { + if (*colNumList) { + delete [] *colNumList; + *colNumList = NULL; + } + + if (*typeList) { + for (int i = 0; i < length; i++) { + if ((*typeList)[i]) { + delete[] (*typeList)[i]; + } + } + delete [] *typeList; + *typeList = NULL; + } + if (*orderFromInput) { + delete [] *orderFromInput; + *orderFromInput = NULL; + } + } + + /** + * Support multi_get function to put data into colNumList and typeList + */ + bool Store::setMultiContainerNumList(const GSRowKeyPredicateEntry* const * predicateList, + int length, int ***colNumList, GSType**** typeList) { + for (int i = 0; i < length; i++) { + Container *tmpContainer; + try { + tmpContainer = this->get_container((*predicateList)[i].containerName); + } catch (GSException e) { + return false; + } + if (tmpContainer == NULL) { + return false; + } + (**colNumList)[i] = tmpContainer->getColumnCount(); + + 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]; + } + delete tmpContainer; + } + return true; + } + } diff --git a/src/Store.h b/src/Store.h index e6ada46..7de25c6 100644 --- a/src/Store.h +++ b/src/Store.h @@ -1,63 +1,67 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _STORE_H_ #define _STORE_H_ -#include "Resource.h" +#include +#include +#include + #include "ContainerInfo.h" #include "Container.h" #include "PartitionController.h" #include "RowKeyPredicate.h" -#include -#include +#include "GSException.h" using namespace std; namespace griddb { - class Store : public Resource { - GSGridStore *mStore; - public: - Store(GSGridStore* store); - ~Store(); - - void drop_container(const char *name); - ContainerInfo* get_container_info(const char *containerName); - - Container* put_container(const char* containerName, - const GSColumnInfo* props, int propsCount, GSContainerType containerType, - bool modifiable = false, GSBool rowKeyAssigned = GS_TRUE, GSBool columnOrderIgnorable = GS_FALSE, - int32_t rowExpirationTime = NULL, GSTimeUnit rowExpirationTimeUnit = - NULL, int32_t expirationDivisionCount = NULL); - Container* get_container(const char* containerName); - void fetch_all(GSQuery* const * queryList, size_t queryCount); - void put_multi_container_row(const GSContainerRowEntry* entryList, - size_t entryCount); - void get_multi_container_row( - const GSRowKeyPredicateEntry * const * predicateList, - size_t predicateCount, const GSContainerRowEntry **entryList, - size_t *entryCount); - - PartitionController* get_partition_controller(); - RowKeyPredicate* create_row_key_predicate(GSType keyType); - - private: - void close(); - }; +class Store { + GSGridStore *mStore; + + friend class StoreFactory; + + public: + bool timestamp_output_with_float; + ~Store(); + void close(GSBool allRelated = GS_FALSE); + + Container* put_container(ContainerInfo* info, bool modifiable = false); + Container* get_container(const char* name); + void drop_container(const char *name); + + void fetch_all(GSQuery* const * queryList, size_t queryCount); + void multi_put(GSRow*** listRow, const int *listRowContainerCount, + const char ** listContainerName, size_t containerCount); + void multi_get(const GSRowKeyPredicateEntry* const * predicateList, + size_t predicateCount, GSContainerRowEntry **entryList, size_t* containerCount, + int **colNumList, GSType*** typeList, int **orderFromInput); + + ContainerInfo* get_container_info(const char *name); + PartitionController* partition_info(); + RowKeyPredicate* create_row_key_predicate(GSType type); + + private: + Store(GSGridStore* store); + void freeMemoryMultiGet(int** colNumList, GSType*** typeList, int length, int** orderFromInput); + bool setMultiContainerNumList(const GSRowKeyPredicateEntry* const * predicateList, + int length, int*** colNumList, GSType**** typeList); +}; } diff --git a/src/StoreFactory.cpp b/src/StoreFactory.cpp index b3f49c4..617e99f 100644 --- a/src/StoreFactory.cpp +++ b/src/StoreFactory.cpp @@ -1,88 +1,181 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "StoreFactory.h" -#include "GSException.h" + +#define MAX_PROPS 10 namespace griddb { - StoreFactory::StoreFactory() : - Resource(NULL), mFactory(NULL), mIsAllRelated(GS_FALSE) { - } - - StoreFactory::~StoreFactory() { - close(); - } - - /** - * Close factory. - */ - void StoreFactory::close() { - if (mFactory != NULL) { - gsCloseFactory(&mFactory, mIsAllRelated); - mFactory = NULL; - } - } - - StoreFactory* StoreFactory::get_default() { - GSGridStoreFactory* pFactory = gsGetDefaultFactory(); - StoreFactory* factory(new StoreFactory()); - factory->set_factory(pFactory); - - return factory; - } - - /** - * Get gridstore object. Convert from C-API: gsGetGridStore - */ - Store* StoreFactory::get_store( - const GSPropertyEntry* props, int propsCount) { - GSGridStore *store; - GSResult ret = gsGetGridStore(mFactory, props, propsCount, &store); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return new Store(store); - } - - /** - * Changes the settings for this Factory. - * The changed settings will be reflected in GridStore object which is already created by the specified Factory and GridStore object which will be created later by the Factory. - */ - void StoreFactory::set_properties(const GSPropertyEntry* props, - int propsCount) { - GSResult ret = gsSetFactoryProperties(mFactory, props, propsCount); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /* - * Return current client version - */ - string StoreFactory::get_version() { - return CLIENT_VERSION; - } - - void StoreFactory::set_factory(GSGridStoreFactory* factory) { - mFactory = factory; - } + StoreFactory::StoreFactory() : mFactory(NULL) { + } + + StoreFactory::~StoreFactory() { + //allRelated = FALSE, since Gridstore object is managed by Store class + close(GS_FALSE); + } + + /** + * @brief Release StoreFactory resource + */ + void StoreFactory::close(GSBool allRelated) { + if (mFactory != NULL) { + gsCloseFactory(&mFactory, allRelated); + mFactory = NULL; + } + } + + /** + * @brief Get a default GSGridStoreFactory instance. + * @return The pointer to a pointer variable to store StoreFactory instance + */ + StoreFactory* StoreFactory::get_instance() { + GSGridStoreFactory* pFactory = gsGetDefaultFactory(); + + try { + StoreFactory* factory(new StoreFactory()); + factory->set_factory(pFactory); + + return factory; + } catch (bad_alloc& ba) { + gsCloseFactory(&pFactory, GS_FALSE); + throw GSException("Memory allocation error"); + } + } + + /* + * set GSPropertyEntry + */ + void StoreFactory::set_property_entry(GSPropertyEntry *prop, const char* name, const char* value) { + prop->name = name; + prop->value = value; + } + + /* + * Check whether in MULTICAST mode + */ + bool StoreFactory::check_multicast(const char* address) { + if (address && address[0] != '\0') { + char* tmp; + try { + Util::strdup((const GSChar**)&tmp, address); + } catch (bad_alloc& ba) { + throw GSException("Memory allocation error"); + } + + char *octets = strtok((char*)tmp, "."); + if (octets) { + int firstOctet = atoi(octets); + int first4Bits = firstOctet >> 4 & 0x0f; + if (first4Bits == 0x0E) { + delete[] tmp; + return true; + } + } + delete[] tmp; + } + return false; + } + + /** + * @brief Get a Store with the specified properties + * @param *host A destination host name + * @param port A destination port number + * @param *cluster_name A cluster name + * @param *database A database name to be connected + * @param *user A user name + * @param *password A password for user authentication + * @param *notification_member A list of address and port pairs in cluster + * @param *notification_provider A URL of address provider + * @return The pointer to a pointer variable to store Store instance + */ + Store* StoreFactory::get_store(const char* host, int32_t port, const char* cluster_name, + const char* database, const char* user, const char* password, + const char* notification_member, const char* notification_provider) { + size_t index = 0; + GSPropertyEntry local_props[MAX_PROPS] = {0}; + std::string lport = std::to_string((long long int)port); + + if (check_multicast(host)) { + set_property_entry(&local_props[0], "notificationAddress", host); + set_property_entry(&local_props[1], "notificationPort", lport.c_str()); + index += 2; + } else if (host && host[0] != '\0') { + set_property_entry(&local_props[0], "host", host); + set_property_entry(&local_props[1], "port", lport.c_str()); + index += 2; + } + + if (notification_member && notification_member[0] != '\0') { + set_property_entry(&local_props[index], "notificationMember", notification_member); + index++; + } + if (notification_provider && notification_provider[0] != '\0') { + set_property_entry(&local_props[index], "notificationProvider", notification_provider); + index++; + } + if (cluster_name && cluster_name[0] != '\0') { + set_property_entry(&local_props[index], "clusterName", cluster_name); + index++; + } + if (database && database[0] != '\0') { + set_property_entry(&local_props[index], "database", database); + index++; + } + if (user && user[0] != '\0') { + set_property_entry(&local_props[index], "user", user); + index++; + + } + if (password && password[0] != '\0') { + set_property_entry(&local_props[index], "password", password); + index++; + } + + GSGridStore *gsStore; + GSResult ret = gsGetGridStore(mFactory, local_props, index, &gsStore); + + // Check ret, if error, throw exception + if (!GS_SUCCEEDED(ret)) { + throw GSException(mFactory, ret); + } + + try { + //return new Store(store); + Store* store = new Store(gsStore); + return store; + } catch (bad_alloc& ba) { + gsCloseGridStore(&gsStore, GS_FALSE); + throw GSException(mFactory, "Memory allocation error"); + } + } + + /** + * @brief Get current client version + * @return Client version name + */ + string StoreFactory::get_version() { + return CLIENT_VERSION; + } + + /* + * Set attribute: mFactory + */ + void StoreFactory::set_factory(GSGridStoreFactory* factory) { + mFactory = factory; + } } diff --git a/src/TimeSeriesProperties.cpp b/src/TimeSeriesProperties.cpp index c355d43..0c05f50 100644 --- a/src/TimeSeriesProperties.cpp +++ b/src/TimeSeriesProperties.cpp @@ -1,58 +1,92 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 "TimeSeriesProperties.h" namespace griddb { - TimeSeriesProperties::TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps) : mTsProps(*timeSeriesProps) { - } + /** + * @brief Constructor a new TimeSeriesProperties::TimeSeriesProperties object + * @param *timeSeriesProps Represents the information about optional configuration settings used for newly creating or updating a TimeSeries + */ + TimeSeriesProperties::TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps) : mTsProps(*timeSeriesProps) { + } - TimeSeriesProperties::TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, - int32_t ExpirationDivisionCount) : mTsProps{elapsedTime, timeUnit, -1, - timeUnit, GS_COMPRESSION_NO, 0, NULL, ExpirationDivisionCount} { - } + /** + * @brief Constructor a new TimeSeriesProperties::TimeSeriesProperties object + * @param elapsedTime The elapsed time period of a Row to be used as the basis of the validity period + * @param timeUnit The unit of elapsed time referenced for the expiration date of a Row + * @param ExpirationDivisionCount The division number for the validity period as the number of expired Row data units to be released + */ + TimeSeriesProperties::TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, + int32_t ExpirationDivisionCount) : mTsProps{elapsedTime, timeUnit, -1, + timeUnit, GS_COMPRESSION_NO, 0, NULL, ExpirationDivisionCount} { + } - TimeSeriesProperties::~TimeSeriesProperties() { - } + TimeSeriesProperties::~TimeSeriesProperties() { + } - void TimeSeriesProperties::set_row_expiration_time(int elapsedTime, - GSTimeUnit timeUnit) { - mTsProps.rowExpirationTime = elapsedTime; - mTsProps.rowExpirationTimeUnit = timeUnit; - } + /** + * @brief Set rowExpiration for TimeSeriesProperties. + * @param elapsedTime The elapsed time period of a Row to be used as the basis of the validity period + * @param timeUnit The unit of elapsed time referenced for the expiration date of a Row + */ + void TimeSeriesProperties::set_row_expiration_time(int elapsedTime, GSTimeUnit timeUnit) { + mTsProps.rowExpirationTime = elapsedTime; + mTsProps.rowExpirationTimeUnit = timeUnit; + } - void TimeSeriesProperties::set_expiration_division_count(int count) { - mTsProps.expirationDivisionCount = count; - } + /** + * @brief Set expirationDivisionCount for TimeSeriesProperties + * @param count The division number for the validity period as the number of expired Row data units to be released + */ + void TimeSeriesProperties::set_expiration_division_count(int count) { + mTsProps.expirationDivisionCount = count; + } - int TimeSeriesProperties::get_row_expiration_time() { - return mTsProps.rowExpirationTime; - } + /** + * @brief Get rowExpirationTime from TimeSeriesProperties + * @return The elapsed time period of a Row to be used as the basis of the validity period + */ + int TimeSeriesProperties::get_row_expiration_time() { + return mTsProps.rowExpirationTime; + } - GSTimeUnit TimeSeriesProperties::get_row_expiration_time_unit() { - return mTsProps.rowExpirationTimeUnit; - } + /** + * @brief Get rowExpirationTimeUnit from TimeSeriesProperties + * @return timeUnit The unit of elapsed time referenced for the expiration date of a Row + */ + GSTimeUnit TimeSeriesProperties::get_row_expiration_time_unit() { + return mTsProps.rowExpirationTimeUnit; + } - int TimeSeriesProperties::get_expiration_division_count() { - return mTsProps.expirationDivisionCount; - } + /** + * @brief Get expirationDivisionCount from TimeSeriesProperties + * @return The division number for the validity period as the number of expired Row data units to be released + */ + int TimeSeriesProperties::get_expiration_division_count() { + return mTsProps.expirationDivisionCount; + } - GSTimeSeriesProperties* TimeSeriesProperties::gs_ptr() { - return &mTsProps; - } + /** + * @brief Get attribute: mTsProps + * @return A pointer store GSTimeSeriesProperties of TimeSeriesProperties + */ + GSTimeSeriesProperties* TimeSeriesProperties::gs_ptr() { + return &mTsProps; + } } /* namespace griddb */ diff --git a/src/TimeSeriesProperties.h b/src/TimeSeriesProperties.h index 70927bb..a44b051 100644 --- a/src/TimeSeriesProperties.h +++ b/src/TimeSeriesProperties.h @@ -1,17 +1,17 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _TIMESERIESPROPERTIES_H_ @@ -21,19 +21,23 @@ namespace griddb { - class TimeSeriesProperties { - GSTimeSeriesProperties mTsProps; - public: - TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps); - TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, int32_t ExpirationDivisionCount); - ~TimeSeriesProperties(); - void set_row_expiration_time(int32_t elapsedTime, GSTimeUnit timeUnit); - void set_expiration_division_count(int32_t count); - int get_row_expiration_time(); - GSTimeUnit get_row_expiration_time_unit(); - int get_expiration_division_count(); - GSTimeSeriesProperties* gs_ptr(); - }; +class TimeSeriesProperties { + private: + GSTimeSeriesProperties mTsProps; + + public: + TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps); + TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, int32_t ExpirationDivisionCount); + ~TimeSeriesProperties(); + // APIs to set values for expiration_time and expiration_division_count + void set_row_expiration_time(int32_t elapsedTime, GSTimeUnit timeUnit); + void set_expiration_division_count(int32_t count); + // APIs to get values of expiration_time, expiration_time_unit, expiration_division_count and TimeSeriesProperties + int get_row_expiration_time(); + GSTimeUnit get_row_expiration_time_unit(); + int get_expiration_division_count(); + GSTimeSeriesProperties* gs_ptr(); +}; } /* namespace griddb */ diff --git a/src/TimestampUtils.cpp b/src/TimestampUtils.cpp index 88823d3..e1db012 100644 --- a/src/TimestampUtils.cpp +++ b/src/TimestampUtils.cpp @@ -1,65 +1,34 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 +#include "TimestampUtils.h" namespace griddb { -TimestampUtils::TimestampUtils() { -} + TimestampUtils::TimestampUtils() { + } -TimestampUtils::~TimestampUtils() { -} + TimestampUtils::~TimestampUtils() { + } -/** - * Get current timestamp. Convert from C-API: gsCurrentTime . - */ -GSTimestamp TimestampUtils::current() { - return gsCurrentTime(); -} - -/** - * Add timestamp. Convert from C-API: gsAddTime . - */ -GSTimestamp TimestampUtils::add_time(GSTimestamp timestamp, int32_t amount, - GSTimeUnit timeUnit) { - return gsAddTime(timestamp, amount, timeUnit); -} - -/** - * Format timestamp. Convert from C-API: gsFormatTime . - */ -string TimestampUtils::format_time(GSTimestamp timestamp, size_t bufSize) { - char* strBuf = new char[bufSize]; - size_t stringSize = gsFormatTime(timestamp, strBuf, bufSize); - string ret(strBuf, stringSize); - delete [] strBuf; - return ret; -} - -/** - * Parse timestamp. Convert from C-API: gsParseTime . - */ -GSTimestamp TimestampUtils::parse(char* str) { - GSTimestamp value; - GSBool ret = gsParseTime(str, &value); - if (ret == GS_FALSE) { - throw GSException("Can't convert timestamp from string"); - } - return value; -} + /** + * Convert from Python timestamp to GridDB timestamp + */ + int64_t TimestampUtils::get_time_millis(double timestamp){ + return int64_t(timestamp * 1000); + } } /* namespace griddb */ diff --git a/src/TimestampUtils.h b/src/TimestampUtils.h index a193e1a..c6b0585 100644 --- a/src/TimestampUtils.h +++ b/src/TimestampUtils.h @@ -1,21 +1,21 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _TIMESTAMP_H_ -#define _TIMESTAMP_H_ +#ifndef _TIMESTAMPUTILS_H_ +#define _TIMESTAMPUTILS_H_ #include "gridstore.h" #include #include "GSException.h" @@ -24,16 +24,13 @@ using namespace std; namespace griddb { - class TimestampUtils { +class TimestampUtils { - public: - TimestampUtils(); - ~TimestampUtils(); - static GSTimestamp current(); - static GSTimestamp add_time(GSTimestamp timestamp, int32_t amount, GSTimeUnit timeUnit); - static string format_time(GSTimestamp timestamp, size_t bufSize); - static GSTimestamp parse(char* str); - }; + public: + TimestampUtils(); + ~TimestampUtils(); + static int64_t get_time_millis(double timestamp); +}; } /* namespace griddb */ diff --git a/src/griddb.i b/src/griddb.i index c0de9f3..20a11fc 100644 --- a/src/griddb.i +++ b/src/griddb.i @@ -1,74 +1,81 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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. */ +%ignore griddb::Container::getGSContainerPtr; +%ignore griddb::Container::getGSTypeList; +%ignore griddb::Container::getColumnCount; +%ignore griddb::Container::getGSRowPtr; +%ignore griddb::ContainerInfo::gs_info; +%ignore griddb::Field; +%ignore griddb::Query::gs_ptr; +%ignore griddb::RowKeyPredicate::gs_ptr; +%ignore griddb::RowSet::getGSTypeList; +%ignore griddb::RowSet::getColumnCount; +%ignore griddb::RowSet::getGSRowPtr; %ignore griddb::AggregationResult::AggregationResult; - +%ignore griddb::QueryAnalysisEntry::QueryAnalysisEntry; +%ignore griddb::TimeSeriesProperties; %ignore griddb::GSException::GSException; - %ignore griddb::TimestampUtils::TimestampUtils; -//Mark these methods below return new object, need to be free by target language +%include "gstype.i" -%feature("new") griddb::Container::query; +%include +//Mark these methods below return new object, need to be free by target language +%feature("new") griddb::Container::query; +//%feature("new") griddb::ContainerInfo::get_time_series_properties; %feature("new") griddb::Query::fetch; - %feature("new") griddb::Query::get_row_set; - %feature("new") griddb::RowSet::get_next_query_analysis; - %feature("new") griddb::RowSet::get_next_aggregation; - +%feature("new") griddb::Store::put_container; %feature("new") griddb::Store::get_container; - %feature("new") griddb::Store::get_container_info; - %feature("new") griddb::Store::create_row_key_predicate; - %feature("new") griddb::Store::partition_info; - %feature("new") griddb::StoreFactory::get_store; - -%feature("new") griddb::StoreFactory::get_default; - -%include "gstype.i" - -%include +%feature("new") griddb::StoreFactory::get_instance; #if defined(SWIGPYTHON) %include "gstype_python.i" -%module griddb_python_client +%module griddb_python #elif defined(SWIGRUBY) %include "gstype_ruby.i" %module griddb_ruby_client #elif defined(SWIGJAVASCRIPT) %include "gstype_js_v8.i" -%module griddb_js_client +%module griddb_client #elif defined(SWIGPHP) %include "gstype_php.i" %module griddb_php_client +#elif defined(SWIGGO) +%include "gstype_go.i" +%module griddb_go #endif %{ #include "gridstore.h" #include "GSException.h" -#include "Resource.h" +#include "Util.h" #include "TimeSeriesProperties.h" +#include "ExpirationInfo.h" #include "ContainerInfo.h" -#include "Row.h" +#include "Field.h" +#include "QueryAnalysisEntry.h" #include "RowSet.h" #include "Query.h" #include "Container.h" @@ -76,18 +83,41 @@ #include "RowKeyPredicate.h" #include "Store.h" #include "StoreFactory.h" +%} +#if !defined(SWIGJAVASCRIPT) +%{ #include "TimestampUtils.h" %} +#endif +#if defined(SWIGJAVASCRIPT) || defined(SWIGPHP) +%{ +#include "EnumValue.h" +%} +#endif -%include -%catches(griddb::GSException); +#if defined(SWIGPYTHON) +%shared_ptr(griddb::Resource) +%shared_ptr(griddb::AggregationResult) +%shared_ptr(griddb::TimeSeriesProperties) +%shared_ptr(griddb::ExpirationInfo) +%shared_ptr(griddb::ContainerInfo) +%shared_ptr(griddb::QueryAnalysisEntry) +%shared_ptr(griddb::RowSet) +%shared_ptr(griddb::Query) +%shared_ptr(griddb::Container) +%shared_ptr(griddb::StoreFactory) +%shared_ptr(griddb::RowKeyPredicate) +%shared_ptr(griddb::Store) +%shared_ptr(griddb::PartitionController) +#endif %include "GSException.h" -%include "Resource.h" %include "AggregationResult.h" %include "TimeSeriesProperties.h" +%include "ExpirationInfo.h" %include "ContainerInfo.h" -%include "Row.h" +%include "Field.h" +%include "QueryAnalysisEntry.h" %include "RowSet.h" %include "Query.h" %include "Container.h" @@ -95,4 +125,9 @@ %include "RowKeyPredicate.h" %include "Store.h" %include "StoreFactory.h" +#if !defined(SWIGJAVASCRIPT) %include "TimestampUtils.h" +#endif +#if defined(SWIGJAVASCRIPT) || defined(SWIGPHP) +%include "EnumValue.h" +#endif diff --git a/src/gstype.i b/src/gstype.i index 182c07c..2c84eea 100644 --- a/src/gstype.i +++ b/src/gstype.i @@ -1,42 +1,51 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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. */ #if defined(SWIGPYTHON) -%module griddb_python_client +%include "gstype_python.i" +%module griddb_python %begin %{ #define SWIG_PYTHON_2_UNICODE %} #elif defined(SWIGRUBY) +%include "gstype_ruby.i" %module griddb_ruby_client #elif defined(SWIGPHP) %module griddb_php_client +#elif defined(SWIGJAVASCRIPT) +%module griddb_client #endif %include %include %include %include +#if defined(SWIGPYTHON) +%include +#endif %include %catches(griddb::GSException); +#if !defined(SWIGGO) enum GSContainerTypeTag { GS_CONTAINER_COLLECTION, GS_CONTAINER_TIME_SERIES, }; +#endif enum GSRowSetTypeTag { GS_ROW_SET_CONTAINER_ROWS, @@ -44,33 +53,34 @@ enum GSRowSetTypeTag { GS_ROW_SET_QUERY_ANALYSIS }; +#if !defined(SWIGGO) // Enum GSTypeTag enum GSTypeTag { - GS_TYPE_STRING, - GS_TYPE_BOOL, - GS_TYPE_BYTE, - GS_TYPE_SHORT, - GS_TYPE_INTEGER, - GS_TYPE_LONG, - GS_TYPE_FLOAT, - GS_TYPE_DOUBLE, - GS_TYPE_TIMESTAMP, - GS_TYPE_GEOMETRY, - GS_TYPE_BLOB, - GS_TYPE_STRING_ARRAY, - GS_TYPE_BOOL_ARRAY, - GS_TYPE_BYTE_ARRAY, - GS_TYPE_SHORT_ARRAY, - GS_TYPE_INTEGER_ARRAY, - GS_TYPE_LONG_ARRAY, - GS_TYPE_FLOAT_ARRAY, - GS_TYPE_DOUBLE_ARRAY, - GS_TYPE_TIMESTAMP_ARRAY, -#if GS_COMPATIBILITY_SUPPORT_3_5 + GS_TYPE_STRING, + GS_TYPE_BOOL, + GS_TYPE_BYTE, + GS_TYPE_SHORT, + GS_TYPE_INTEGER, + GS_TYPE_LONG, + GS_TYPE_FLOAT, + GS_TYPE_DOUBLE, + GS_TYPE_TIMESTAMP, + GS_TYPE_GEOMETRY, + GS_TYPE_BLOB, + GS_TYPE_STRING_ARRAY, + GS_TYPE_BOOL_ARRAY, + GS_TYPE_BYTE_ARRAY, + GS_TYPE_SHORT_ARRAY, + GS_TYPE_INTEGER_ARRAY, + GS_TYPE_LONG_ARRAY, + GS_TYPE_FLOAT_ARRAY, + GS_TYPE_DOUBLE_ARRAY, + GS_TYPE_TIMESTAMP_ARRAY, GS_TYPE_NULL = -1 -#endif }; +#endif +#if !defined(SWIGGO) // Enum GSIndexTypeFlagTag enum GSIndexTypeFlagTag { GS_INDEX_FLAG_DEFAULT, @@ -78,66 +88,69 @@ enum GSIndexTypeFlagTag { GS_INDEX_FLAG_HASH, GS_INDEX_FLAG_SPATIAL }; +#endif -typedef int32_t GSTypeOption; +enum GSFetchOptionTag { -typedef int32_t GSIndexTypeFlags; + GS_FETCH_LIMIT, -typedef int64_t GSTimestamp; +#if GS_INTERNAL_DEFINITION_VISIBLE +#if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE -typedef int32_t GSEnum; + GS_FETCH_SIZE = (GS_FETCH_LIMIT + 1) +#endif +#endif +}; -typedef GSEnum GSRowSetType; +#if !defined(SWIGGO) +enum GSTimeUnitTag { -typedef GSEnum GSContainerType; + GS_TIME_UNIT_YEAR, -typedef GSEnum GSType; + GS_TIME_UNIT_MONTH, -typedef int32_t GSResult; + GS_TIME_UNIT_DAY, -typedef char GSChar; + GS_TIME_UNIT_HOUR, -typedef char GSBool; + GS_TIME_UNIT_MINUTE, -typedef GSEnum GSTimeUnit; + GS_TIME_UNIT_SECOND, -enum GSFetchOptionTag { + GS_TIME_UNIT_MILLISECOND +}; +#endif - GS_FETCH_LIMIT, +enum GSTypeOptionTag { -#if GS_COMPATIBILITY_SUPPORT_1_5 + GS_TYPE_OPTION_KEY = 1 << 0, -#if GS_INTERNAL_DEFINITION_VISIBLE -#if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE + GS_TYPE_OPTION_NULLABLE = 1 << 1, - GS_FETCH_SIZE = (GS_FETCH_LIMIT + 1) -#endif -#endif + GS_TYPE_OPTION_NOT_NULL = 1 << 2, -#endif }; -enum GSTimeUnitTag { - - GS_TIME_UNIT_YEAR, - - - GS_TIME_UNIT_MONTH, +typedef int32_t GSTypeOption; +typedef int32_t GSIndexTypeFlags; - GS_TIME_UNIT_DAY, +typedef int64_t GSTimestamp; +typedef int32_t GSEnum; - GS_TIME_UNIT_HOUR, +typedef GSEnum GSRowSetType; +typedef GSEnum GSContainerType; - GS_TIME_UNIT_MINUTE, +typedef GSEnum GSType; +typedef int32_t GSResult; - GS_TIME_UNIT_SECOND, +typedef char GSChar; +typedef char GSBool; - GS_TIME_UNIT_MILLISECOND -}; +typedef GSEnum GSTimeUnit; typedef struct GSQueryAnalysisEntryTag GSQueryAnalysisEntry; From 472eef7f872931aad137814d6d1a88f3ae8aec3f Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:12:16 +0900 Subject: [PATCH 02/22] add source code of Python client (0.8.2) --- src/EnumValue.h | 105 +++++++++++++++++++++++++++ src/ExpirationInfo.h | 81 +++++++++++++++++++++ src/Field.cpp | 106 +++++++++++++++++++++++++++ src/Field.h | 39 ++++++++++ src/QueryAnalysisEntry.cpp | 144 +++++++++++++++++++++++++++++++++++++ src/QueryAnalysisEntry.h | 46 ++++++++++++ src/Util.cpp | 31 ++++++++ src/Util.h | 34 +++++++++ 8 files changed, 586 insertions(+) create mode 100644 src/EnumValue.h create mode 100644 src/ExpirationInfo.h create mode 100644 src/Field.cpp create mode 100644 src/Field.h create mode 100644 src/QueryAnalysisEntry.cpp create mode 100644 src/QueryAnalysisEntry.h create mode 100644 src/Util.cpp create mode 100644 src/Util.h diff --git a/src/EnumValue.h b/src/EnumValue.h new file mode 100644 index 0000000..dfbffbd --- /dev/null +++ b/src/EnumValue.h @@ -0,0 +1,105 @@ +/* + 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 _ENUM_VALUE_H_ +#define _ENUM_VALUE_H_ + +using namespace std; + +namespace griddb { +// Represents the type(s) of a Container. +class ContainerType { + public: + static const int COLLECTION = 0; + static const int TIME_SERIES = 1; +}; +// Represents the type(s) of indexes set on a Container. +class IndexType { + public: + static const int DEFAULT = -1; + static const int TREE = 1 << 0; + static const int HASH = 1 << 1; + static const int SPATIAL = 1 << 2; +}; +// The type of content that can be extracted from GSRowSet. +class RowSetType { + public: + static const int CONTAINER_ROWS = 0; + static const int AGGREGATION_RESULT = 1; + static const int QUERY_ANALYSIS = 2; +}; +// The options for fetching the result of a query. +class FetchOption { + public: + static const int LIMIT = 0; + +#if GS_INTERNAL_DEFINITION_VISIBLE +#if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE + static const int SIZE = (LIMIT + 1); +#endif +#endif + +#if GS_COMPATIBILITY_SUPPORT_4_0 + static const int PARTIAL_EXECUTION = (LIMIT + 2); +#endif +}; +// Represents the time unit(s) used in TimeSeries data operation. +class TimeUnit { + public: + static const int YEAR = 0; + static const int MONTH = 1; + static const int DAY = 2; + static const int HOUR = 3; + static const int MINUTE = 4; + static const int SECOND = 5; + static const int MILLISECOND = 6; +}; +// Represents the type(s) of field values in GridDB. +class Type { + public: + static const int STRING = 0; + static const int BOOL = 1; + static const int BYTE = 2; + static const int SHORT = 3; + static const int INTEGER = 4; + static const int LONG = 5; + static const int FLOAT = 6; + static const int DOUBLE = 7; + static const int TIMESTAMP = 8; + static const int GEOMETRY = 9; + static const int BLOB = 10; + static const int STRING_ARRAY = 11; + static const int BOOL_ARRAY = 12; + static const int BYTE_ARRAY = 13; + static const int SHORT_ARRAY = 14; + static const int INTEGER_ARRAY = 15; + static const int LONG_ARRAY = 16; + static const int FLOAT_ARRAY = 17; + static const int DOUBLE_ARRAY = 18; + static const int TIMESTAMP_ARRAY = 19; + + // Can't use NULL because it is keyword of C language + static const int NULL_TYPE = -1; +}; +// Sum of bits of value of the flag indicating the option setting for Column. +class TypeOption { + public: + static const int NULLABLE = 1 << 1; + static const int NOT_NULL = 1 << 2; +}; +} + +#endif diff --git a/src/ExpirationInfo.h b/src/ExpirationInfo.h new file mode 100644 index 0000000..c59a972 --- /dev/null +++ b/src/ExpirationInfo.h @@ -0,0 +1,81 @@ +/* + 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 _EXPIRATIONINFO_H_ +#define _EXPIRATIONINFO_H_ + +#include +#include + +using namespace std; + +namespace griddb { +class ExpirationInfo { + /* + * Contains information about expiration configuration + */ + GSTimeSeriesProperties mTimeSeriesProps; + + public: + ExpirationInfo(const GSTimeSeriesProperties* timeSeriesProps) { + mTimeSeriesProps.rowExpirationTime = timeSeriesProps->rowExpirationTime; + mTimeSeriesProps.rowExpirationTimeUnit = timeSeriesProps->rowExpirationTimeUnit; + mTimeSeriesProps.expirationDivisionCount = timeSeriesProps->expirationDivisionCount; + mTimeSeriesProps.compressionList = NULL; + mTimeSeriesProps.compressionListSize = 0; + mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; + mTimeSeriesProps.compressionWindowSize = 0; + mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; + }; + ExpirationInfo(int time, GSTimeUnit unit, int division_count) { + mTimeSeriesProps.rowExpirationTime = time; + mTimeSeriesProps.rowExpirationTimeUnit = unit; + mTimeSeriesProps.expirationDivisionCount = division_count; + mTimeSeriesProps.compressionList = NULL; + mTimeSeriesProps.compressionListSize = 0; + mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; + mTimeSeriesProps.compressionWindowSize = 0; + mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; + }; + ~ExpirationInfo() { + //nothing to do + }; + int get_time() { + return mTimeSeriesProps.rowExpirationTime; + }; + void set_time(int time) { + mTimeSeriesProps.rowExpirationTime = time; + }; + GSTimeUnit get_time_unit() { + return mTimeSeriesProps.rowExpirationTimeUnit; + }; + void set_time_unit(GSTimeUnit unit) { + mTimeSeriesProps.rowExpirationTimeUnit = unit; + }; + int get_division_count() { + return mTimeSeriesProps.expirationDivisionCount; + }; + void set_division_count(int division_count) { + mTimeSeriesProps.expirationDivisionCount = division_count; + }; + GSTimeSeriesProperties* gs_ts() { + return &mTimeSeriesProps; + }; +}; + +} /* namespace griddb */ + +#endif diff --git a/src/Field.cpp b/src/Field.cpp new file mode 100644 index 0000000..d1eaa13 --- /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 [] (char*)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 new file mode 100644 index 0000000..15e3f36 --- /dev/null +++ b/src/Field.h @@ -0,0 +1,39 @@ +/* + 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 _FIELD_H_ +#define _FIELD_H_ + +#include +#include + +#include "gridstore.h" + +using namespace std; + +namespace griddb { + +class Field { + public: + GSType type; + GSValue value; + Field(); + ~Field(); +}; + +} + +#endif /* _FIELD_H_ */ diff --git a/src/QueryAnalysisEntry.cpp b/src/QueryAnalysisEntry.cpp new file mode 100644 index 0000000..daffdf0 --- /dev/null +++ b/src/QueryAnalysisEntry.cpp @@ -0,0 +1,144 @@ +/* + 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 "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) { + return; + } + + try { + if (!mQueryAnalysis) { + mQueryAnalysis = new GSQueryAnalysisEntry(); + } + + mQueryAnalysis->statement = NULL; + mQueryAnalysis->type = NULL; + mQueryAnalysis->value = NULL; + mQueryAnalysis->valueType = NULL; + + if (queryAnalysis->statement) { + Util::strdup(&(mQueryAnalysis->statement), queryAnalysis->statement); + } + + if (queryAnalysis->type) { + Util::strdup(&(mQueryAnalysis->type), queryAnalysis->type); + } + + if (queryAnalysis->value) { + Util::strdup(&(mQueryAnalysis->value), queryAnalysis->value); + } + + if (queryAnalysis->valueType) { + 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) { + delete[] mQueryAnalysis->statement; + } + if (mQueryAnalysis->type) { + delete[] mQueryAnalysis->type; + } + if (mQueryAnalysis->value) { + delete[] mQueryAnalysis->value; + } + if (mQueryAnalysis->valueType) { + delete[] mQueryAnalysis->valueType; + } + delete mQueryAnalysis; + } + } + + /** + * @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; + 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 new file mode 100644 index 0000000..107839b --- /dev/null +++ b/src/QueryAnalysisEntry.h @@ -0,0 +1,46 @@ +/* + 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 SRC_QUERYANALYSISENTRY_H_ +#define SRC_QUERYANALYSISENTRY_H_ + +#include +#include + +#include "gridstore.h" +#include "GSException.h" +#include "Util.h" + +using namespace std; + +namespace griddb { + +class QueryAnalysisEntry { + private: + GSQueryAnalysisEntry* mQueryAnalysis; + void freeMemory(); + + public: + QueryAnalysisEntry(GSQueryAnalysisEntry* queryAnalysis); + ~QueryAnalysisEntry(); + void close(); + void get(GSQueryAnalysisEntry* queryAnalysis); + +}; + +} +#endif /* SRC_QUERYANALYSISENTRY_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 156d2702a8a42616d2ddfa47e151ef610c3d8c7a Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:13:21 +0900 Subject: [PATCH 03/22] delete for 0.8 --- src/Resource.cpp | 63 -------- src/Resource.h | 42 ------ src/Row.cpp | 385 ----------------------------------------------- src/Row.h | 95 ------------ 4 files changed, 585 deletions(-) delete mode 100644 src/Resource.cpp delete mode 100644 src/Resource.h delete mode 100644 src/Row.cpp delete mode 100644 src/Row.h diff --git a/src/Resource.cpp b/src/Resource.cpp deleted file mode 100644 index 9f15a41..0000000 --- a/src/Resource.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - 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 "Resource.h" - -namespace griddb { - -Resource::Resource(void *resource) : mResource(resource) { - } - - Resource::~Resource() { - } - - /** - * Get error stack size. Convert from C-API: gsGetErrorStackSize. - */ - size_t Resource::get_error_stack_size() { - return gsGetErrorStackSize(mResource); - } - - /** - * Get error stack code. Convert from C-API: gsGetErrorCode. - */ - GSResult Resource::get_error_code(size_t stackIndex) { - return gsGetErrorCode(mResource, stackIndex); - } - - /** - * Format error code. Convert from C-API: gsFormatErrorMessage. - */ - string Resource::format_error_message(size_t stackIndex, size_t bufSize) { - char* strBuf = new char[bufSize]; - size_t stringSize = gsFormatErrorMessage(mResource, stackIndex, strBuf, bufSize); - string ret(strBuf, stringSize); - delete [] strBuf; - return ret; - } - - /** - * Format error location. Convert from C-API: gsFormatErrorLocation. - */ - string Resource::format_error_location(size_t stackIndex, size_t bufSize) { - char* strBuf = new char[bufSize]; - size_t stringSize = gsFormatErrorLocation(mResource, stackIndex, strBuf, bufSize); - string ret(strBuf, stringSize); - delete [] strBuf; - return ret; - } - -} /* namespace griddb */ diff --git a/src/Resource.h b/src/Resource.h deleted file mode 100644 index b6970a1..0000000 --- a/src/Resource.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 _RESOURCE_H_ -#define _RESOURCE_H_ - -#include -#include "gridstore.h" - -using namespace std; - -namespace griddb { - -class Resource { - void *mResource; - -public: - Resource(void *resource); - ~Resource(); - - size_t get_error_stack_size(); - GSResult get_error_code(size_t stackIndex); - string format_error_message(size_t stackIndex, size_t bufSize); - string format_error_location(size_t stackIndex, size_t bufSize); -}; - -} /* namespace griddb */ - -#endif /* SRC_RESOURCE_H_ */ diff --git a/src/Row.cpp b/src/Row.cpp deleted file mode 100644 index ea4d110..0000000 --- a/src/Row.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - 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 "Row.h" -#include "GSException.h" - -namespace griddb { - Row::Row(GSRow *row) : Resource(row), mRow(row) { - } - - Row::~Row() { - close(); - } - - /** - * Set field by String - */ - void Row::set_field_by_string(int32_t column, string value) { - GSResult ret = gsSetRowFieldByString(mRow, column, value.c_str()); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field with string type. - */ - char* Row::get_field_as_string(int32_t column) { - const GSChar *temp; - GSResult ret = gsGetRowFieldAsString(mRow, column, &temp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (char*) temp; - } - - /** - * Set field by bool - */ - void Row::set_field_by_bool(int32_t column, bool value) { - GSResult ret = gsSetRowFieldByBool(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field with boolean type. - */ - bool Row::get_field_as_bool(int32_t column) { - GSBool value; - GSResult ret = gsGetRowFieldAsBool(mRow, column, &value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return (bool) value; - } - - /** - * Set field by long - */ - void Row::set_field_by_long(int32_t column, int64_t value) { - GSResult ret = gsSetRowFieldByLong(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field with long type. - */ - long Row::get_field_as_long(int32_t column) { - long value; - GSResult ret = gsGetRowFieldAsLong(mRow, column, &value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return value; - } - - /** - * Set field by byte. Convert from C-Api: gsSetRowFieldByByte - */ - void Row::set_field_by_byte(int32_t column, int8_t value) { - GSResult ret = gsSetRowFieldByByte(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as byte. Convert from C-Api: gsGetRowFieldAsByte - */ - int8_t Row::get_field_as_byte(int32_t column) { - int8_t value; - GSResult ret = gsGetRowFieldAsByte(mRow, column, &value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return value; - } - - /** - * Set field by short. Convert from C-Api: gsSetRowFieldByShort - */ - void Row::set_field_by_short(int32_t column, int16_t value) { - GSResult ret = gsSetRowFieldByShort(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as short. Convert from C-API: gsGetRowFieldAsShort - */ - int16_t Row::get_field_as_short(int32_t column) { - int16_t temp; - GSResult ret = gsGetRowFieldAsShort(mRow, column, &temp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return temp; - } - - /** - * Set field by integer. Convert from C-Api: gsSetRowFieldByInteger - */ - void Row::set_field_by_integer(int32_t column, int32_t value) { - GSResult ret = gsSetRowFieldByInteger(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as integer. Convert from C-Api: gsGetRowFieldAsInteger - */ - int32_t Row::get_field_as_integer(int32_t column) { - int32_t temp; - GSResult ret = gsGetRowFieldAsInteger(mRow, column, &temp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return temp; - } - - /** - * Set field by timestamp. Convert from C-Api: gsSetRowFieldByTimestamp - */ - void Row::set_field_by_timestamp(int32_t column, GSTimestamp value) { - GSResult ret = gsSetRowFieldByTimestamp(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as timestamp. Convert from C-Api: gsGetRowFieldAsTimestamp - */ - GSTimestamp Row::get_field_as_timestamp(int32_t column) { - GSTimestamp timestamp; - GSResult ret = gsGetRowFieldAsTimestamp(mRow, column, ×tamp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return timestamp; - } - - /** - * Set field by float. Convert from C-Api: gsSetRowFieldByFloat - */ - void Row::set_field_by_float(int32_t column, float value) { - GSResult ret = gsSetRowFieldByFloat(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as float. Convert from C-Api: gsGetRowFieldAsFloat - */ - float Row::get_field_as_float(int32_t column) { - float temp; - GSResult ret = gsGetRowFieldAsFloat(mRow, column, &temp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return temp; - } - - /** - * Set field by double. Convert from C-Api: gsSetRowFieldByDouble - */ - void Row::set_field_by_double(int32_t column, double value) { - GSResult ret = gsSetRowFieldByDouble(mRow, column, value); - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as double. Convert from C-Api: gsGetRowFieldAsDouble - */ - double Row::get_field_as_double(int32_t column) { - double temp; - GSResult ret = gsGetRowFieldAsDouble(mRow, column, &temp); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - return temp; - } - - /** - * Set row field as GSBlob. Convert from C-Api: gsSetRowFieldByBlob - */ - void Row::set_field_by_blob(int32_t column, const GSBlob* fieldValue) { - GSResult ret = gsSetRowFieldByBlob(mRow, column, fieldValue); - - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Get row field as Blob. Convert from C-Api: gsGetRowFieldAsBlob - */ - void Row::get_field_as_blob(int32_t column, GSBlob *value) { - GSResult ret = gsGetRowFieldAsBlob(mRow, column, value); - - // Check ret, if error, throw exception - if (ret != GS_RESULT_OK) { - throw GSException(ret); - } - } - - /** - * Returns the schema corresponding to the specified Row. - */ - ContainerInfo* Row::get_schema() { - GSContainerInfo schemaInfo; - GSResult ret = gsGetRowSchema(mRow, &schemaInfo); - if(ret != GS_RESULT_OK) { - throw GSException(ret); - } - - return new ContainerInfo(&schemaInfo); - } - - /** - * Close row. - */ - void Row::close() { - if (mRow) { - gsCloseRow(&mRow); - mRow = NULL; - } - } - - /** - * Return raw pointer for other functions. - */ - GSRow* Row::gs_ptr() { - return mRow; - } - - char* Row::set_field_by_geometry(int32_t column, string value) { - //TODO: update with C-API implementation - return NULL; - } - - const char* Row::get_field_as_geometry(int32_t column) { - //TODO: update with C-API implementation - return NULL; - } - - bool Row::set_field_by_string_array(int32_t column, const GSChar *const *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_string_array(int32_t column, - const char* const ** fieldValue, size_t* size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_byte_array(int32_t column, const int8_t *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_byte_array(int32_t column, const int8_t **fieldValue, size_t *size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_short_array(int32_t column, const int16_t *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_short_array(int32_t column, const int16_t** fieldValue, - size_t* size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_integer_array(int32_t column, - const int32_t *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_integer_array(int32_t column, const int32_t** fieldValue, - size_t* size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_long_array(int32_t column, const int64_t *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_long_array(int32_t column, const int64_t** fieldValue, - size_t* size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_float_array(int32_t column, const float *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_float_array(int32_t column, const float** fieldValue, - size_t* size) { - //TODO: update with C-API implementation - } - - void Row::set_field_by_double_array(int32_t column, const double *fieldValue, size_t size) { - //TODO: update with C-API implementation - } - - void Row::get_field_as_double_array(int32_t column, const double** fieldValue, - size_t* size) { - //TODO: update with C-API implementation - } - - bool Row::set_field_by_timestamp_array(int32_t column, const GSTimestamp *fieldValue, size_t size) { - //TODO: update with C-API implementation - return NULL; - } - - void Row::get_field_as_timestamp_array(int32_t column, - const int64_t** fieldValue, size_t* size) { - //TODO: update with C-API implementation - } -} diff --git a/src/Row.h b/src/Row.h deleted file mode 100644 index 65a0dcf..0000000 --- a/src/Row.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - 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 _ROW_H_ -#define _ROW_H_ - -#include -#include -#include - -#include "Resource.h" -#include "gridstore.h" -#include "ContainerInfo.h" - -using namespace std; - -namespace griddb { - -class Row : public Resource { - GSRow *mRow; -public: - Row(GSRow *row); - ~Row(); - - void set_field_by_string(int32_t column, string value); - char* get_field_as_string(int32_t column); - void set_field_by_bool(int32_t column, bool value); - bool get_field_as_bool(int32_t column); - void set_field_by_long(int32_t column, int64_t value); - long get_field_as_long(int32_t column); - void set_field_by_byte(int32_t column, int8_t value); - int8_t get_field_as_byte(int32_t column); - void set_field_by_short(int32_t column, int16_t value); - int16_t get_field_as_short(int32_t column); - void set_field_by_integer(int32_t column, int32_t value); - int32_t get_field_as_integer(int32_t column); - void set_field_by_float(int32_t column, float value); - float get_field_as_float(int32_t column); - void set_field_by_double(int32_t column, double value); - double get_field_as_double(int32_t column); - void set_field_by_timestamp(int32_t column, GSTimestamp value); - GSTimestamp get_field_as_timestamp(int32_t column); - - char* set_field_by_geometry(int32_t column, string value); - const char* get_field_as_geometry(int32_t column); - void set_field_by_blob(int32_t column, const GSBlob *fieldValue); - void get_field_as_blob(int32_t column, GSBlob *value); - bool set_field_by_string_array(int32_t column, const GSChar *const *fieldValue, size_t size); - void get_field_as_string_array(int32_t column, - const char * const **fieldValue, size_t *size); - bool set_field_by_byte_array(int32_t column, const int8_t *fieldValue, size_t size); - //TODO: Handle 2 return value : double pointer and size of array. - void get_field_as_byte_array(int32_t column, const int8_t **fieldValue, size_t *size); - bool set_field_by_short_array(int32_t column, const int16_t *fieldValue, size_t size); - void get_field_as_short_array(int32_t column, const int16_t **fieldValue, - size_t *size); - bool set_field_by_integer_array(int32_t column, const int32_t *fieldValue, size_t size); - void get_field_as_integer_array(int32_t column, const int32_t **fieldValue, - size_t *size); - bool set_field_by_long_array(int32_t column, const int64_t *fieldValue, size_t size); - void get_field_as_long_array(int32_t column, const int64_t **fieldValue, - size_t *size); - bool set_field_by_float_array(int32_t column, const float *fieldValue, size_t size); - void get_field_as_float_array(int32_t column, const float **fieldValue, - size_t *size); - void set_field_by_double_array(int32_t column, const double *fieldValue, size_t size); - void get_field_as_double_array(int32_t column, const double **fieldValue, - size_t *size); - bool set_field_by_timestamp_array(int32_t column, const GSTimestamp *fieldValue, size_t size); - void get_field_as_timestamp_array(int32_t column, - const int64_t **fieldValue, size_t *size); - - ContainerInfo* get_schema(); - - GSRow* gs_ptr(); - -private: - void close(); -}; -} - -#endif /* _ROW_H_ */ From 97145729a5acdfae1bb849893388a4ced3e6e4da Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:14:32 +0900 Subject: [PATCH 04/22] update for 0.8 --- src/StoreFactory.h | 80 ++++---- src/gstype_php.i | 482 ++------------------------------------------- 2 files changed, 53 insertions(+), 509 deletions(-) diff --git a/src/StoreFactory.h b/src/StoreFactory.h index f7680f3..cb06c99 100644 --- a/src/StoreFactory.h +++ b/src/StoreFactory.h @@ -1,61 +1,59 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. + 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 _STORE_FACTORY_H_ #define _STORE_FACTORY_H_ -#define CLIENT_VERSION "GridDB PHP Client 0.5.0" - -#include "Resource.h" -#include "gridstore.h" -#include "Store.h" +#define CLIENT_VERSION "GridDB PHP Client 0.8" #include #include +#include "gridstore.h" +#include "Store.h" +#include "GSException.h" +#include "Util.h" + using namespace std; namespace griddb { - /** - * Class GridStoreFactory to contain GSGridStoreFactory object. - * This class is implemented as singleton. - */ - class StoreFactory : public Resource { - - GSBool mIsAllRelated; - - GSGridStoreFactory* mFactory; - - public: - ~StoreFactory(); - - static StoreFactory* get_default(); - Store* get_store(const GSPropertyEntry* props, int propsCount); - void set_properties(const GSPropertyEntry* props, int propsCount); - string get_version(); - /** - * Release all GridStore created by this factory and related resources - */ - void close(); - - private: - StoreFactory(); - void set_factory(GSGridStoreFactory* factory); +/** + * Class GridStoreFactory to contain GSGridStoreFactory object. + * This class is implemented as singleton. + */ +class StoreFactory { + private: + GSGridStoreFactory* mFactory; + + public: + ~StoreFactory(); + void close(GSBool allRelated = GS_FALSE); + static StoreFactory* get_instance(); + Store* get_store(const char* host=NULL, int32_t port=0, const char* cluster_name=NULL, + const char* database=NULL, const char* username=NULL, const char* password=NULL, + const char* notification_member=NULL, const char* notification_provider=NULL); + string get_version(); + + private: + StoreFactory(); + void set_property_entry(GSPropertyEntry *prop, const char* name, const char* value); + bool check_multicast(const char* address); + void set_factory(GSGridStoreFactory* factory); +}; - }; } #endif diff --git a/src/gstype_php.i b/src/gstype_php.i index 835a8ed..2013e94 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -1,115 +1,23 @@ /* - Copyright (c) 2017 TOSHIBA Digital Solutions Corporation + 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 + 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 + 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. - */ + 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 "zend_interfaces.h" %} -/** - * Support throw exception in PHP language - */ -%fragment("throwGSException", "header") { - static void throwGSException(griddb::GSException* exception){ - const char* obj_typename = "GSException"; - size_t obj_typename_len = strlen(obj_typename); - // Create a resource - zval resource; - - SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); - zval ex; - zval ctor_rv; - - // Create a PHP GSException object - zend_string * obj_typename_zend = zend_string_init(obj_typename, obj_typename_len, 0); - zend_class_entry* ce = zend_lookup_class(obj_typename_zend); - zend_string_release(obj_typename_zend); - if (!ce) { - SWIG_FAIL(); - } - - object_and_properties_init(&ex, ce, NULL); - - // Constructor, pass resource to constructor argument - zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); - zend_call_method(&ex, ce, &constructor, NULL, 0, &ctor_rv, 1, &resource, NULL TSRMLS_CC); - if (Z_TYPE(ctor_rv) != IS_UNDEF) { - zval_ptr_dtor(&ctor_rv); - } - - // Throw - zend_throw_exception_object(&ex); - } -} -%typemap(throws, fragment="throwGSException") griddb::GSException %{ - griddb::GSException* tmpException = new griddb::GSException($1.get_code(), $1.what()); - throwGSException(tmpException); - return; -%} - -/** - * Typemaps for put_container() function - */ -%typemap(in) (const GSColumnInfo* props, int propsCount) -(zval *inputVar, zval *data1, zval *data2, HashTable *arr, HashPosition pos1, HashTable *assocArr, HashPosition pos2, int i, zend_string* key, ulong key_len, ulong index) { -//Convert PHP arrays into GSColumnInfo properties - //Convert input array to HashTable - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected array as input"); - SWIG_FAIL(); - } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); - $1 = NULL; - if ($2 > 0) { - $1 = (GSColumnInfo *) malloc($2*sizeof(GSColumnInfo)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - memset($1, 0x0, $2*sizeof(GSColumnInfo)); - - i = 0; - for(zend_hash_internal_pointer_reset_ex(arr, &pos1); - (data1 = zend_hash_get_current_data_ex(arr, &pos1)) != NULL; - zend_hash_move_forward_ex(arr, &pos1)) { - if(Z_TYPE_P(data1) != IS_ARRAY) { - php_printf("Expected associative array as elements"); - SWIG_FAIL(); - } - assocArr = Z_ARRVAL_P(data1); - for(zend_hash_internal_pointer_reset_ex(assocArr, &pos2); (data2 = zend_hash_get_current_data_ex(assocArr, &pos2)) != NULL; zend_hash_move_forward_ex(assocArr, &pos2)) { - if (zend_hash_get_current_key_ex(assocArr, &key, &index, &pos2) == HASH_KEY_IS_STRING) { - $1[i].name = ZSTR_VAL(key); - $1[i].type = Z_LVAL_P(data2); - } - } - i++; - } - } -} - -%typemap(typecheck) (const GSColumnInfo* props, int propsCount) { - $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; -} - -%typemap(freearg) (const GSColumnInfo* props, int propsCount) (int i) { - if ($1) { - free((void *) $1); - } -} /** * Typemaps for get_store() function @@ -152,371 +60,9 @@ } } -/** - * Typemaps for fetch_all() function - */ -%typemap(in) (GSQuery* const* queryList, size_t queryCount) -(HashTable *arr, HashPosition pos, zval *data, griddb::Query *query, int res = 0, int i = 0) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); - SWIG_FAIL(); - } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); - $1 = NULL; - if($2 > 0) { - $1 = (GSQuery**) malloc($2*sizeof(GSQuery*)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - zend_string *key; - int key_len; - long index; - for(zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_LONG) { - res = SWIG_ConvertPtr(data, (void**)&query, $descriptor(griddb::Query*), 0); - if (!SWIG_IsOK(res)) { - php_printf("Convert pointer failed"); - SWIG_FAIL(); - } - $1[i] = query->gs_ptr(); - i++; - } - } - } -} - -%typemap(freearg) (GSQuery* const* queryList, size_t queryCount) { - if ($1) { - free((void *) $1); - } -} - -/** - * Typemaps for put_multi_row_container() function - */ -%typemap(in) (const GSContainerRowEntry* entryList, size_t entryCount) -(int i, int res = 0, void** pRowList = 0, int listSize, HashTable *arr, HashTable *rowArr, HashPosition pos, HashPosition posRow, zval *data, zval *row, griddb::Row *vrow, int res = 0) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected indexed of associative array as input"); - SWIG_FAIL(); - } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); - $1 = NULL; - if ($2 > 0) { - $1 = (GSContainerRowEntry *) malloc($2*sizeof(GSContainerRowEntry)); - memset($1, 0x0, $2*sizeof(GSContainerRowEntry)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - i = 0; - zend_string *key; - int key_len; - long index; - for(zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { - $1[i].containerName = strdup(ZSTR_VAL(key)); - } - else { - php_printf("Expected string as containerName"); - SWIG_FAIL(); - } - - // Check if rowList is an indexed array - if(Z_TYPE_P(data) != IS_ARRAY) { - php_printf("Expected indexed array as rowList"); - SWIG_FAIL(); - } - // Get Row element from list - rowArr = Z_ARRVAL_P(data); - listSize = (int) zend_hash_num_elements(rowArr); - if (listSize > 0) { - pRowList = (void**)malloc(listSize*sizeof(void *)); - $1[i].rowList = pRowList; - } - $1[i].rowCount = listSize; - zend_string *keyRow; - int keyLenRow; - long indexRow; - int j = 0; - for(zend_hash_internal_pointer_reset_ex(rowArr, &posRow); - (row = zend_hash_get_current_data_ex(rowArr, &posRow)) != NULL; - zend_hash_move_forward_ex(rowArr, &posRow)) { - if(zend_hash_get_current_key_ex(rowArr, &keyRow, (zend_ulong*)&indexRow, &posRow) == HASH_KEY_IS_LONG) { - res = SWIG_ConvertPtr(row, (void**)&vrow, $descriptor(griddb::Row*), 0); - if (!SWIG_IsOK(res)) { - php_printf("Convert pointer failed"); - SWIG_FAIL(); - } - pRowList[j] = vrow->gs_ptr(); - j++; - } - } - i++; - } - } -} - -%typemap(freearg) (const GSContainerRowEntry* entryList, size_t entryCount) (int i) { - if ($1) { - for (i = 0; i < $2; i++) { - if ($1[i].containerName) { - free((void *) $1[i].containerName); - } - if ($1[i].rowList) { - free((void *) $1[i].rowList); - } - } - free((void *) $1); - } -} - -/** - * Typemaps for put_multi_row() function - */ -%typemap(in) (const void* const * rowObjs, size_t rowCount) -(HashTable *rowArr, HashPosition pos, zval *data, griddb::Row *row, int res = 0, int i = 0) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); - SWIG_FAIL(); - } - - rowArr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(rowArr); - $1 = NULL; - if($2 > 0) { - $1 = (void**) malloc($2*sizeof(void*)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - zend_string *key; - int key_len; - long index; - int i = 0; - for(zend_hash_internal_pointer_reset_ex(rowArr, &pos); - (data = zend_hash_get_current_data_ex(rowArr, &pos)) != NULL; - zend_hash_move_forward_ex(rowArr, &pos)) { - - if(zend_hash_get_current_key_ex(rowArr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_LONG) { - res = SWIG_ConvertPtr(data, (void**)&row, $descriptor(griddb::Row*), 0); - if (!SWIG_IsOK(res)) { - php_printf("Convert pointer failed"); - SWIG_FAIL(); - } - $1[i] = row->gs_ptr(); - i++; - } - } - } -} - -%typemap(freearg) (const void* const * rowObjs, size_t rowCount) { - if ($1) { - free((void *) $1); - } -} - -// Empty typemap to override default (argout) typemaps for (void **) input -// This typemap is required to avoid error because of the use of undeclared variables generated by SWIG -%typemap(argout) (const void* const * rowObjs, size_t rowCount) {} - -/** - * Typemaps for set_field_by_byte_array() function - */ -%typemap(in) (const int8_t *fieldValue, size_t size) -(HashTable *arr, HashPosition pos, zval *data) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); - SWIG_FAIL(); - } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); - $1 = NULL; - if ($2 > 0) { - $1 = (int8_t *) malloc($2*sizeof(int8_t)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - zend_string *key; - int key_len; - long index; - int i = 0; - for(zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_LONG) { - $1[i] = Z_LVAL_P(data); - i++; - } - } - } -} +//Read only attribute Container::type +%include +//%attribute(griddb::Store, int, type_data, get_data); -%typemap(freearg) (const int8_t *fieldValue, size_t size) { - if ($1) { - free((void *) $1); - } -} -/** - * Typemaps input for get_multi_container_row() function - */ -%typemap(in) (const GSRowKeyPredicateEntry *const * predicateList, size_t predicateCount) -(zend_string *key, HashTable *arr, HashPosition pos, zval *data, GSRowKeyPredicateEntry* pList, griddb::RowKeyPredicate *vpredicate, int i, int res = 0) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); - SWIG_FAIL(); - } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); - $1 = NULL; - i = 0; - if($2 > 0) { - pList = (GSRowKeyPredicateEntry*) malloc($2*sizeof(GSRowKeyPredicateEntry)); - if(pList == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } - $1 = &pList; - int key_len; - long index; - for(zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { - GSRowKeyPredicateEntry *predicateEntry = &pList[i]; - predicateEntry->containerName = strdup(ZSTR_VAL(key)); - res = SWIG_ConvertPtr(data, (void**)&vpredicate, $descriptor(griddb::RowKeyPredicate*), 0); - if (!SWIG_IsOK(res)) { - php_printf("Convert pointer failed"); - SWIG_FAIL(); - } - predicateEntry->predicate = vpredicate->gs_ptr(); - i++; - } - } - } -} - -%typemap(freearg) (const GSRowKeyPredicateEntry *const * predicateList, size_t predicateCount) (int i, GSRowKeyPredicateEntry* pList) { - if ($1 && *$1) { - pList = *$1; - - for (i = 0; i < $2; i++) { - if(pList[i].containerName) { - free((void *) pList[i].containerName); - } - } - free((void *) pList); - } -} - -/** - * Typemaps output for get_multi_container_row() function - */ -%typemap(in, numinputs = 0) (const GSContainerRowEntry **entryList, size_t *entryCount) (GSContainerRowEntry *pEntryList, size_t temp) { - $1 = &pEntryList; - $2 = &temp; -} - -%typemap(argout, fragment="t_output_helper") (const GSContainerRowEntry **entryList, size_t *entryCount) -(size_t i = 0, size_t j = 0, GSContainerRowEntry *entry, GSRow* pRow, griddb::Row* row, zval temp_result, zval list, zval value) { - array_init(&temp_result); - for(i = 0; i < *$2; i++) { - // Get container - entry = &(*$1)[i]; - array_init(&list); - for(j = 0; j < entry->rowCount; j++) { - pRow = (GSRow *) entry->rowList[j]; - if (pRow) { - row = new griddb::Row(pRow); - SWIG_SetPointerZval(&value, (void *)(row), $descriptor(griddb::Row *), 2); - add_index_zval(&list, j, &value); - } - } - add_assoc_zval(&temp_result, entry->containerName, &list); - } - t_output_helper($result, &temp_result); -} - -/** - * Typemaps output for partition controller function - */ -%typemap(in, numinputs=0) (const GSChar *const ** stringList, size_t *size) (GSChar **nameList1, size_t size1) { - $1 = &nameList1; - $2 = &size1; -} - -%typemap(argout,numinputs=0) (const GSChar *const ** stringList, size_t *size) (int i) { - array_init_size($result, size1$argnum); - for (i = 0; i < size1$argnum; i++) { - add_index_string($result, (ulong) i, nameList1$argnum[i]); - } -} - -%typemap(in, numinputs=0) (const int **intList, size_t *size) (int *intList1, size_t size1) { - $1 = &intList1; - $2 = &size1; -} - -%typemap(argout,numinputs=0) (const int **intList, size_t *size) (int i) { - array_init_size($result, size1$argnum); - for (i = 0; i < size1$argnum; i++) { - add_index_long($result, (ulong) i, intList1$argnum[i]); - } -} - -%typemap(in, numinputs=0) (const long **longList, size_t *size) (long *longList1, size_t size1) { - $1 = &longList1; - $2 = &size1; -} - -%typemap(argout,numinputs=0) (const long **longList, size_t *size) (int i) { - array_init_size($result, size1$argnum); - for (i = 0; i < size1$argnum; i++) { - add_index_double($result, (ulong) i, longList1$argnum[i]); - } -} - -// set_field_as_blob -%typemap(in) (const GSBlob *fieldValue) { - if(Z_TYPE_P(&$input) != IS_STRING) { - php_printf("Expected string as input"); - RETURN_NULL(); - } - - $1 = (GSBlob*) malloc(sizeof(GSBlob)); - - convert_to_string(&$input); - $1->size = Z_STRLEN_P(&$input); - $1->data = (char*) Z_STRVAL($input); -} - -%typemap(freearg) (const GSBlob *fieldValue) { - if ($1) { - free((void *) $1); - } -} - -%typemap(in, numinputs = 0) (GSBlob *value) (GSBlob pValue) { - $1 = &pValue; -} - -// Get_field_as_blob -%typemap(argout, fragment="t_output_helper") (GSBlob *value) { - zval o; - ZVAL_STRINGL(&o, (const char*)pValue$argnum.data, pValue$argnum.size); - t_output_helper($result, &o); -} -// Type check for GSBool type -%php_typecheck2(GSBool, SWIG_TYPECHECK_BOOL, IS_TRUE, IS_FALSE) From 7c7a090bbab9d460c52fd95b39ea6cd66472d6f5 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:20:09 +0900 Subject: [PATCH 05/22] implement GSException class, getStore function and constructor for containerInfo --- src/ContainerInfo.h | 4 +- src/gstype_php.i | 324 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 306 insertions(+), 22 deletions(-) diff --git a/src/ContainerInfo.h b/src/ContainerInfo.h index 045a249..58036eb 100644 --- a/src/ContainerInfo.h +++ b/src/ContainerInfo.h @@ -52,8 +52,8 @@ class ContainerInfo { public: ContainerInfo(GSContainerInfo *containerInfo); - ContainerInfo(const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type = GS_CONTAINER_COLLECTION, + ContainerInfo(const GSChar* name = NULL, const GSColumnInfo* props = NULL, + int propsCount = 0, GSContainerType type = GS_CONTAINER_COLLECTION, bool row_key = true, ExpirationInfo* expiration = NULL); ~ContainerInfo(); diff --git a/src/gstype_php.i b/src/gstype_php.i index 2013e94..11908b0 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -18,51 +18,335 @@ #include "zend_interfaces.h" %} +//Read only attribute Container::type +%include +//%attribute(griddb::Store, int, type_data, get_data); +//Read only attribute ContainerInfo::name +%attribute(griddb::ContainerInfo, GSChar*, name, get_name, set_name); +//Read only attribute ContainerInfo::type +%attribute(griddb::ContainerInfo, GSContainerType, type, get_type, set_type); +//Read only attribute ContainerInfo::rowKey +%attribute(griddb::ContainerInfo, bool, rowKey, get_row_key_assigned, set_row_key_assigned); +//Read only attribute ContainerInfo::columnInfoArray +%attributeval(griddb::ContainerInfo, ColumnInfoList, columnInfoArray, get_column_info_list, set_column_info_list); +//Read only attribute ContainerInfo::expiration +%attribute(griddb::ContainerInfo, griddb::ExpirationInfo*, expiration, get_expiration_info, set_expiration_info); +//Read only attribute ExpirationInfo::time +%attribute(griddb::ExpirationInfo, int, time, get_time, set_time); +//Read only attribute ExpirationInfo::unit +%attribute(griddb::ExpirationInfo, GSTimeUnit, unit, get_time_unit, set_time_unit); +//Read only attribute ExpirationInfo::divisionCount +%attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); + +// rename all method to camel cases +%rename(getMessageException) griddb::GSException::get_message; +%rename(getCodeException) griddb::GSException::get_code; +%rename("%(lowercamelcase)s", %$isfunction) ""; + +/* + * ignore unnecessary functions + */ +%ignore griddb::ContainerInfo::ContainerInfo(GSContainerInfo* containerInfo); + +/** + * Support throw exception in PHP language + */ +%fragment("throwGSException", "header") { + static void throwGSException(griddb::GSException* exception) { + const char* obj_typename = "GSException"; + size_t obj_typename_len = strlen(obj_typename); + // Create a resource + zval resource; + + SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); + zval ex; + zval ctor_rv; + + // Create a PHP GSException object + zend_string * obj_typename_zend = zend_string_init(obj_typename, obj_typename_len, 0); + zend_class_entry* ce = zend_lookup_class(obj_typename_zend); + zend_string_release(obj_typename_zend); + if (!ce) { + SWIG_FAIL(); + } + + object_and_properties_init(&ex, ce, NULL); + + // Constructor, pass resource to constructor argument + zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); + zend_call_method(&ex, ce, &constructor, NULL, 0, &ctor_rv, 1, &resource, NULL TSRMLS_CC); + if (Z_TYPE(ctor_rv) != IS_UNDEF) { + zval_ptr_dtor(&ctor_rv); + } + + // Throw + zend_throw_exception_object(&ex); + } +} +%typemap(throws, fragment="throwGSException") griddb::GSException %{ + griddb::GSException* tmpException = new griddb::GSException(&$1); + throwGSException(tmpException); + return; + %} /** * Typemaps for get_store() function */ -%typemap(in) (const GSPropertyEntry* props, int propsCount) -(HashTable *arr, HashPosition pos, zval *data) { +%typemap(in, numinputs = 1) +(const char* host, int32_t port, const char* cluster_name, const char* database, const char* username, const char* password, + const char* notification_member, const char* notification_provider) (HashTable *arr, HashPosition pos, zval *data) { if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); + SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); SWIG_FAIL(); } arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); + int length = (int) zend_hash_num_elements(arr); + char* name = 0; $1 = NULL; - if ($2 > 0) { - $1 = (GSPropertyEntry *) malloc($2*sizeof(GSPropertyEntry)); - if($1 == NULL) { - php_printf("Memory allocation error"); - SWIG_FAIL(); - } + $2 = 0; + $3 = NULL; + $4 = NULL; + $5 = NULL; + $6 = NULL; + $7 = NULL; + $8 = NULL; + if (length > 0) { zend_string *key; int key_len; long index; - int i = 0; for(zend_hash_internal_pointer_reset_ex(arr, &pos); (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; zend_hash_move_forward_ex(arr, &pos)) { if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { - $1[i].name = ZSTR_VAL(key); - $1[i].value = Z_STRVAL_P(data); - i++; + name = ZSTR_VAL(key); + if(strcmp(name, "host") == 0) { + $1 = Z_STRVAL_P(data); + } + else if(strcmp(name, "port") == 0) { + //Input valid is number only + { + if(Z_TYPE_P(data) == IS_LONG) { + $2 = Z_LVAL_P(data); + } else { + SWIG_PHP_Error(E_ERROR, "Expected port number input as int type"); + SWIG_FAIL(); + } + } + } + else if(strcmp(name, "clusterName") == 0) { + $3 = Z_STRVAL_P(data); + } + else if(strcmp(name, "database") == 0) { + $4 = Z_STRVAL_P(data); + } + else if(strcmp(name, "username") == 0) { + $5 = Z_STRVAL_P(data); + } + else if(strcmp(name, "password") == 0) { + $6 = Z_STRVAL_P(data); + } + else if(strcmp(name, "notificationMember") == 0) { + $7 = Z_STRVAL_P(data); + } + else if(strcmp(name, "notificationProvider") == 0) { + $8 = Z_STRVAL_P(data); + } else { + SWIG_PHP_Error(E_ERROR, "Invalid Property"); + SWIG_FAIL(); + }; } } } } -%typemap(freearg) (const GSPropertyEntry* props, int propsCount) (int i = 0) { - if ($1) { - free((void *) $1); +%typemap(typecheck,precedence = SWIG_TYPECHECK_CHAR_ARRAY) (const char* host, int32_t port, const char* cluster_name, const char* database, const char* username, const char* password, + const char* notification_member, const char* notification_provider) { + $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; +} + +/** + * Typemaps for ContainerInfo : support keyword parameter ({"name" : str, "columnInfoArray" : array, "type" : int, 'rowKey':boolean, "expiration" : array}) + */ +%typemap(in) (const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) +(HashTable *arr1, HashPosition pos1, zval *data1, HashTable *arr2, HashPosition pos2, zval *data2, HashTable *arr3, HashPosition pos3, zval *columnName, zval *columnType) { + if(Z_TYPE_P(&$input) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); + SWIG_FAIL(); + } + + arr1 = Z_ARRVAL_P(&$input); + int length1 = (int) zend_hash_num_elements(arr1); + char* name = 0; + //Create $1, $2, $3, $3, $4, $5, $6 with default value + $1 = NULL; + $2 = NULL; + $3 = 0; + $4 = GS_CONTAINER_COLLECTION; + $5 = true;//defautl value rowKey = true + $6 = NULL; + bool boolVal, vbool; + griddb::ExpirationInfo* expiration; + if (length1 > 0) { + zend_string *key; + int key_len; + long index; + for(zend_hash_internal_pointer_reset_ex(arr1, &pos1); + (data1 = zend_hash_get_current_data_ex(arr1, &pos1)) != NULL; + zend_hash_move_forward_ex(arr1, &pos1)) { + if(zend_hash_get_current_key_ex(arr1, &key, (zend_ulong*)&index, &pos1) == HASH_KEY_IS_STRING) { + name = ZSTR_VAL(key); + if(strcmp(name, "name") == 0) { + if(Z_TYPE_P(data1) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Invalid value for property name"); + SWIG_FAIL(); + } + $1 = Z_STRVAL_P(data1); + } + else if(strcmp(name, "columnInfoArray") == 0) { + //Input valid is array only + if(Z_TYPE_P(data1) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array as input for property columnInfoArray"); + SWIG_FAIL(); + } + arr2 = Z_ARRVAL_P(data1); + int length2 = (int) zend_hash_num_elements(arr2); + $3 = length2; + if($3 > 0) { + $2 = (GSColumnInfo *) malloc($3*sizeof(GSColumnInfo)); + if($2 == NULL) { + SWIG_PHP_Error(E_ERROR, "Memory allocation error"); + SWIG_FAIL(); + } + memset($2, 0x0, $3*sizeof(GSColumnInfo)); + int i = 0; + //Get element "name", "status". + for(zend_hash_internal_pointer_reset_ex(arr2, &pos2); + (data2 = zend_hash_get_current_data_ex(arr2, &pos2)) != NULL; + zend_hash_move_forward_ex(arr2, &pos2)) { + if(Z_TYPE_P(data2) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array as elements for columnInfoArray"); + SWIG_FAIL(); + } + arr3 = Z_ARRVAL_P(data2); + int length3 = (int) zend_hash_num_elements(arr3); + if(length3 != 2) { + SWIG_PHP_Error(E_ERROR, "Expected 2 elements for columnInfoArray property"); + SWIG_FAIL(); + } + + zend_hash_internal_pointer_reset_ex(arr3, &pos3); + if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as column name"); + SWIG_FAIL(); + } + $2[i].name = strdup(Z_STRVAL_P(columnName)); + + zend_hash_move_forward_ex(arr3, &pos3); + if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); + SWIG_FAIL(); + } + $2[i].type = Z_LVAL_P(columnType); + i++; + } + } + } + else if(strcmp(name, "type") == 0) { + if(Z_TYPE_P(data1) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Invalid value for property type"); + SWIG_FAIL(); + } + $4 = Z_LVAL_P(data1); + } + else if(strcmp(name, "rowKey") == 0) { + $5 = (bool) zval_is_true(data1); + } + else if(strcmp(name, "expiration") == 0) { + int res = SWIG_ConvertPtr(data1, (void**)&expiration, $descriptor(griddb::ExpirationInfo*), 0 | 0 ); + if (!SWIG_IsOK(res)) { + SWIG_PHP_Error(E_ERROR, "Invalid value for property expiration"); + SWIG_FAIL(); + } + $6 = (griddb::ExpirationInfo *) expiration; + } else { + SWIG_PHP_Error(E_ERROR, "Invalid Property"); + SWIG_FAIL(); + }; + } + } } } -//Read only attribute Container::type -%include -//%attribute(griddb::Store, int, type_data, get_data); +%typemap(freearg) (const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { + if ($2) { + free((void *) $2); + } +} +%typemap(typecheck, precedence = SWIG_TYPECHECK_CHAR_ARRAY) (const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { + $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; +} +%fragment("convertToFieldWithType", "header") { + static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { + int res; + GSResult ret; + if(Z_TYPE_P(value) == IS_NULL) { + ret = gsSetRowFieldNull(row, column); + return (ret == GS_RESULT_OK); + } + switch(type) { + case GS_TYPE_STRING: { + GSChar* stringVal; + if(Z_TYPE_P(value) != IS_STRING) { + return false; + } + stringVal = Z_STRVAL_P(value); + ret = gsSetRowFieldByString(row, column, stringVal); + break; + } + case GS_TYPE_LONG: { + int64_t longVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + longVal = Z_LVAL_P(value); + ret = gsSetRowFieldByLong(row, column, longVal); + } + case GS_TYPE_BOOL: { + bool boolVal; + boolVal = (bool) zval_is_true(data1); + ret = gsSetRowFieldByLong(row, column, boolVal); + } + case GS_TYPE_BYTE: { + int8_t byteVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + shortVal = Z_LVAL_P(value); + ret = gsSetRowFieldByShort(row, column, shortVal); + } + case GS_TYPE_SHORT: { + int16_t byteVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + shortVal = Z_LVAL_P(value); + ret = gsSetRowFieldByShort(row, column, shortVal); + } + case GS_TYPE_INTEGER: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } + } + } +} From 31734ff46ae6fb7f2df1a2a490e19ae1333d5f7a Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:43:35 +0900 Subject: [PATCH 06/22] change getMessage() API into getErrorMessage() API --- src/gstype_php.i | 54 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/gstype_php.i b/src/gstype_php.i index 11908b0..77940e6 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -39,14 +39,14 @@ %attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); // rename all method to camel cases -%rename(getMessageException) griddb::GSException::get_message; -%rename(getCodeException) griddb::GSException::get_code; +%rename(getErrorMessage) griddb::GSException::get_message; %rename("%(lowercamelcase)s", %$isfunction) ""; /* * ignore unnecessary functions */ %ignore griddb::ContainerInfo::ContainerInfo(GSContainerInfo* containerInfo); +%ignore griddb::GSException::get_code; /** * Support throw exception in PHP language @@ -320,15 +320,19 @@ case GS_TYPE_BOOL: { bool boolVal; boolVal = (bool) zval_is_true(data1); - ret = gsSetRowFieldByLong(row, column, boolVal); + ret = gsSetRowFieldByBool(row, column, boolVal); } case GS_TYPE_BYTE: { int8_t byteVal; if(Z_TYPE_P(value) != IS_LONG) { return false; } - shortVal = Z_LVAL_P(value); - ret = gsSetRowFieldByShort(row, column, shortVal); + byteVal = Z_LVAL_P(value); + if (byteVal < std::numeric_limits::min() || + byteVal > std::numeric_limits::max()) { + return false; + } + ret = gsSetRowFieldByByte(row, column, byteVal); } case GS_TYPE_SHORT: { int16_t byteVal; @@ -346,6 +350,46 @@ intVal = Z_LVAL_P(value); ret = gsSetRowFieldByInteger(row, column, intVal); } + case GS_TYPE_FLOAT: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } + case GS_TYPE_DOUBLE: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } + case GS_TYPE_DOUBLE: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } + case GS_TYPE_TIMESTAMP: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } + case GS_TYPE_BLOB: { + int32_t intVal; + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + ret = gsSetRowFieldByInteger(row, column, intVal); + } } } } From 9e0f78abc1107ab8e3da735c864f80469632369d Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:44:41 +0900 Subject: [PATCH 07/22] implement putRow/getRow --- src/ContainerInfo.h | 6 +- src/StoreFactory.h | 6 +- src/gstype_php.i | 641 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 575 insertions(+), 78 deletions(-) diff --git a/src/ContainerInfo.h b/src/ContainerInfo.h index 58036eb..d9c262a 100644 --- a/src/ContainerInfo.h +++ b/src/ContainerInfo.h @@ -52,9 +52,9 @@ class ContainerInfo { public: ContainerInfo(GSContainerInfo *containerInfo); - ContainerInfo(const GSChar* name = NULL, const GSColumnInfo* props = NULL, - int propsCount = 0, GSContainerType type = GS_CONTAINER_COLLECTION, - bool row_key = true, ExpirationInfo* expiration = NULL); + ContainerInfo(const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, + bool row_key, ExpirationInfo* expiration); ~ContainerInfo(); void set_name(GSChar* containerName); diff --git a/src/StoreFactory.h b/src/StoreFactory.h index cb06c99..411e348 100644 --- a/src/StoreFactory.h +++ b/src/StoreFactory.h @@ -42,9 +42,9 @@ class StoreFactory { ~StoreFactory(); void close(GSBool allRelated = GS_FALSE); static StoreFactory* get_instance(); - Store* get_store(const char* host=NULL, int32_t port=0, const char* cluster_name=NULL, - const char* database=NULL, const char* username=NULL, const char* password=NULL, - const char* notification_member=NULL, const char* notification_provider=NULL); + Store* get_store(const char* host, int32_t port, const char* cluster_name, + const char* database, const char* username, const char* password, + const char* notification_member, const char* notification_provider); string get_version(); private: diff --git a/src/gstype_php.i b/src/gstype_php.i index 77940e6..7167adc 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -14,6 +14,7 @@ limitations under the License. */ +#define ARRAY_SIZE(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) %{ #include "zend_interfaces.h" %} @@ -53,19 +54,19 @@ */ %fragment("throwGSException", "header") { static void throwGSException(griddb::GSException* exception) { - const char* obj_typename = "GSException"; - size_t obj_typename_len = strlen(obj_typename); + const char* objTypename = "GSException"; + size_t objTypenameLen = strlen(objTypename); // Create a resource zval resource; SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); zval ex; - zval ctor_rv; + zval ctorRv; // Create a PHP GSException object - zend_string * obj_typename_zend = zend_string_init(obj_typename, obj_typename_len, 0); - zend_class_entry* ce = zend_lookup_class(obj_typename_zend); - zend_string_release(obj_typename_zend); + zend_string * objTypenameZend = zend_string_init(objTypename, objTypenameLen, 0); + zend_class_entry* ce = zend_lookup_class(objTypenameZend); + zend_string_release(objTypenameZend); if (!ce) { SWIG_FAIL(); } @@ -74,9 +75,9 @@ // Constructor, pass resource to constructor argument zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); - zend_call_method(&ex, ce, &constructor, NULL, 0, &ctor_rv, 1, &resource, NULL TSRMLS_CC); - if (Z_TYPE(ctor_rv) != IS_UNDEF) { - zval_ptr_dtor(&ctor_rv); + zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); + if (Z_TYPE(ctorRv) != IS_UNDEF) { + zval_ptr_dtor(&ctorRv); } // Throw @@ -90,14 +91,17 @@ %} /** - * Typemaps for get_store() function + * Typemaps for get_store() function : support keyword parameter ({"host" : str, + * "port" : int, "clusterName" : str, "database" : str, "usrname" : str, + * "password " : str, "notificationMember" : str, "notificationProvider" : str} */ %typemap(in, numinputs = 1) -(const char* host, int32_t port, const char* cluster_name, const char* database, const char* username, const char* password, - const char* notification_member, const char* notification_provider) (HashTable *arr, HashPosition pos, zval *data) { +(const char* host, int32_t port, const char* cluster_name, const char* database, + const char* username, const char* password, + const char* notification_member, const char* notification_provider) + (HashTable *arr, HashPosition pos, zval *data) { if(Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); - SWIG_FAIL(); } arr = Z_ARRVAL_P(&$input); @@ -130,7 +134,6 @@ $2 = Z_LVAL_P(data); } else { SWIG_PHP_Error(E_ERROR, "Expected port number input as int type"); - SWIG_FAIL(); } } } @@ -153,27 +156,24 @@ $8 = Z_STRVAL_P(data); } else { SWIG_PHP_Error(E_ERROR, "Invalid Property"); - SWIG_FAIL(); }; } } } } -%typemap(typecheck,precedence = SWIG_TYPECHECK_CHAR_ARRAY) (const char* host, int32_t port, const char* cluster_name, const char* database, const char* username, const char* password, - const char* notification_member, const char* notification_provider) { - $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; -} - /** - * Typemaps for ContainerInfo : support keyword parameter ({"name" : str, "columnInfoArray" : array, "type" : int, 'rowKey':boolean, "expiration" : array}) + * Typemaps for ContainerInfo : support keyword parameter ({"name" : str, + * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, "expiration" : array}) */ -%typemap(in) (const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) -(HashTable *arr1, HashPosition pos1, zval *data1, HashTable *arr2, HashPosition pos2, zval *data2, HashTable *arr3, HashPosition pos3, zval *columnName, zval *columnType) { +%typemap(in, numinputs = 1) (const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, bool row_key, + griddb::ExpirationInfo* expiration) + (HashTable *arr1, HashPosition pos1, zval *data1, HashTable *arr2, + HashPosition pos2, zval *data2, HashTable *arr3, + HashPosition pos3, zval *columnName, zval *columnType) { if(Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); - SWIG_FAIL(); } arr1 = Z_ARRVAL_P(&$input); @@ -200,7 +200,6 @@ if(strcmp(name, "name") == 0) { if(Z_TYPE_P(data1) != IS_STRING) { SWIG_PHP_Error(E_ERROR, "Invalid value for property name"); - SWIG_FAIL(); } $1 = Z_STRVAL_P(data1); } @@ -208,7 +207,6 @@ //Input valid is array only if(Z_TYPE_P(data1) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected array as input for property columnInfoArray"); - SWIG_FAIL(); } arr2 = Z_ARRVAL_P(data1); int length2 = (int) zend_hash_num_elements(arr2); @@ -217,7 +215,6 @@ $2 = (GSColumnInfo *) malloc($3*sizeof(GSColumnInfo)); if($2 == NULL) { SWIG_PHP_Error(E_ERROR, "Memory allocation error"); - SWIG_FAIL(); } memset($2, 0x0, $3*sizeof(GSColumnInfo)); int i = 0; @@ -227,26 +224,22 @@ zend_hash_move_forward_ex(arr2, &pos2)) { if(Z_TYPE_P(data2) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected array as elements for columnInfoArray"); - SWIG_FAIL(); } arr3 = Z_ARRVAL_P(data2); int length3 = (int) zend_hash_num_elements(arr3); if(length3 != 2) { SWIG_PHP_Error(E_ERROR, "Expected 2 elements for columnInfoArray property"); - SWIG_FAIL(); } zend_hash_internal_pointer_reset_ex(arr3, &pos3); if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_STRING) { SWIG_PHP_Error(E_ERROR, "Expected string as column name"); - SWIG_FAIL(); } $2[i].name = strdup(Z_STRVAL_P(columnName)); zend_hash_move_forward_ex(arr3, &pos3); if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_LONG) { SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); - SWIG_FAIL(); } $2[i].type = Z_LVAL_P(columnType); i++; @@ -256,7 +249,6 @@ else if(strcmp(name, "type") == 0) { if(Z_TYPE_P(data1) != IS_LONG) { SWIG_PHP_Error(E_ERROR, "Invalid value for property type"); - SWIG_FAIL(); } $4 = Z_LVAL_P(data1); } @@ -264,15 +256,14 @@ $5 = (bool) zval_is_true(data1); } else if(strcmp(name, "expiration") == 0) { - int res = SWIG_ConvertPtr(data1, (void**)&expiration, $descriptor(griddb::ExpirationInfo*), 0 | 0 ); + int res = SWIG_ConvertPtr(data1, (void**)&expiration, + $descriptor(griddb::ExpirationInfo*), 0 | 0 ); if (!SWIG_IsOK(res)) { SWIG_PHP_Error(E_ERROR, "Invalid value for property expiration"); - SWIG_FAIL(); } $6 = (griddb::ExpirationInfo *) expiration; } else { SWIG_PHP_Error(E_ERROR, "Invalid Property"); - SWIG_FAIL(); }; } } @@ -280,25 +271,26 @@ } %typemap(freearg) (const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { + int propsCount, GSContainerType type, bool row_key, + griddb::ExpirationInfo* expiration) { if ($2) { free((void *) $2); } } -%typemap(typecheck, precedence = SWIG_TYPECHECK_CHAR_ARRAY) (const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { - $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; -} - -%fragment("convertToFieldWithType", "header") { +%fragment("convertToFieldWithType", "header", fragment = "convertZvalValueToFloat", + fragment = "convertZvalValueToDouble", + fragment = "convertZvalValueToGSTimestamp") { static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { int res; GSResult ret; + bool vbool; + if(Z_TYPE_P(value) == IS_NULL) { ret = gsSetRowFieldNull(row, column); return (ret == GS_RESULT_OK); } + switch(type) { case GS_TYPE_STRING: { GSChar* stringVal; @@ -315,82 +307,587 @@ return false; } longVal = Z_LVAL_P(value); - ret = gsSetRowFieldByLong(row, column, longVal); + ret = gsSetRowFieldByLong(row, column, longVal); + break; } case GS_TYPE_BOOL: { + if(Z_TYPE_P(value) == IS_STRING) { + return false; + } bool boolVal; - boolVal = (bool) zval_is_true(data1); + boolVal = (bool) zval_is_true(value); ret = gsSetRowFieldByBool(row, column, boolVal); + break; } case GS_TYPE_BYTE: { - int8_t byteVal; + int64_t byteVal; if(Z_TYPE_P(value) != IS_LONG) { return false; } byteVal = Z_LVAL_P(value); - if (byteVal < std::numeric_limits::min() || + if (byteVal < std::numeric_limits::min() || byteVal > std::numeric_limits::max()) { return false; } ret = gsSetRowFieldByByte(row, column, byteVal); + break; } case GS_TYPE_SHORT: { - int16_t byteVal; + int64_t shortVal; if(Z_TYPE_P(value) != IS_LONG) { return false; } shortVal = Z_LVAL_P(value); + if (shortVal < std::numeric_limits::min() || + shortVal > std::numeric_limits::max()) { + return false; + } ret = gsSetRowFieldByShort(row, column, shortVal); + break; } case GS_TYPE_INTEGER: { - int32_t intVal; + int64_t intVal; if(Z_TYPE_P(value) != IS_LONG) { return false; } intVal = Z_LVAL_P(value); - ret = gsSetRowFieldByInteger(row, column, intVal); - } - case GS_TYPE_FLOAT: { - int32_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { + if (intVal < std::numeric_limits::min() || + intVal > std::numeric_limits::max()) { return false; } - intVal = Z_LVAL_P(value); ret = gsSetRowFieldByInteger(row, column, intVal); + break; } - case GS_TYPE_DOUBLE: { - int32_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { + case GS_TYPE_FLOAT: { + float floatVal; + vbool = convertZvalValueToFloat(value, &floatVal); + if(!vbool) { return false; } - intVal = Z_LVAL_P(value); - ret = gsSetRowFieldByInteger(row, column, intVal); + ret = gsSetRowFieldByFloat(row, column, floatVal); + break; } case GS_TYPE_DOUBLE: { - int32_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { + double doubleVal; + vbool = convertZvalValueToDouble(value, &doubleVal); + if(!vbool) { return false; } - intVal = Z_LVAL_P(value); - ret = gsSetRowFieldByInteger(row, column, intVal); + ret = gsSetRowFieldByDouble(row, column, doubleVal); + break; } case GS_TYPE_TIMESTAMP: { - int32_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { + GSTimestamp timestampValue; + vbool = convertZvalValueToGSTimestamp(value, ×tampValue); + if (!vbool) { return false; } - intVal = Z_LVAL_P(value); - ret = gsSetRowFieldByInteger(row, column, intVal); + ret = gsSetRowFieldByTimestamp(row, column, timestampValue); + break; } case GS_TYPE_BLOB: { - int32_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { + GSBlob blobVal; + int64_t size; + if(Z_TYPE_P(value) != IS_STRING) { return false; } - intVal = Z_LVAL_P(value); - ret = gsSetRowFieldByInteger(row, column, intVal); + blobVal.data = Z_STRVAL_P(value); + size = Z_STRLEN_P(value); + blobVal.size = size; + ret = gsSetRowFieldByBlob(row, column, (const GSBlob *)&blobVal); + break; + } + default: + return false; + break; + } + return (ret == GS_RESULT_OK); + } +} + +/** + * Support convert type from Zval value to Double. input in target language can be : + * float or integer + */ +%fragment("convertZvalValueToDouble", "header") { + static bool convertZvalValueToDouble(zval* value, double* doubleValPtr) { + if(Z_TYPE_P(value) == IS_LONG) { + // input can be integer + int64_t intVal; + intVal = Z_LVAL_P(value); + *doubleValPtr = intVal; + //When input value is integer, it should be between -9007199254740992(-2^53)/9007199254740992(2^53). + return (-9007199254740992 <= intVal && 9007199254740992 >= intVal); + } else if(Z_TYPE_P(value) == IS_DOUBLE) { + *doubleValPtr = Z_DVAL_P(value); + return (*doubleValPtr < std::numeric_limits::max() && + *doubleValPtr > -1 *std::numeric_limits::max()); + } else { + return false; + } + } +} + +/** + * Support convert type from Zval value to Float. input in target language can be : + * float or integer + */ +%fragment("convertZvalValueToFloat", "header") { + static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { + if(Z_TYPE_P(value) == IS_LONG) { + // input can be integer + int64_t intVal; + intVal = Z_LVAL_P(value); + *floatValPtr = intVal; + //When input value is integer, it should be between -16777216(-2^24)/16777216(2^24). + return (-16777216 <= intVal && 16777216 >= intVal); + } else if(Z_TYPE_P(value) == IS_DOUBLE) { + *floatValPtr = Z_DVAL_P(value); + return (*floatValPtr < std::numeric_limits::max() && + *floatValPtr > -1 *std::numeric_limits::max()); + } else { + return false; + } + } +} + +/** + * Support convert type from object to GSTimestamp : input in target language can be : datetime object + */ +%fragment("convertZvalValueToGSTimestamp", "header"){ + static bool convertZvalValueToGSTimestamp(zval* datetime, GSTimestamp* timestamp) { + // Support for checking DateTime class + zend_class_entry *ce = NULL; + const char* className = "DateTime"; + + // Support for checking DateTime object + const char* functionName1 = "is_a"; + zval retVal1; + zval functionNameZval1; + zval classNameZval; + + // Support for get timestamp with second + const char* functionName2 = "date_timestamp_get"; + zval retVal2; + zval functionNameZval2; + + // Support for get timestamp with microsecond + const char* functionName3 = "date_format"; + const char* formatStr = "u"; + zval retVal3; + zval functionNameZval3; + zval formatStrZval; + + // Check DateTime class exist or not + zend_string *zstrClassName = zend_string_init(className, strlen(className ), 0); + ce = zend_lookup_class(zstrClassName); + zend_string_release(zstrClassName); + if (!ce) { + return false; + } + + // Check input in target language is DateTime object + ZVAL_STRING(&functionNameZval1, functionName1); + ZVAL_STRING(&classNameZval, className); + zval params1[2] = { + *datetime, + classNameZval + }; + call_user_function(EG(function_table), NULL, + &functionNameZval1, &retVal1, + ARRAY_SIZE(params1), params1 TSRMLS_CC); + bool output = zval_is_true(&retVal1); + if (!output) { + return false; + }; + + // Convert from datetime to timestamp + // (1)Get timestamp with seconds + ZVAL_STRING(&functionNameZval2, functionName2); + zval params2[1] = {*datetime}; + call_user_function(EG(function_table), NULL, + &functionNameZval2, + &retVal2, ARRAY_SIZE(params2), + params2 TSRMLS_CC); + int64_t timestampSecond = Z_LVAL(retVal2); + + // (2)Get timestamp with microsecond + ZVAL_STRING(&functionNameZval3, functionName3); + ZVAL_STRING(&formatStrZval, formatStr); + zval params3[2] = { + *datetime, + formatStrZval + }; + call_user_function(EG(function_table), NULL, + &functionNameZval3, + &retVal3, ARRAY_SIZE(params3), + params3 TSRMLS_CC); + int64_t timestampMicroSecond = atoi(Z_STRVAL(retVal3)); + + // Convert timestamp to milisecond + *timestamp = (timestampSecond * 1000) + (timestampMicroSecond/1000); + return true; + } +} + +/** + * Typemaps for put_row() function + */ +%typemap(in, fragment = "convertToFieldWithType") (GSRow *row) + (HashTable *arr, HashPosition pos, zval* data) { + $1 = NULL; + const int size = 60; + if(Z_TYPE_P(&$input) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected an array as input"); + } + arr = Z_ARRVAL_P(&$input); + int length = (int) zend_hash_num_elements(arr); + GSRow *tmpRow = arg1->getGSRowPtr(); + int colNum = arg1->getColumnCount(); + GSType* typeList = arg1->getGSTypeList(); + + if(length != colNum) { + SWIG_PHP_Error(E_ERROR, "Num row is different with container info"); + } + + if(length > 0) { + for(zend_hash_internal_pointer_reset_ex(arr, &pos); + (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; + zend_hash_move_forward_ex(arr, &pos)) { + GSType type = typeList[pos]; + if (!(convertToFieldWithType(tmpRow, pos, data, type))) { + char gsType[size]; + sprintf(gsType, "Invalid value for column %d, type should be : %d", pos, type); + SWIG_PHP_Error(E_ERROR, gsType); + } + } + } +} + +/** + * Support convert row key Field from zval* in target language to C Object with specific type + */ +%fragment("convertToRowKeyFieldWithType", "header") { +static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSType type) { + field.type = type; + + if (Z_TYPE_P(value) == IS_NULL) { + //Not support NULL + return false; + } + + int checkConvert = 0; + switch (type) { + case (GS_TYPE_STRING): + if(Z_TYPE_P(value) != IS_STRING) { + return false; + } + field.value.asString = strdup(Z_STRVAL_P(value)); + break; + case (GS_TYPE_INTEGER): + int64_t intVal; + if (Z_TYPE_P(value) != IS_LONG) { + return false; + } + intVal = Z_LVAL_P(value); + if (intVal < std::numeric_limits::min() || + intVal > std::numeric_limits::max()) { + return false; } + field.value.asInteger = intVal; + break; + case (GS_TYPE_LONG): + if(Z_TYPE_P(value) != IS_LONG) { + return false; + } + field.value.asLong = Z_LVAL_P(value); + break; + case (GS_TYPE_TIMESTAMP): + return convertZvalValueToGSTimestamp(value, &field.value.asTimestamp); + break; + default: + //Not support for now + return false; + break; + } + return true; +} +} + +/* +* Typemap for get_row +*/ +%typemap(in, fragment = "convertToRowKeyFieldWithType") + (griddb::Field* keyFields)(griddb::Field field) { + $1 = &field; + if (Z_TYPE_P(&$input) == IS_NULL) { + $1->type = GS_TYPE_NULL; + } else { + GSType* typeList = arg1->getGSTypeList(); + GSType type = typeList[0]; + if (!convertToRowKeyFieldWithType(*$1, &$input, type)) { + SWIG_PHP_Error(E_ERROR, "Can not convert to row field"); } } } +%typemap(in, numinputs = 0) (GSRow *rowdata) { + $1 = NULL; +} + +/** + * Support convert data from GSRow* row to zval array + */ +%fragment("getRowFields", "header", fragment = "convertTimestampToObject") { +static bool getRowFields(GSRow* row, int columnCount, + GSType* typeList, int* columnError, + GSType* fieldTypeError, zval* outList) { + GSResult ret; + bool retVal = true; + for (int i = 0; i < columnCount; i++) { + //Check NULL value + GSBool nullValue; + ret = gsGetRowFieldNull(row, (int32_t) i, &nullValue); + if (ret != GS_RESULT_OK) { + *columnError = i; + retVal = false; + *fieldTypeError = GS_TYPE_NULL; + return retVal; + } + if (nullValue) { + add_index_zval(outList, i, NULL); + continue; + } + switch(typeList[i]) { + case GS_TYPE_LONG: { + int64_t longValue; + ret = gsGetRowFieldAsLong(row, (int32_t) i, &longValue); + add_index_long(outList, i, longValue); + break; + } + case GS_TYPE_STRING: { + GSChar* stringValue; + ret = gsGetRowFieldAsString(row, (int32_t) i, (const GSChar **)&stringValue); + add_index_string(outList, i, stringValue); + break; + } + case GS_TYPE_BLOB: { + GSBlob blobValue = {0}; + ret = gsGetRowFieldAsBlob(row, (int32_t) i, &blobValue); + add_index_string(outList, i, (char*)blobValue.data); + break; + } + case GS_TYPE_BOOL: { + GSBool boolValue; + bool boolVal; + ret = gsGetRowFieldAsBool(row, (int32_t) i, &boolValue); + if(boolValue == GS_TRUE){ + boolVal = true; + } else { + boolVal = false; + } + add_index_bool(outList, i, boolVal); + break; + } + case GS_TYPE_INTEGER: { + int32_t intValue; + ret = gsGetRowFieldAsInteger(row, (int32_t) i, &intValue); + add_index_long(outList, i, intValue); + break; + } + case GS_TYPE_FLOAT: { + float floatValue; + ret = gsGetRowFieldAsFloat(row, (int32_t) i, &floatValue); + add_index_double(outList, i, floatValue); + break; + } + case GS_TYPE_DOUBLE: { + double doubleValue; + ret = gsGetRowFieldAsDouble(row, (int32_t) i, &doubleValue); + add_index_double(outList, i, doubleValue); + break; + } + case GS_TYPE_TIMESTAMP: { + GSTimestamp timestampValue; + ret = gsGetRowFieldAsTimestamp(row, (int32_t) i, ×tampValue); + zval dateTime; + convertTimestampToObject(×tampValue, &dateTime); + add_index_zval(outList, i, &dateTime); + break; + } + case GS_TYPE_BYTE: { + int8_t byteValue; + ret = gsGetRowFieldAsByte(row, (int32_t) i, &byteValue); + add_index_long(outList, i, byteValue); + break; + } + case GS_TYPE_SHORT: { + int16_t shortValue; + ret = gsGetRowFieldAsShort(row, (int32_t) i, &shortValue); + add_index_long(outList, i, shortValue); + break; + } + default: { + // NOT OK + ret = -1; + break; + } + } + if (ret != GS_RESULT_OK) { + *columnError = i; + *fieldTypeError = typeList[i]; + retVal = false; + return retVal; + } + } + return retVal; +} +} + +/** + * Support convert data from timestamp to DateTime object in target language + */ +%fragment("convertTimestampToObject", "header") { +static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { + const int size = 60; + char timeStr[size]; + zval functionNameZval; + zval formatStringZval; + zval formattedTimePhp; + const char* functionName = "date_create_from_format"; + const char* formatString = "U.u"; + + // Get time with seconds + int64_t second = *timestamp/1000; + + // Get time with microSeconds + int64_t microSecond = (*timestamp % 1000) * 1000; + sprintf(timeStr, "%ld.%06d", second, microSecond); + + ZVAL_STRING(&functionNameZval, functionName); + ZVAL_STRING(&formatStringZval, formatString); + ZVAL_STRING(&formattedTimePhp, timeStr); + zval params[2] = { + formatStringZval, + formattedTimePhp + }; + + call_user_function(EG(function_table), NULL, &functionNameZval, dateTime, + ARRAY_SIZE(params), params TSRMLS_CC); +} +} + +/* +* This typemap argument out does not get data from argument "GSRow *rowdata" +* The argument "GSRow *rowdata" is not used in the function Container::get(), it only for the purpose of typemap matching pattern +* The actual output data is store in class member and can be get by function getGSRowPtr() +*/ +//%typemap(argout, fragment = "getRowFields") (GSRow *rowdata) { +%typemap(argout, fragment = "getRowFields") (GSRow *rowdata) { + if (result == GS_FALSE) { + RETVAL_NULL(); + } else { + bool retVal; + int errorColumn; + GSType errorType; + const int size = 60; + + // Get row pointer + GSRow* row = arg1->getGSRowPtr(); + + // Get row fields + array_init_size(return_value, arg1->getColumnCount()); + retVal = getRowFields(row, arg1->getColumnCount(), + arg1->getGSTypeList(), + &errorColumn, &errorType, + return_value); + + if (retVal == false) { + char errorMsg[size]; + sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); + SWIG_PHP_Error(E_ERROR, errorMsg); + } + } +} + +/** + * Type map for Rowset::next() + */ +%typemap(in, numinputs = 0) (GSRowSetType* type, bool* hasNextRow, + griddb::QueryAnalysisEntry** queryAnalysis, griddb::AggregationResult** aggResult) + (GSRowSetType typeTmp, bool hasNextRowTmp, + griddb::QueryAnalysisEntry* queryAnalysisTmp = NULL, griddb::AggregationResult* aggResultTmp = NULL) { + $1 = &typeTmp; + hasNextRowTmp = true; + $2 = &hasNextRowTmp; + $3 = &queryAnalysisTmp; + $4 = &aggResultTmp; +} + +%typemap(argout, fragment = "getRowFields") (GSRowSetType* type, bool* hasNextRow, + griddb::QueryAnalysisEntry** queryAnalysis, griddb::AggregationResult** aggResult) { + + const int size = 60; + switch (*$1) { + case (GS_ROW_SET_CONTAINER_ROWS): { + bool retVal; + int errorColumn; + if (*$2 == false) { + RETURN_NULL(); + } else { + GSRow* row = arg1->getGSRowPtr(); + array_init_size(return_value, arg1->getColumnCount()); + GSType errorType; + retVal = getRowFields(row, arg1->getColumnCount(), + arg1->getGSTypeList(), + &errorColumn, &errorType, return_value); + if (retVal == false) { + char errorMsg[size]; + sprintf(errorMsg, "Can't get data for field %d with type%d", errorColumn, errorType); + SWIG_PHP_Error(E_ERROR, errorMsg); + } + } + break; + } + case (GS_ROW_SET_AGGREGATION_RESULT): { + SWIG_SetPointerZval(return_value, (void *) (*$4), + $descriptor(griddb::AggregationResult *), SWIG_CAST_NEW_MEMORY); + + break; + } + case (GS_ROW_SET_QUERY_ANALYSIS): { + // Not support now + break; + } + default: { + SWIG_PHP_Error(E_ERROR, "Invalid type"); + break; + } + } +} + +/* +* Typemap for get function in AggregationResult class +*/ +%typemap(in, numinputs = 0) (griddb::Field *agValue) (griddb::Field tmpAgValue){ + $1 = &tmpAgValue; +} +%typemap(argout) (griddb::Field *agValue) { + int i; + switch ($1->type) { + case GS_TYPE_LONG: { + RETVAL_LONG($1->value.asLong); + break; + } + case GS_TYPE_DOUBLE: { + RETVAL_DOUBLE($1->value.asDouble); + break; + } + case GS_TYPE_TIMESTAMP: + convertTimestampToObject(&($1->value.asTimestamp), return_value); + default: + RETURN_NULL(); + } +} + + From e5a18d6117b827c6b6d102677dd4dd56f09fbec7 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:45:10 +0900 Subject: [PATCH 08/22] implement typemap for getTimeMillis(DateTime $dt) --- src/TimestampUtils.cpp | 6 +++--- src/TimestampUtils.h | 2 +- src/gstype_php.i | 48 ++++++++++++++++++++++++++++++------------ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/TimestampUtils.cpp b/src/TimestampUtils.cpp index e1db012..f32bd1c 100644 --- a/src/TimestampUtils.cpp +++ b/src/TimestampUtils.cpp @@ -25,10 +25,10 @@ namespace griddb { } /** - * Convert from Python timestamp to GridDB timestamp + * Convert from PHP DateTime to GridDB timestamp */ - int64_t TimestampUtils::get_time_millis(double timestamp){ - return int64_t(timestamp * 1000); + int64_t TimestampUtils::get_time_millis(int64_t timestamp){ + return timestamp; } } /* namespace griddb */ diff --git a/src/TimestampUtils.h b/src/TimestampUtils.h index c6b0585..ce71d7c 100644 --- a/src/TimestampUtils.h +++ b/src/TimestampUtils.h @@ -29,7 +29,7 @@ class TimestampUtils { public: TimestampUtils(); ~TimestampUtils(); - static int64_t get_time_millis(double timestamp); + static int64_t get_time_millis(int64_t timestamp); }; } /* namespace griddb */ diff --git a/src/gstype_php.i b/src/gstype_php.i index 7167adc..61b9da0 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -40,9 +40,14 @@ %attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); // rename all method to camel cases -%rename(getErrorMessage) griddb::GSException::get_message; %rename("%(lowercamelcase)s", %$isfunction) ""; +// "getMessage" is a default final method of Exception class in PHP. So convert name into getErrorMessage +%rename(getErrorMessage) griddb::GSException::get_message; + +// "default" is a PHP keyword. So convert name into DEFAULT_TYPE +%rename(DEFAULT_TYPE) griddb::IndexType::DEFAULT; + /* * ignore unnecessary functions */ @@ -531,12 +536,13 @@ } /** - * Typemaps for put_row() function - */ +* Typemaps for RowSet::update() and Container::put() function +* The argument "GSRow *row" is not used in the function body, it only for the purpose of typemap matching pattern +* The actual input data is store in class member and can be get by function getGSRowPtr() +*/ %typemap(in, fragment = "convertToFieldWithType") (GSRow *row) (HashTable *arr, HashPosition pos, zval* data) { - $1 = NULL; - const int size = 60; + const int SIZE = 60; if(Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected an array as input"); } @@ -556,7 +562,7 @@ zend_hash_move_forward_ex(arr, &pos)) { GSType type = typeList[pos]; if (!(convertToFieldWithType(tmpRow, pos, data, type))) { - char gsType[size]; + char gsType[SIZE]; sprintf(gsType, "Invalid value for column %d, type should be : %d", pos, type); SWIG_PHP_Error(E_ERROR, gsType); } @@ -569,6 +575,7 @@ */ %fragment("convertToRowKeyFieldWithType", "header") { static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSType type) { + bool vbool; field.type = type; if (Z_TYPE_P(value) == IS_NULL) { @@ -603,7 +610,10 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy field.value.asLong = Z_LVAL_P(value); break; case (GS_TYPE_TIMESTAMP): - return convertZvalValueToGSTimestamp(value, &field.value.asTimestamp); + vbool = convertZvalValueToGSTimestamp(value, &field.value.asTimestamp); + if (!vbool) { + return false; + } break; default: //Not support for now @@ -749,8 +759,8 @@ static bool getRowFields(GSRow* row, int columnCount, */ %fragment("convertTimestampToObject", "header") { static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { - const int size = 60; - char timeStr[size]; + const int SIZE = 60; + char timeStr[SIZE]; zval functionNameZval; zval formatStringZval; zval formattedTimePhp; @@ -790,7 +800,7 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { bool retVal; int errorColumn; GSType errorType; - const int size = 60; + const int SIZE = 60; // Get row pointer GSRow* row = arg1->getGSRowPtr(); @@ -803,7 +813,7 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { return_value); if (retVal == false) { - char errorMsg[size]; + char errorMsg[SIZE]; sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); SWIG_PHP_Error(E_ERROR, errorMsg); } @@ -827,7 +837,7 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { %typemap(argout, fragment = "getRowFields") (GSRowSetType* type, bool* hasNextRow, griddb::QueryAnalysisEntry** queryAnalysis, griddb::AggregationResult** aggResult) { - const int size = 60; + const int SIZE = 60; switch (*$1) { case (GS_ROW_SET_CONTAINER_ROWS): { bool retVal; @@ -842,7 +852,7 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { arg1->getGSTypeList(), &errorColumn, &errorType, return_value); if (retVal == false) { - char errorMsg[size]; + char errorMsg[SIZE]; sprintf(errorMsg, "Can't get data for field %d with type%d", errorColumn, errorType); SWIG_PHP_Error(E_ERROR, errorMsg); } @@ -890,4 +900,16 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { } } +/* +* Typemap for TimestampUtils::get_time_millis: convert DateTime object from target language to timestamp with millisecond in C++ layer +*/ +%typemap(in, fragement = "convertZvalValueToGSTimestamp") (int64_t timestamp){ + bool vbool; + GSTimestamp timestampValue; + vbool = convertZvalValueToGSTimestamp(&$input, ×tampValue); + if(!vbool){ + SWIG_PHP_Error(E_ERROR, "Expected a DateTime object as input"); + } + $1 = timestampValue; +} From 95a1f8d02ce9812b1d664833b7c1ab68c8c62fa0 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:45:40 +0900 Subject: [PATCH 09/22] implement attribute --- src/Container.cpp | 34 +- src/Container.h | 4 +- src/Query.cpp | 13 +- src/Query.h | 2 +- src/gstype_php.i | 943 +++++++++++++++++++++++++++------------------- 5 files changed, 563 insertions(+), 433 deletions(-) diff --git a/src/Container.cpp b/src/Container.cpp index 8bdc1c0..b1df025 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -61,7 +61,7 @@ namespace griddb { freeMemoryContainer(); throw GSException(mContainer, "Memory allocation error"); } - + mContainerInfo->timeSeriesProperties = NULL; mContainerInfo->triggerInfoList = NULL; mContainerInfo->dataAffinity = NULL; @@ -74,8 +74,6 @@ namespace griddb { } Container::~Container() { - - // allRelated = FALSE, since all row object is managed by Row class close(GS_FALSE); } @@ -124,20 +122,9 @@ namespace griddb { * @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 (name) { - GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER; - indexInfo.name = name; - indexInfo.type = index_type; - indexInfo.columnName = column_name; - ret = gsDropIndexDetail(mContainer, &indexInfo); - } else { - ret = gsDropIndex(mContainer, column_name, index_type); - } + void Container::drop_index(const char* column_name, GSIndexTypeFlags index_type) { + GSResult ret = gsDropIndex(mContainer, column_name, index_type); if (!GS_SUCCEEDED(ret)) { throw GSException(mContainer, ret); @@ -148,20 +135,9 @@ namespace griddb { * @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 (name){ - GSIndexInfo indexInfo = GS_INDEX_INFO_INITIALIZER; - indexInfo.name = name; - indexInfo.type = index_type; - indexInfo.columnName = column_name; - ret = gsCreateIndexDetail(mContainer, &indexInfo); - } else { - ret = gsCreateIndex(mContainer, column_name, index_type); - } + void Container::create_index(const char *column_name, GSIndexTypeFlags index_type) { + GSResult ret = gsCreateIndex(mContainer, column_name, index_type); if (!GS_SUCCEEDED(ret)) { throw GSException(mContainer, ret); diff --git a/src/Container.h b/src/Container.h index 74f7f47..4569006 100644 --- a/src/Container.h +++ b/src/Container.h @@ -43,8 +43,8 @@ class Container { ~Container(); void close(GSBool allRelated = GS_FALSE); 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); + void create_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT); + void drop_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT); bool put(GSRow *row); Query* query(const char *query); void abort(); diff --git a/src/Query.cpp b/src/Query.cpp index 8bd596d..c4166ff 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -100,9 +100,8 @@ namespace griddb { /** * @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){ + void Query::set_fetch_options(int limit){ GSFetchOption fetchOption; GSResult ret; if (limit >= 0) { @@ -112,15 +111,5 @@ namespace griddb { 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 (!GS_SUCCEEDED(ret)) { - throw GSException(mQuery, ret); - } -#endif - } } } diff --git a/src/Query.h b/src/Query.h index 3500886..da2406e 100644 --- a/src/Query.h +++ b/src/Query.h @@ -41,7 +41,7 @@ class Query { ~Query(); void close(); RowSet* fetch(bool for_update = false); - void set_fetch_options(int limit = -1, bool partial = false); + void set_fetch_options(int limit); RowSet* get_row_set(); GSQuery* gs_ptr(); diff --git a/src/gstype_php.i b/src/gstype_php.i index 61b9da0..e0e711e 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -18,10 +18,29 @@ %{ #include "zend_interfaces.h" %} +/* + * Change method names in PHP + */ +//Rename all method to camel cases +%rename("%(lowercamelcase)s", %$isfunction) ""; +//"getMessage" is a default final method of Exception class in PHP. So convert name into getErrorMessage +%rename(getErrorMessage) griddb::GSException::get_message; +//"default" is a PHP keyword. So convert name into DEFAULT_TYPE +%rename(DEFAULT_TYPE) griddb::IndexType::DEFAULT; -//Read only attribute Container::type +/* + * Use attribute in PHP language + */ %include -//%attribute(griddb::Store, int, type_data, get_data); + +//Read only attribute Container::type +%attribute(griddb::Container, int, type, get_type); +//Read only attribute GSException::is_timeout +%attribute(griddb::GSException, bool, isTimeout, is_timeout); +//Read only attribute RowSet::size +%attribute(griddb::RowSet, int32_t, size, size); +//Read only attribute RowSet::type +%attribute(griddb::RowSet, GSRowSetType, type, type); //Read only attribute ContainerInfo::name %attribute(griddb::ContainerInfo, GSChar*, name, get_name, set_name); //Read only attribute ContainerInfo::type @@ -39,79 +58,74 @@ //Read only attribute ExpirationInfo::divisionCount %attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); -// rename all method to camel cases -%rename("%(lowercamelcase)s", %$isfunction) ""; - -// "getMessage" is a default final method of Exception class in PHP. So convert name into getErrorMessage -%rename(getErrorMessage) griddb::GSException::get_message; - -// "default" is a PHP keyword. So convert name into DEFAULT_TYPE -%rename(DEFAULT_TYPE) griddb::IndexType::DEFAULT; - /* - * ignore unnecessary functions + * Ignore unnecessary functions */ %ignore griddb::ContainerInfo::ContainerInfo(GSContainerInfo* containerInfo); %ignore griddb::GSException::get_code; +%ignore ColumnInfoList; /** * Support throw exception in PHP language */ %fragment("throwGSException", "header") { - static void throwGSException(griddb::GSException* exception) { - const char* objTypename = "GSException"; - size_t objTypenameLen = strlen(objTypename); - // Create a resource - zval resource; +static void throwGSException(griddb::GSException* exception) { + const char* objTypename = "GSException"; + size_t objTypenameLen = strlen(objTypename); + // Create a resource + zval resource; - SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); - zval ex; - zval ctorRv; + SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); + zval ex; + zval ctorRv; - // Create a PHP GSException object - zend_string * objTypenameZend = zend_string_init(objTypename, objTypenameLen, 0); - zend_class_entry* ce = zend_lookup_class(objTypenameZend); - zend_string_release(objTypenameZend); - if (!ce) { - SWIG_FAIL(); - } + // Create a PHP GSException object + zend_string * objTypenameZend = zend_string_init(objTypename, objTypenameLen, 0); + zend_class_entry* ce = zend_lookup_class(objTypenameZend); + zend_string_release(objTypenameZend); + if (!ce) { + SWIG_FAIL(); + } - object_and_properties_init(&ex, ce, NULL); + object_and_properties_init(&ex, ce, NULL); - // Constructor, pass resource to constructor argument - zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); - zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); - if (Z_TYPE(ctorRv) != IS_UNDEF) { - zval_ptr_dtor(&ctorRv); - } + // Constructor, pass resource to constructor argument + zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); + zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); + if (Z_TYPE(ctorRv) != IS_UNDEF) { + zval_ptr_dtor(&ctorRv); + } - // Throw - zend_throw_exception_object(&ex); + // Throw + zend_throw_exception_object(&ex); } } + %typemap(throws, fragment="throwGSException") griddb::GSException %{ griddb::GSException* tmpException = new griddb::GSException(&$1); throwGSException(tmpException); return; - %} +%} /** - * Typemaps for get_store() function : support keyword parameter ({"host" : str, - * "port" : int, "clusterName" : str, "database" : str, "usrname" : str, - * "password " : str, "notificationMember" : str, "notificationProvider" : str} + * Typemaps for get_store() function : support keyword parameter ("host" : str, + * "port" : int, "clusterName" : str, "database" : str, "username" : str, + * "password " : str, "notificationMember" : str, "notificationProvider" : str) */ %typemap(in, numinputs = 1) (const char* host, int32_t port, const char* cluster_name, const char* database, const char* username, const char* password, const char* notification_member, const char* notification_provider) (HashTable *arr, HashPosition pos, zval *data) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { + + if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); } arr = Z_ARRVAL_P(&$input); int length = (int) zend_hash_num_elements(arr); char* name = 0; + //Create $1, $2, $3, $3, $4, $5, $6, $7, $8 with default value $1 = NULL; $2 = 0; $3 = NULL; @@ -124,126 +138,156 @@ zend_string *key; int key_len; long index; - for(zend_hash_internal_pointer_reset_ex(arr, &pos); + for (zend_hash_internal_pointer_reset_ex(arr, &pos); (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; zend_hash_move_forward_ex(arr, &pos)) { - if(zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { + if (zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { name = ZSTR_VAL(key); - if(strcmp(name, "host") == 0) { + if (strcmp(name, "host") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for host property"); + } $1 = Z_STRVAL_P(data); } - else if(strcmp(name, "port") == 0) { + else if (strcmp(name, "port") == 0) { //Input valid is number only - { - if(Z_TYPE_P(data) == IS_LONG) { - $2 = Z_LVAL_P(data); - } else { - SWIG_PHP_Error(E_ERROR, "Expected port number input as int type"); - } + if (Z_TYPE_P(data) != IS_LONG){ + SWIG_PHP_Error(E_ERROR, "Expected integer as input for port number property"); } + $2 = Z_LVAL_P(data); } - else if(strcmp(name, "clusterName") == 0) { + else if (strcmp(name, "clusterName") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for clusterName property"); + } $3 = Z_STRVAL_P(data); } - else if(strcmp(name, "database") == 0) { + else if (strcmp(name, "database") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for database property"); + } $4 = Z_STRVAL_P(data); } - else if(strcmp(name, "username") == 0) { + else if (strcmp(name, "username") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for username property"); + } $5 = Z_STRVAL_P(data); } - else if(strcmp(name, "password") == 0) { + else if (strcmp(name, "password") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for password property"); + } $6 = Z_STRVAL_P(data); } - else if(strcmp(name, "notificationMember") == 0) { + else if (strcmp(name, "notificationMember") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for notificationMember property"); + } $7 = Z_STRVAL_P(data); } - else if(strcmp(name, "notificationProvider") == 0) { + else if (strcmp(name, "notificationProvider") == 0) { + if (Z_TYPE_P(data) != IS_STRING){ + SWIG_PHP_Error(E_ERROR, "Expected string as input for host notificationProvider property"); + } $8 = Z_STRVAL_P(data); } else { SWIG_PHP_Error(E_ERROR, "Invalid Property"); }; + } else { + SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); } } } } /** - * Typemaps for ContainerInfo : support keyword parameter ({"name" : str, - * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, "expiration" : array}) + * Typemaps for ContainerInfo : support keyword parameter ("name" : str, + * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, "expiration" : expiraion object) */ %typemap(in, numinputs = 1) (const GSChar* name, const GSColumnInfo* props, int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) - (HashTable *arr1, HashPosition pos1, zval *data1, HashTable *arr2, - HashPosition pos2, zval *data2, HashTable *arr3, - HashPosition pos3, zval *columnName, zval *columnType) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { + (HashTable *arrContainerInfo, HashPosition posContainerInfo, zval *dataContainerInfo, + HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, + HashTable *arrColumnInfo, HashPosition posColumnInfo, + zval *columnName, zval *columnType) { + + if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); } - arr1 = Z_ARRVAL_P(&$input); - int length1 = (int) zend_hash_num_elements(arr1); char* name = 0; - //Create $1, $2, $3, $3, $4, $5, $6 with default value + // Create $1, $2, $3, $3, $4, $5, $6 with default value $1 = NULL; $2 = NULL; $3 = 0; $4 = GS_CONTAINER_COLLECTION; - $5 = true;//defautl value rowKey = true + $5 = true;//default value rowKey = true $6 = NULL; - bool boolVal, vbool; griddb::ExpirationInfo* expiration; - if (length1 > 0) { + + // Fetch the hash table from a zval input + arrContainerInfo = Z_ARRVAL_P(&$input); + int sizeOfContainerInfo = (int) zend_hash_num_elements(arrContainerInfo); + + if (sizeOfContainerInfo > 0) { zend_string *key; int key_len; long index; - for(zend_hash_internal_pointer_reset_ex(arr1, &pos1); - (data1 = zend_hash_get_current_data_ex(arr1, &pos1)) != NULL; - zend_hash_move_forward_ex(arr1, &pos1)) { - if(zend_hash_get_current_key_ex(arr1, &key, (zend_ulong*)&index, &pos1) == HASH_KEY_IS_STRING) { + for (zend_hash_internal_pointer_reset_ex(arrContainerInfo, &posContainerInfo); + (dataContainerInfo = zend_hash_get_current_data_ex(arrContainerInfo, &posContainerInfo)) != NULL; + zend_hash_move_forward_ex(arrContainerInfo, &posContainerInfo)) { + if (zend_hash_get_current_key_ex(arrContainerInfo, &key, (zend_ulong*)&index, &posContainerInfo) == HASH_KEY_IS_STRING) { name = ZSTR_VAL(key); - if(strcmp(name, "name") == 0) { - if(Z_TYPE_P(data1) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Invalid value for property name"); + if (strcmp(name, "name") == 0) { + if (Z_TYPE_P(dataContainerInfo) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as input for name property"); } - $1 = Z_STRVAL_P(data1); + $1 = Z_STRVAL_P(dataContainerInfo); } - else if(strcmp(name, "columnInfoArray") == 0) { - //Input valid is array only - if(Z_TYPE_P(data1) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array as input for property columnInfoArray"); + else if (strcmp(name, "columnInfoArray") == 0) { + // Input valid is array only + if (Z_TYPE_P(dataContainerInfo) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array as input for columnInfo property"); } - arr2 = Z_ARRVAL_P(data1); - int length2 = (int) zend_hash_num_elements(arr2); - $3 = length2; - if($3 > 0) { + // Fetch the hash table from a zval + arrColumnInfoArray = Z_ARRVAL_P(dataContainerInfo); + int sizeOfColumnInfoArray = (int) zend_hash_num_elements(arrColumnInfoArray); + $3 = sizeOfColumnInfoArray; + if ($3 > 0) { $2 = (GSColumnInfo *) malloc($3*sizeof(GSColumnInfo)); - if($2 == NULL) { + if ($2 == NULL) { SWIG_PHP_Error(E_ERROR, "Memory allocation error"); } memset($2, 0x0, $3*sizeof(GSColumnInfo)); + + // Get name and type of column int i = 0; - //Get element "name", "status". - for(zend_hash_internal_pointer_reset_ex(arr2, &pos2); - (data2 = zend_hash_get_current_data_ex(arr2, &pos2)) != NULL; - zend_hash_move_forward_ex(arr2, &pos2)) { - if(Z_TYPE_P(data2) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array as elements for columnInfoArray"); + for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); + (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; + zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { + if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array property as ColumnInfo element"); } - arr3 = Z_ARRVAL_P(data2); - int length3 = (int) zend_hash_num_elements(arr3); - if(length3 != 2) { - SWIG_PHP_Error(E_ERROR, "Expected 2 elements for columnInfoArray property"); + // Fetch the hash table from a zval + arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); + int sizeOfColumnInfo = (int) zend_hash_num_elements(arrColumnInfo); + if (sizeOfColumnInfo != 2) { + SWIG_PHP_Error(E_ERROR, "Expected two elements for columnInfo property"); } - zend_hash_internal_pointer_reset_ex(arr3, &pos3); - if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_STRING) { + // Get column name + zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_STRING) { SWIG_PHP_Error(E_ERROR, "Expected string as column name"); } - $2[i].name = strdup(Z_STRVAL_P(columnName)); - zend_hash_move_forward_ex(arr3, &pos3); - if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arr3, &pos3)) != IS_LONG) { + $2[i].name = Z_STRVAL_P(columnName); + + // Get column type + zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_LONG) { SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); } $2[i].type = Z_LVAL_P(columnType); @@ -251,20 +295,23 @@ } } } - else if(strcmp(name, "type") == 0) { - if(Z_TYPE_P(data1) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Invalid value for property type"); + else if (strcmp(name, "type") == 0) { + if (Z_TYPE_P(dataContainerInfo) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected integer as input for type property"); } - $4 = Z_LVAL_P(data1); + $4 = Z_LVAL_P(dataContainerInfo); } - else if(strcmp(name, "rowKey") == 0) { - $5 = (bool) zval_is_true(data1); + else if (strcmp(name, "rowKey") == 0) { + if (Z_TYPE_P(dataContainerInfo) == IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected boolean as input for rowKey property"); + } + $5 = (bool) zval_is_true(dataContainerInfo); } - else if(strcmp(name, "expiration") == 0) { - int res = SWIG_ConvertPtr(data1, (void**)&expiration, + else if (strcmp(name, "expiration") == 0) { + int res = SWIG_ConvertPtr(dataContainerInfo, (void**)&expiration, $descriptor(griddb::ExpirationInfo*), 0 | 0 ); if (!SWIG_IsOK(res)) { - SWIG_PHP_Error(E_ERROR, "Invalid value for property expiration"); + SWIG_PHP_Error(E_ERROR, "Expected expiration object as input for expiration property"); } $6 = (griddb::ExpirationInfo *) expiration; } else { @@ -275,6 +322,9 @@ } } +/** + * Cleanup argument data for ContainerInfo constructor + */ %typemap(freearg) (const GSChar* name, const GSColumnInfo* props, int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { @@ -283,256 +333,249 @@ } } -%fragment("convertToFieldWithType", "header", fragment = "convertZvalValueToFloat", +%fragment("convertToFieldWithType", "header", + fragment = "convertZvalValueToFloat", fragment = "convertZvalValueToDouble", - fragment = "convertZvalValueToGSTimestamp") { - static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { - int res; - GSResult ret; - bool vbool; - - if(Z_TYPE_P(value) == IS_NULL) { - ret = gsSetRowFieldNull(row, column); - return (ret == GS_RESULT_OK); - } - - switch(type) { - case GS_TYPE_STRING: { - GSChar* stringVal; - if(Z_TYPE_P(value) != IS_STRING) { - return false; - } - stringVal = Z_STRVAL_P(value); - ret = gsSetRowFieldByString(row, column, stringVal); - break; + fragment = "convertDateTimeObjectToGSTimestamp") { +static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { + GSResult returnCode; + bool isSuccess; + + if (Z_TYPE_P(value) == IS_NULL) { + returnCode = gsSetRowFieldNull(row, column); + return (GS_SUCCEEDED(returnCode)); + } + + switch (type) { + case GS_TYPE_STRING: { + GSChar* stringVal; + if (Z_TYPE_P(value) != IS_STRING) { + return false; } - case GS_TYPE_LONG: { - int64_t longVal; - if(Z_TYPE_P(value) != IS_LONG) { - return false; - } - longVal = Z_LVAL_P(value); - ret = gsSetRowFieldByLong(row, column, longVal); - break; + stringVal = Z_STRVAL_P(value); + returnCode = gsSetRowFieldByString(row, column, stringVal); + break; + } + case GS_TYPE_LONG: { + int64_t longVal; + if (Z_TYPE_P(value) != IS_LONG) { + return false; } - case GS_TYPE_BOOL: { - if(Z_TYPE_P(value) == IS_STRING) { - return false; - } - bool boolVal; - boolVal = (bool) zval_is_true(value); - ret = gsSetRowFieldByBool(row, column, boolVal); - break; + longVal = Z_LVAL_P(value); + returnCode = gsSetRowFieldByLong(row, column, longVal); + break; + } + case GS_TYPE_BOOL: { + if (Z_TYPE_P(value) == IS_STRING) { + return false; } - case GS_TYPE_BYTE: { - int64_t byteVal; - if(Z_TYPE_P(value) != IS_LONG) { - return false; - } - byteVal = Z_LVAL_P(value); - if (byteVal < std::numeric_limits::min() || - byteVal > std::numeric_limits::max()) { - return false; - } - ret = gsSetRowFieldByByte(row, column, byteVal); - break; + bool boolVal; + boolVal = (bool) zval_is_true(value); + returnCode = gsSetRowFieldByBool(row, column, boolVal); + break; + } + case GS_TYPE_BYTE: { + int64_t byteVal; + if (Z_TYPE_P(value) != IS_LONG) { + return false; } - case GS_TYPE_SHORT: { - int64_t shortVal; - if(Z_TYPE_P(value) != IS_LONG) { - return false; - } - shortVal = Z_LVAL_P(value); - if (shortVal < std::numeric_limits::min() || - shortVal > std::numeric_limits::max()) { - return false; - } - ret = gsSetRowFieldByShort(row, column, shortVal); - break; + byteVal = Z_LVAL_P(value); + if (byteVal < std::numeric_limits::min() || + byteVal > std::numeric_limits::max()) { + return false; } - case GS_TYPE_INTEGER: { - int64_t intVal; - if(Z_TYPE_P(value) != IS_LONG) { - return false; - } - intVal = Z_LVAL_P(value); - if (intVal < std::numeric_limits::min() || - intVal > std::numeric_limits::max()) { - return false; - } - ret = gsSetRowFieldByInteger(row, column, intVal); - break; + returnCode = gsSetRowFieldByByte(row, column, byteVal); + break; + } + case GS_TYPE_SHORT: { + int64_t shortVal; + if (Z_TYPE_P(value) != IS_LONG) { + return false; } - case GS_TYPE_FLOAT: { - float floatVal; - vbool = convertZvalValueToFloat(value, &floatVal); - if(!vbool) { - return false; - } - ret = gsSetRowFieldByFloat(row, column, floatVal); - break; + shortVal = Z_LVAL_P(value); + if (shortVal < std::numeric_limits::min() || + shortVal > std::numeric_limits::max()) { + return false; } - case GS_TYPE_DOUBLE: { - double doubleVal; - vbool = convertZvalValueToDouble(value, &doubleVal); - if(!vbool) { - return false; - } - ret = gsSetRowFieldByDouble(row, column, doubleVal); - break; + returnCode = gsSetRowFieldByShort(row, column, shortVal); + break; + } + case GS_TYPE_INTEGER: { + int64_t intVal; + if (Z_TYPE_P(value) != IS_LONG) { + return false; } - case GS_TYPE_TIMESTAMP: { - GSTimestamp timestampValue; - vbool = convertZvalValueToGSTimestamp(value, ×tampValue); - if (!vbool) { - return false; - } - ret = gsSetRowFieldByTimestamp(row, column, timestampValue); - break; + intVal = Z_LVAL_P(value); + if (intVal < std::numeric_limits::min() || + intVal > std::numeric_limits::max()) { + return false; } - case GS_TYPE_BLOB: { - GSBlob blobVal; - int64_t size; - if(Z_TYPE_P(value) != IS_STRING) { - return false; - } - blobVal.data = Z_STRVAL_P(value); - size = Z_STRLEN_P(value); - blobVal.size = size; - ret = gsSetRowFieldByBlob(row, column, (const GSBlob *)&blobVal); - break; + returnCode = gsSetRowFieldByInteger(row, column, intVal); + break; + } + case GS_TYPE_FLOAT: { + float floatVal; + isSuccess = convertZvalValueToFloat(value, &floatVal); + if (!isSuccess) { + return false; } - default: - return false; + returnCode = gsSetRowFieldByFloat(row, column, floatVal); break; } - return (ret == GS_RESULT_OK); + case GS_TYPE_DOUBLE: { + double doubleVal; + isSuccess = convertZvalValueToDouble(value, &doubleVal); + if (!isSuccess) { + return false; + } + returnCode = gsSetRowFieldByDouble(row, column, doubleVal); + break; + } + case GS_TYPE_TIMESTAMP: { + GSTimestamp timestampValue; + isSuccess = convertDateTimeObjectToGSTimestamp(value, ×tampValue); + if (!isSuccess) { + return false; + } + returnCode = gsSetRowFieldByTimestamp(row, column, timestampValue); + break; + } + case GS_TYPE_BLOB: { + // Support string type for Blob data + GSBlob blobVal; + size_t size; + if (Z_TYPE_P(value) != IS_STRING) { + return false; + } + blobVal.data = Z_STRVAL_P(value); + size = Z_STRLEN_P(value); + blobVal.size = size; + returnCode = gsSetRowFieldByBlob(row, column, (const GSBlob *)&blobVal); + break; + } + default: + return false; + break; } + return (GS_SUCCEEDED(returnCode)); +} } /** - * Support convert type from Zval value to Double. input in target language can be : - * float or integer + * Support convert type from Zval value to Double. + * Input in target language can be : float or integer */ %fragment("convertZvalValueToDouble", "header") { - static bool convertZvalValueToDouble(zval* value, double* doubleValPtr) { - if(Z_TYPE_P(value) == IS_LONG) { - // input can be integer - int64_t intVal; - intVal = Z_LVAL_P(value); - *doubleValPtr = intVal; - //When input value is integer, it should be between -9007199254740992(-2^53)/9007199254740992(2^53). - return (-9007199254740992 <= intVal && 9007199254740992 >= intVal); - } else if(Z_TYPE_P(value) == IS_DOUBLE) { - *doubleValPtr = Z_DVAL_P(value); - return (*doubleValPtr < std::numeric_limits::max() && - *doubleValPtr > -1 *std::numeric_limits::max()); - } else { - return false; - } +static bool convertZvalValueToDouble(zval* value, double* doubleValPtr) { + if (Z_TYPE_P(value) == IS_LONG) { + // Input can be integer + int64_t intVal; + intVal = Z_LVAL_P(value); + *doubleValPtr = intVal; + // When input value is integer, it should be between -9007199254740992(-2^53)/9007199254740992(2^53). + return (-9007199254740992 <= intVal && 9007199254740992 >= intVal); + } else if (Z_TYPE_P(value) == IS_DOUBLE) { + *doubleValPtr = Z_DVAL_P(value); + return (*doubleValPtr < std::numeric_limits::max() && + *doubleValPtr > -1 *std::numeric_limits::max()); + } else { + return false; } } +} /** - * Support convert type from Zval value to Float. input in target language can be : - * float or integer + * Support convert type from Zval value to Float. + * Input in target language can be : float or integer */ %fragment("convertZvalValueToFloat", "header") { - static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { - if(Z_TYPE_P(value) == IS_LONG) { - // input can be integer - int64_t intVal; - intVal = Z_LVAL_P(value); - *floatValPtr = intVal; - //When input value is integer, it should be between -16777216(-2^24)/16777216(2^24). - return (-16777216 <= intVal && 16777216 >= intVal); - } else if(Z_TYPE_P(value) == IS_DOUBLE) { - *floatValPtr = Z_DVAL_P(value); - return (*floatValPtr < std::numeric_limits::max() && - *floatValPtr > -1 *std::numeric_limits::max()); - } else { - return false; - } +static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { + if (Z_TYPE_P(value) == IS_LONG) { + // Input can be integer + int64_t intVal; + intVal = Z_LVAL_P(value); + *floatValPtr = intVal; + // When input value is integer, it should be between -16777216(-2^24)/16777216(2^24). + return (-16777216 <= intVal && 16777216 >= intVal); + } else if (Z_TYPE_P(value) == IS_DOUBLE) { + *floatValPtr = Z_DVAL_P(value); + return (*floatValPtr < std::numeric_limits::max() && + *floatValPtr > -1 *std::numeric_limits::max()); + } else { + return false; } } +} /** * Support convert type from object to GSTimestamp : input in target language can be : datetime object */ -%fragment("convertZvalValueToGSTimestamp", "header"){ - static bool convertZvalValueToGSTimestamp(zval* datetime, GSTimestamp* timestamp) { - // Support for checking DateTime class - zend_class_entry *ce = NULL; - const char* className = "DateTime"; - - // Support for checking DateTime object - const char* functionName1 = "is_a"; - zval retVal1; - zval functionNameZval1; - zval classNameZval; - - // Support for get timestamp with second - const char* functionName2 = "date_timestamp_get"; - zval retVal2; - zval functionNameZval2; - - // Support for get timestamp with microsecond - const char* functionName3 = "date_format"; - const char* formatStr = "u"; - zval retVal3; - zval functionNameZval3; - zval formatStrZval; - - // Check DateTime class exist or not - zend_string *zstrClassName = zend_string_init(className, strlen(className ), 0); - ce = zend_lookup_class(zstrClassName); - zend_string_release(zstrClassName); - if (!ce) { - return false; - } +%fragment("convertDateTimeObjectToGSTimestamp", "header"){ +static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* timestamp) { + // Check DateTime class exist or not + zend_class_entry *ce = NULL; + const char* dateTimeClassName = "DateTime"; - // Check input in target language is DateTime object - ZVAL_STRING(&functionNameZval1, functionName1); - ZVAL_STRING(&classNameZval, className); - zval params1[2] = { - *datetime, - classNameZval - }; - call_user_function(EG(function_table), NULL, - &functionNameZval1, &retVal1, - ARRAY_SIZE(params1), params1 TSRMLS_CC); - bool output = zval_is_true(&retVal1); - if (!output) { - return false; - }; - - // Convert from datetime to timestamp - // (1)Get timestamp with seconds - ZVAL_STRING(&functionNameZval2, functionName2); - zval params2[1] = {*datetime}; - call_user_function(EG(function_table), NULL, - &functionNameZval2, - &retVal2, ARRAY_SIZE(params2), - params2 TSRMLS_CC); - int64_t timestampSecond = Z_LVAL(retVal2); - - // (2)Get timestamp with microsecond - ZVAL_STRING(&functionNameZval3, functionName3); - ZVAL_STRING(&formatStrZval, formatStr); - zval params3[2] = { - *datetime, - formatStrZval - }; - call_user_function(EG(function_table), NULL, - &functionNameZval3, - &retVal3, ARRAY_SIZE(params3), - params3 TSRMLS_CC); - int64_t timestampMicroSecond = atoi(Z_STRVAL(retVal3)); - - // Convert timestamp to milisecond - *timestamp = (timestampSecond * 1000) + (timestampMicroSecond/1000); - return true; + zend_string *zstrClassName = zend_string_init(dateTimeClassName, strlen(dateTimeClassName ), 0); + ce = zend_lookup_class(zstrClassName); + zend_string_release(zstrClassName); + if (!ce) { + return false; } + + // Check input in target language is DateTime object + zval isAFunctionZval; + zval dateTimeClassNameZval; + zval isDateTimeZval; + + ZVAL_STRING(&isAFunctionZval, "is_a"); + ZVAL_STRING(&dateTimeClassNameZval, dateTimeClassName); + zval paramsForIsA[2] = { + *datetime, + dateTimeClassNameZval + }; + call_user_function(EG(function_table), NULL, + &isAFunctionZval, &isDateTimeZval, + ARRAY_SIZE(paramsForIsA), paramsForIsA TSRMLS_CC); + bool isDateTime = zval_is_true(&isDateTimeZval); + if (!isDateTime) { + return false; + }; + + // Convert from datetime to timestamp + // (1)Get timestamp with seconds + zval dateTimestampGetFunctionZval; + zval retSecondTimestamp; + + ZVAL_STRING(&dateTimestampGetFunctionZval, "date_timestamp_get"); + zval paramsForDateTimestampGet[1] = {*datetime}; + call_user_function(EG(function_table), NULL, + &dateTimestampGetFunctionZval, + &retSecondTimestamp, ARRAY_SIZE(paramsForDateTimestampGet), + paramsForDateTimestampGet TSRMLS_CC); + int64_t timestampSecond = Z_LVAL(retSecondTimestamp); + + // (2)Get timestamp with microsecond + zval dateFormatFunctionZval; + zval microSecondFormatZval; + zval retMicrosecondTimestamp; + + ZVAL_STRING(&dateFormatFunctionZval, "date_format"); + ZVAL_STRING(µSecondFormatZval, "u"); + zval paramsForDateFormat[2] = { + *datetime, + microSecondFormatZval + }; + call_user_function(EG(function_table), NULL, + &dateFormatFunctionZval, + &retMicrosecondTimestamp, ARRAY_SIZE(paramsForDateFormat), + paramsForDateFormat TSRMLS_CC); + int64_t timestampMicroSecond = atoi(Z_STRVAL(retMicrosecondTimestamp)); + + // Convert timestamp to milisecond + *timestamp = (timestampSecond * 1000) + (timestampMicroSecond/1000); + return true; +} } /** @@ -543,7 +586,7 @@ %typemap(in, fragment = "convertToFieldWithType") (GSRow *row) (HashTable *arr, HashPosition pos, zval* data) { const int SIZE = 60; - if(Z_TYPE_P(&$input) != IS_ARRAY) { + if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected an array as input"); } arr = Z_ARRVAL_P(&$input); @@ -552,20 +595,18 @@ int colNum = arg1->getColumnCount(); GSType* typeList = arg1->getGSTypeList(); - if(length != colNum) { + if (length != colNum) { SWIG_PHP_Error(E_ERROR, "Num row is different with container info"); } - if(length > 0) { - for(zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - GSType type = typeList[pos]; - if (!(convertToFieldWithType(tmpRow, pos, data, type))) { - char gsType[SIZE]; - sprintf(gsType, "Invalid value for column %d, type should be : %d", pos, type); - SWIG_PHP_Error(E_ERROR, gsType); - } + for (zend_hash_internal_pointer_reset_ex(arr, &pos); + (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; + zend_hash_move_forward_ex(arr, &pos)) { + GSType type = typeList[pos]; + if (!(convertToFieldWithType(tmpRow, pos, data, type))) { + char gsType[SIZE]; + sprintf(gsType, "Invalid value for column %d, type should be : %d", pos, type); + SWIG_PHP_Error(E_ERROR, gsType); } } } @@ -575,7 +616,7 @@ */ %fragment("convertToRowKeyFieldWithType", "header") { static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSType type) { - bool vbool; + bool isSuccess; field.type = type; if (Z_TYPE_P(value) == IS_NULL) { @@ -583,13 +624,12 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy return false; } - int checkConvert = 0; switch (type) { case (GS_TYPE_STRING): - if(Z_TYPE_P(value) != IS_STRING) { + if (Z_TYPE_P(value) != IS_STRING) { return false; } - field.value.asString = strdup(Z_STRVAL_P(value)); + griddb::Util::strdup(&field.value.asString, Z_STRVAL_P(value)); break; case (GS_TYPE_INTEGER): int64_t intVal; @@ -604,14 +644,14 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy field.value.asInteger = intVal; break; case (GS_TYPE_LONG): - if(Z_TYPE_P(value) != IS_LONG) { + if (Z_TYPE_P(value) != IS_LONG) { return false; } field.value.asLong = Z_LVAL_P(value); break; case (GS_TYPE_TIMESTAMP): - vbool = convertZvalValueToGSTimestamp(value, &field.value.asTimestamp); - if (!vbool) { + isSuccess = convertDateTimeObjectToGSTimestamp(value, &field.value.asTimestamp); + if (!isSuccess) { return false; } break; @@ -648,50 +688,62 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy /** * Support convert data from GSRow* row to zval array */ -%fragment("getRowFields", "header", fragment = "convertTimestampToObject") { +%fragment("getRowFields", "header", fragment = "convertTimestampToDateTimeObject") { static bool getRowFields(GSRow* row, int columnCount, GSType* typeList, int* columnError, GSType* fieldTypeError, zval* outList) { - GSResult ret; - bool retVal = true; + GSResult returnCode; + bool returnValue = true; for (int i = 0; i < columnCount; i++) { //Check NULL value GSBool nullValue; - ret = gsGetRowFieldNull(row, (int32_t) i, &nullValue); - if (ret != GS_RESULT_OK) { + returnCode = gsGetRowFieldNull(row, (int32_t) i, &nullValue); + if (!GS_SUCCEEDED(returnCode)) { *columnError = i; - retVal = false; + returnValue = false; *fieldTypeError = GS_TYPE_NULL; - return retVal; + return returnValue; } if (nullValue) { add_index_zval(outList, i, NULL); continue; } - switch(typeList[i]) { + switch (typeList[i]) { case GS_TYPE_LONG: { int64_t longValue; - ret = gsGetRowFieldAsLong(row, (int32_t) i, &longValue); + returnCode = gsGetRowFieldAsLong(row, (int32_t) i, &longValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_long(outList, i, longValue); break; } case GS_TYPE_STRING: { GSChar* stringValue; - ret = gsGetRowFieldAsString(row, (int32_t) i, (const GSChar **)&stringValue); + returnCode = gsGetRowFieldAsString(row, (int32_t) i, (const GSChar **)&stringValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_string(outList, i, stringValue); break; } case GS_TYPE_BLOB: { GSBlob blobValue = {0}; - ret = gsGetRowFieldAsBlob(row, (int32_t) i, &blobValue); + returnCode = gsGetRowFieldAsBlob(row, (int32_t) i, &blobValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_string(outList, i, (char*)blobValue.data); break; } case GS_TYPE_BOOL: { GSBool boolValue; bool boolVal; - ret = gsGetRowFieldAsBool(row, (int32_t) i, &boolValue); - if(boolValue == GS_TRUE){ + returnCode = gsGetRowFieldAsBool(row, (int32_t) i, &boolValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } + if (boolValue == GS_TRUE){ boolVal = true; } else { boolVal = false; @@ -701,64 +753,82 @@ static bool getRowFields(GSRow* row, int columnCount, } case GS_TYPE_INTEGER: { int32_t intValue; - ret = gsGetRowFieldAsInteger(row, (int32_t) i, &intValue); + returnCode = gsGetRowFieldAsInteger(row, (int32_t) i, &intValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_long(outList, i, intValue); break; } case GS_TYPE_FLOAT: { float floatValue; - ret = gsGetRowFieldAsFloat(row, (int32_t) i, &floatValue); + returnCode = gsGetRowFieldAsFloat(row, (int32_t) i, &floatValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_double(outList, i, floatValue); break; } case GS_TYPE_DOUBLE: { double doubleValue; - ret = gsGetRowFieldAsDouble(row, (int32_t) i, &doubleValue); + returnCode = gsGetRowFieldAsDouble(row, (int32_t) i, &doubleValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_double(outList, i, doubleValue); break; } case GS_TYPE_TIMESTAMP: { GSTimestamp timestampValue; - ret = gsGetRowFieldAsTimestamp(row, (int32_t) i, ×tampValue); zval dateTime; - convertTimestampToObject(×tampValue, &dateTime); + returnCode = gsGetRowFieldAsTimestamp(row, (int32_t) i, ×tampValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } + convertTimestampToDateTimeObject(×tampValue, &dateTime); add_index_zval(outList, i, &dateTime); break; } case GS_TYPE_BYTE: { int8_t byteValue; - ret = gsGetRowFieldAsByte(row, (int32_t) i, &byteValue); + returnCode = gsGetRowFieldAsByte(row, (int32_t) i, &byteValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_long(outList, i, byteValue); break; } case GS_TYPE_SHORT: { int16_t shortValue; - ret = gsGetRowFieldAsShort(row, (int32_t) i, &shortValue); + returnCode = gsGetRowFieldAsShort(row, (int32_t) i, &shortValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } add_index_long(outList, i, shortValue); break; } default: { // NOT OK - ret = -1; + returnCode = -1; break; } } - if (ret != GS_RESULT_OK) { + if (!GS_SUCCEEDED(returnCode)) { *columnError = i; *fieldTypeError = typeList[i]; - retVal = false; - return retVal; + returnValue = false; + return returnValue; } } - return retVal; + return returnValue; } } /** * Support convert data from timestamp to DateTime object in target language */ -%fragment("convertTimestampToObject", "header") { -static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { +%fragment("convertTimestampToDateTimeObject", "header") { +static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateTime) { const int SIZE = 60; char timeStr[SIZE]; zval functionNameZval; @@ -792,12 +862,11 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { * The argument "GSRow *rowdata" is not used in the function Container::get(), it only for the purpose of typemap matching pattern * The actual output data is store in class member and can be get by function getGSRowPtr() */ -//%typemap(argout, fragment = "getRowFields") (GSRow *rowdata) { %typemap(argout, fragment = "getRowFields") (GSRow *rowdata) { if (result == GS_FALSE) { RETVAL_NULL(); } else { - bool retVal; + bool returnValue; int errorColumn; GSType errorType; const int SIZE = 60; @@ -807,12 +876,12 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { // Get row fields array_init_size(return_value, arg1->getColumnCount()); - retVal = getRowFields(row, arg1->getColumnCount(), + returnValue = getRowFields(row, arg1->getColumnCount(), arg1->getGSTypeList(), &errorColumn, &errorType, return_value); - if (retVal == false) { + if (returnValue == false) { char errorMsg[SIZE]; sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); SWIG_PHP_Error(E_ERROR, errorMsg); @@ -840,7 +909,7 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { const int SIZE = 60; switch (*$1) { case (GS_ROW_SET_CONTAINER_ROWS): { - bool retVal; + bool returnValue; int errorColumn; if (*$2 == false) { RETURN_NULL(); @@ -848,25 +917,26 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { GSRow* row = arg1->getGSRowPtr(); array_init_size(return_value, arg1->getColumnCount()); GSType errorType; - retVal = getRowFields(row, arg1->getColumnCount(), + returnValue = getRowFields(row, arg1->getColumnCount(), arg1->getGSTypeList(), &errorColumn, &errorType, return_value); - if (retVal == false) { + if (returnValue == false) { char errorMsg[SIZE]; - sprintf(errorMsg, "Can't get data for field %d with type%d", errorColumn, errorType); + sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); SWIG_PHP_Error(E_ERROR, errorMsg); } } break; } case (GS_ROW_SET_AGGREGATION_RESULT): { - SWIG_SetPointerZval(return_value, (void *) (*$4), + SWIG_SetPointerZval(return_value, (void *) (*$4), $descriptor(griddb::AggregationResult *), SWIG_CAST_NEW_MEMORY); break; } case (GS_ROW_SET_QUERY_ANALYSIS): { // Not support now + SWIG_PHP_Error(E_ERROR, "Function is not supportted now"); break; } default: { @@ -882,8 +952,8 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { %typemap(in, numinputs = 0) (griddb::Field *agValue) (griddb::Field tmpAgValue){ $1 = &tmpAgValue; } + %typemap(argout) (griddb::Field *agValue) { - int i; switch ($1->type) { case GS_TYPE_LONG: { RETVAL_LONG($1->value.asLong); @@ -894,22 +964,117 @@ static void convertTimestampToObject(GSTimestamp* timestamp, zval* dateTime) { break; } case GS_TYPE_TIMESTAMP: - convertTimestampToObject(&($1->value.asTimestamp), return_value); + convertTimestampToDateTimeObject(&($1->value.asTimestamp), return_value); default: RETURN_NULL(); } } /* -* Typemap for TimestampUtils::get_time_millis: convert DateTime object from target language to timestamp with millisecond in C++ layer +* Typemap for TimestampUtils::get_time_millis: convert DateTime object from +* target language to timestamp with millisecond in C++ layer */ -%typemap(in, fragement = "convertZvalValueToGSTimestamp") (int64_t timestamp){ - bool vbool; +%typemap(in, fragement = "convertDateTimeObjectToGSTimestamp") (int64_t timestamp){ + bool isSuccess; GSTimestamp timestampValue; - vbool = convertZvalValueToGSTimestamp(&$input, ×tampValue); - if(!vbool){ + isSuccess = convertDateTimeObjectToGSTimestamp(&$input, ×tampValue); + if (!isSuccess){ SWIG_PHP_Error(E_ERROR, "Expected a DateTime object as input"); } $1 = timestampValue; } +/* +* Typemap for set attribute ContainerInfo::column_info_list +*/ +%typemap(in, numinputs = 1) (ColumnInfoList*) + (HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, + HashTable *arrColumnInfo, HashPosition posColumnInfo, zval *dataColumnInfo, + zval *columnName, zval *columnType){ + ColumnInfoList infolist; + int i = 0; + GSColumnInfo* containerInfo; + $1 = &infolist; + + if (Z_TYPE_P(&$input) != IS_ARRAY){ + SWIG_PHP_Error(E_ERROR, "Expected an array as input"); + } + + arrColumnInfoArray = Z_ARRVAL_P(&$input); + int length = (int) zend_hash_num_elements(arrColumnInfoArray); + + if (length > 0) { + containerInfo = (GSColumnInfo *) malloc(length*sizeof(GSColumnInfo)); + if (containerInfo == NULL) { + SWIG_PHP_Error(E_ERROR, "Memmory allocation error"); + } + memset(containerInfo, 0x0, length*sizeof(GSColumnInfo)); + + // Set value for property of columnInfoList + $1->columnInfo = containerInfo; + $1->size = length; + + for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); + (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; + zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { + // Input valid is array only + if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array property as ColumnInfo element"); + } + + arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); + int sizeColumn = (int) zend_hash_num_elements(arrColumnInfo); + if (sizeColumn != 2) { + SWIG_PHP_Error(E_ERROR, "Expected two elements for ColumnInfo property"); + } + // Get column name + zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as column name"); + } + containerInfo[i].name = Z_STRVAL_P(columnName); + + // Get column type + zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); + } + containerInfo[i].type = Z_LVAL_P(columnType); + i++; + } + } +} + +/** + * Cleanup argument data for set attribute ContainerInfo::column_info_list + */ +%typemap(freearg) (ColumnInfoList*) { + size_t size = $1->size; + if ($1->columnInfo) { + free($1->columnInfo); + } +} + +/* +* Typemap for get attribute ContainerInfo::column_info_list +*/ +%typemap(out) (ColumnInfoList*) { + // Define size of column + const int SIZE_COLUMN = 2; + // Define an array contains name and type of each column + zval columnInfoArray; + + // Get ColumnInfoList object + ColumnInfoList data = *$1; + // Get size of columnInfo property + size_t size = data.size; + + array_init_size(return_value, size); + for (int i = 0; i < size; i++) { + array_init_size(&columnInfoArray, SIZE_COLUMN); + add_next_index_string(&columnInfoArray, (data.columnInfo)[i].name); + add_next_index_long(&columnInfoArray, (data.columnInfo)[i].type); + add_next_index_zval(return_value, &columnInfoArray); + } +} + From cedb4f227892fb3adf6d1102044bfb7ad993dbbf Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:46:06 +0900 Subject: [PATCH 10/22] implement partitionController --- src/gstype_php.i | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gstype_php.i b/src/gstype_php.i index e0e711e..91d9af1 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -35,7 +35,7 @@ //Read only attribute Container::type %attribute(griddb::Container, int, type, get_type); -//Read only attribute GSException::is_timeout +//Read only attribute GSException::isTimeout %attribute(griddb::GSException, bool, isTimeout, is_timeout); //Read only attribute RowSet::size %attribute(griddb::RowSet, int32_t, size, size); @@ -57,6 +57,10 @@ %attribute(griddb::ExpirationInfo, GSTimeUnit, unit, get_time_unit, set_time_unit); //Read only attribute ExpirationInfo::divisionCount %attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); +//Read only attribute Store::partitionController +%attribute(griddb::Store, griddb::PartitionController*, partitionController, partition_info); +//Read only attribute PartitionController::partitionCount +%attribute(griddb::PartitionController, int, partitionCount, get_partition_count); /* * Ignore unnecessary functions @@ -1049,9 +1053,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT * Cleanup argument data for set attribute ContainerInfo::column_info_list */ %typemap(freearg) (ColumnInfoList*) { - size_t size = $1->size; if ($1->columnInfo) { - free($1->columnInfo); + free((void*) $1->columnInfo); } } @@ -1078,3 +1081,20 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT } } +/** +* Typemaps output for PartitionController::get_container_names +*/ +%typemap(in, numinputs = 0) (const GSChar *const ** stringList, size_t *size) (GSChar **nameList, size_t size) { + $1 = &nameList; + $2 = &size; +} + +%typemap(argout, numinputs = 0) (const GSChar * const ** stringList, size_t *size) { + GSChar** nameList = *$1; + size_t size = *$2; + + array_init_size(return_value, size); + for (int i = 0; i < size; i++){ + add_next_index_string(return_value, nameList[i]); + } +} From 3ef59d1ef06eec399024d939e2c776ce03778492 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:46:53 +0900 Subject: [PATCH 11/22] update gstype_php.i after checking static code using cpplint --- src/gstype_php.i | 642 ++++++++++++++++++++++++++--------------------- 1 file changed, 356 insertions(+), 286 deletions(-) diff --git a/src/gstype_php.i b/src/gstype_php.i index 91d9af1..5202e66 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -14,18 +14,20 @@ limitations under the License. */ -#define ARRAY_SIZE(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) +#define ARRAY_SIZE(x) \ + ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) %{ #include "zend_interfaces.h" %} /* * Change method names in PHP */ -//Rename all method to camel cases +// Rename all method to camel cases %rename("%(lowercamelcase)s", %$isfunction) ""; -//"getMessage" is a default final method of Exception class in PHP. So convert name into getErrorMessage +// "getMessage" is a default final method of Exception class in PHP. +// So convert name into getErrorMessage %rename(getErrorMessage) griddb::GSException::get_message; -//"default" is a PHP keyword. So convert name into DEFAULT_TYPE +// "default" is a PHP keyword. So convert name into DEFAULT_TYPE %rename(DEFAULT_TYPE) griddb::IndexType::DEFAULT; /* @@ -33,34 +35,41 @@ */ %include -//Read only attribute Container::type +// Read only attribute Container::type %attribute(griddb::Container, int, type, get_type); -//Read only attribute GSException::isTimeout +// Read only attribute GSException::isTimeout %attribute(griddb::GSException, bool, isTimeout, is_timeout); -//Read only attribute RowSet::size +// Read only attribute RowSet::size %attribute(griddb::RowSet, int32_t, size, size); -//Read only attribute RowSet::type +// Read only attribute RowSet::type %attribute(griddb::RowSet, GSRowSetType, type, type); -//Read only attribute ContainerInfo::name +// Read only attribute ContainerInfo::name %attribute(griddb::ContainerInfo, GSChar*, name, get_name, set_name); -//Read only attribute ContainerInfo::type +// Read only attribute ContainerInfo::type %attribute(griddb::ContainerInfo, GSContainerType, type, get_type, set_type); -//Read only attribute ContainerInfo::rowKey -%attribute(griddb::ContainerInfo, bool, rowKey, get_row_key_assigned, set_row_key_assigned); -//Read only attribute ContainerInfo::columnInfoArray -%attributeval(griddb::ContainerInfo, ColumnInfoList, columnInfoArray, get_column_info_list, set_column_info_list); -//Read only attribute ContainerInfo::expiration -%attribute(griddb::ContainerInfo, griddb::ExpirationInfo*, expiration, get_expiration_info, set_expiration_info); -//Read only attribute ExpirationInfo::time +// Read only attribute ContainerInfo::rowKey +%attribute(griddb::ContainerInfo, bool, rowKey, + get_row_key_assigned, set_row_key_assigned); +// Read only attribute ContainerInfo::columnInfoArray +%attributeval(griddb::ContainerInfo, ColumnInfoList, columnInfoArray, + get_column_info_list, set_column_info_list); +// Read only attribute ContainerInfo::expiration +%attribute(griddb::ContainerInfo, griddb::ExpirationInfo*, expiration, + get_expiration_info, set_expiration_info); +// Read only attribute ExpirationInfo::time %attribute(griddb::ExpirationInfo, int, time, get_time, set_time); -//Read only attribute ExpirationInfo::unit -%attribute(griddb::ExpirationInfo, GSTimeUnit, unit, get_time_unit, set_time_unit); -//Read only attribute ExpirationInfo::divisionCount -%attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); -//Read only attribute Store::partitionController -%attribute(griddb::Store, griddb::PartitionController*, partitionController, partition_info); -//Read only attribute PartitionController::partitionCount -%attribute(griddb::PartitionController, int, partitionCount, get_partition_count); +// Read only attribute ExpirationInfo::unit +%attribute(griddb::ExpirationInfo, GSTimeUnit, unit, + get_time_unit, set_time_unit); +// Read only attribute ExpirationInfo::divisionCount +%attribute(griddb::ExpirationInfo, int, divisionCount, + get_division_count, set_division_count); +// Read only attribute Store::partitionController +%attribute(griddb::Store, griddb::PartitionController*, + partitionController, partition_info); +// Read only attribute PartitionController::partitionCount +%attribute(griddb::PartitionController, int, partitionCount, + get_partition_count); /* * Ignore unnecessary functions @@ -79,12 +88,14 @@ static void throwGSException(griddb::GSException* exception) { // Create a resource zval resource; - SWIG_SetPointerZval(&resource, (void *)exception, $descriptor(griddb::GSException *), 1); + SWIG_SetPointerZval(&resource, reinterpret_cast(exception), + $descriptor(griddb::GSException *), 1); zval ex; zval ctorRv; // Create a PHP GSException object - zend_string * objTypenameZend = zend_string_init(objTypename, objTypenameLen, 0); + zend_string * objTypenameZend = zend_string_init(objTypename, + objTypenameLen, 0); zend_class_entry* ce = zend_lookup_class(objTypenameZend); zend_string_release(objTypenameZend); if (!ce) { @@ -95,7 +106,8 @@ static void throwGSException(griddb::GSException* exception) { // Constructor, pass resource to constructor argument zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); - zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); + zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, + 1, &resource, NULL TSRMLS_CC); if (Z_TYPE(ctorRv) != IS_UNDEF) { zval_ptr_dtor(&ctorRv); } @@ -105,7 +117,7 @@ static void throwGSException(griddb::GSException* exception) { } } -%typemap(throws, fragment="throwGSException") griddb::GSException %{ +%typemap(throws, fragment = "throwGSException") griddb::GSException %{ griddb::GSException* tmpException = new griddb::GSException(&$1); throwGSException(tmpException); return; @@ -121,15 +133,14 @@ static void throwGSException(griddb::GSException* exception) { const char* username, const char* password, const char* notification_member, const char* notification_provider) (HashTable *arr, HashPosition pos, zval *data) { - if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); } arr = Z_ARRVAL_P(&$input); - int length = (int) zend_hash_num_elements(arr); + int length = zend_hash_num_elements(arr); char* name = 0; - //Create $1, $2, $3, $3, $4, $5, $6, $7, $8 with default value + // Create $1, $2, $3, $3, $4, $5, $6, $7, $8 with default value $1 = NULL; $2 = 0; $3 = NULL; @@ -138,85 +149,91 @@ static void throwGSException(griddb::GSException* exception) { $6 = NULL; $7 = NULL; $8 = NULL; - if (length > 0) { - zend_string *key; - int key_len; - long index; - for (zend_hash_internal_pointer_reset_ex(arr, &pos); - (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; - zend_hash_move_forward_ex(arr, &pos)) { - if (zend_hash_get_current_key_ex(arr, &key, (zend_ulong*)&index, &pos) == HASH_KEY_IS_STRING) { - name = ZSTR_VAL(key); - if (strcmp(name, "host") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for host property"); - } - $1 = Z_STRVAL_P(data); - } - else if (strcmp(name, "port") == 0) { - //Input valid is number only - if (Z_TYPE_P(data) != IS_LONG){ - SWIG_PHP_Error(E_ERROR, "Expected integer as input for port number property"); - } - $2 = Z_LVAL_P(data); - } - else if (strcmp(name, "clusterName") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for clusterName property"); - } - $3 = Z_STRVAL_P(data); - } - else if (strcmp(name, "database") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for database property"); - } - $4 = Z_STRVAL_P(data); - } - else if (strcmp(name, "username") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for username property"); - } - $5 = Z_STRVAL_P(data); - } - else if (strcmp(name, "password") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for password property"); - } - $6 = Z_STRVAL_P(data); - } - else if (strcmp(name, "notificationMember") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for notificationMember property"); - } - $7 = Z_STRVAL_P(data); - } - else if (strcmp(name, "notificationProvider") == 0) { - if (Z_TYPE_P(data) != IS_STRING){ - SWIG_PHP_Error(E_ERROR, "Expected string as input for host notificationProvider property"); - } - $8 = Z_STRVAL_P(data); - } else { - SWIG_PHP_Error(E_ERROR, "Invalid Property"); - }; - } else { - SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); + + if (length == 0) { + SWIG_PHP_Error(E_ERROR, "Expect not empty array as input"); + } + + zend_string *key; + int key_len; + ulong index; + for (zend_hash_internal_pointer_reset_ex(arr, &pos); + (data = zend_hash_get_current_data_ex(arr, &pos)) != NULL; + zend_hash_move_forward_ex(arr, &pos)) { + if (zend_hash_get_current_key_ex(arr, &key, &index, + &pos) != HASH_KEY_IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); + } + + name = ZSTR_VAL(key); + if (strcmp(name, "host") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for host property"); + } + $1 = Z_STRVAL_P(data); + } else if (strcmp(name, "port") == 0) { + // Input valid is number only + if (Z_TYPE_P(data) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected integer as" + " input for port number property"); + } + $2 = Z_LVAL_P(data); + } else if (strcmp(name, "clusterName") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for clusterName property"); + } + $3 = Z_STRVAL_P(data); + } else if (strcmp(name, "database") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for database property"); + } + $4 = Z_STRVAL_P(data); + } else if (strcmp(name, "username") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for username property"); + } + $5 = Z_STRVAL_P(data); + } else if (strcmp(name, "password") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for password property"); + } + $6 = Z_STRVAL_P(data); + } else if (strcmp(name, "notificationMember") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for notificationMember property"); + } + $7 = Z_STRVAL_P(data); + } else if (strcmp(name, "notificationProvider") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as" + " input for host notificationProvider property"); } + $8 = Z_STRVAL_P(data); + } else { + SWIG_PHP_Error(E_ERROR, "Invalid Property"); } } } /** * Typemaps for ContainerInfo : support keyword parameter ("name" : str, - * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, "expiration" : expiraion object) + * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, + * "expiration" : expiraion object) */ %typemap(in, numinputs = 1) (const GSChar* name, const GSColumnInfo* props, int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) - (HashTable *arrContainerInfo, HashPosition posContainerInfo, zval *dataContainerInfo, - HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, - HashTable *arrColumnInfo, HashPosition posColumnInfo, - zval *columnName, zval *columnType) { - + (HashTable *arrContainerInfo, HashPosition posContainerInfo, + zval *dataContainerInfo, HashTable *arrColumnInfoArray, + HashPosition posColumnInfoArray, zval *dataColumnInfoArray, + HashTable *arrColumnInfo, HashPosition posColumnInfo, + zval *columnName, zval *columnType) { if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); } @@ -227,101 +244,116 @@ static void throwGSException(griddb::GSException* exception) { $2 = NULL; $3 = 0; $4 = GS_CONTAINER_COLLECTION; - $5 = true;//default value rowKey = true + $5 = true; // default value rowKey = true $6 = NULL; griddb::ExpirationInfo* expiration; // Fetch the hash table from a zval input arrContainerInfo = Z_ARRVAL_P(&$input); - int sizeOfContainerInfo = (int) zend_hash_num_elements(arrContainerInfo); - - if (sizeOfContainerInfo > 0) { - zend_string *key; - int key_len; - long index; - for (zend_hash_internal_pointer_reset_ex(arrContainerInfo, &posContainerInfo); - (dataContainerInfo = zend_hash_get_current_data_ex(arrContainerInfo, &posContainerInfo)) != NULL; - zend_hash_move_forward_ex(arrContainerInfo, &posContainerInfo)) { - if (zend_hash_get_current_key_ex(arrContainerInfo, &key, (zend_ulong*)&index, &posContainerInfo) == HASH_KEY_IS_STRING) { - name = ZSTR_VAL(key); - if (strcmp(name, "name") == 0) { - if (Z_TYPE_P(dataContainerInfo) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as input for name property"); - } - $1 = Z_STRVAL_P(dataContainerInfo); + int sizeOfContainerInfo = zend_hash_num_elements(arrContainerInfo); + + if (sizeOfContainerInfo == 0) { + SWIG_PHP_Error(E_ERROR, "Expect not empty array as input" + " for ContainerInfo"); + } + + zend_string *key; + int key_len; + ulong index; + for (zend_hash_internal_pointer_reset_ex(arrContainerInfo, &posContainerInfo); + (dataContainerInfo = zend_hash_get_current_data_ex(arrContainerInfo, &posContainerInfo)) != NULL; + zend_hash_move_forward_ex(arrContainerInfo, &posContainerInfo)) { + if (zend_hash_get_current_key_ex(arrContainerInfo, &key, &index, &posContainerInfo) != HASH_KEY_IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); + } + + name = ZSTR_VAL(key); + if (strcmp(name, "name") == 0) { + if (Z_TYPE_P(dataContainerInfo) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as input" + " for name property"); + } + $1 = Z_STRVAL_P(dataContainerInfo); + } else if (strcmp(name, "columnInfoArray") == 0) { + // Input valid is array only + if (Z_TYPE_P(dataContainerInfo) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array as input" + " for columnInfo property"); + } + // Fetch the hash table from a zval + arrColumnInfoArray = Z_ARRVAL_P(dataContainerInfo); + int sizeOfColumnInfoArray = zend_hash_num_elements(arrColumnInfoArray); + $3 = sizeOfColumnInfoArray; + if ($3 == 0) { + SWIG_PHP_Error(E_ERROR, "Expect not empty array"); + } + $2 = new GSColumnInfo[$3]; + if ($2 == NULL) { + SWIG_PHP_Error(E_ERROR, "Memory allocation error"); + } + memset($2, 0x0, $3*sizeof(GSColumnInfo)); + + // Get name and type of column + int i = 0; + for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); + (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; + zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { + if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array property as" + " ColumnInfo element"); } - else if (strcmp(name, "columnInfoArray") == 0) { - // Input valid is array only - if (Z_TYPE_P(dataContainerInfo) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array as input for columnInfo property"); - } - // Fetch the hash table from a zval - arrColumnInfoArray = Z_ARRVAL_P(dataContainerInfo); - int sizeOfColumnInfoArray = (int) zend_hash_num_elements(arrColumnInfoArray); - $3 = sizeOfColumnInfoArray; - if ($3 > 0) { - $2 = (GSColumnInfo *) malloc($3*sizeof(GSColumnInfo)); - if ($2 == NULL) { - SWIG_PHP_Error(E_ERROR, "Memory allocation error"); - } - memset($2, 0x0, $3*sizeof(GSColumnInfo)); - - // Get name and type of column - int i = 0; - for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); - (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; - zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { - if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array property as ColumnInfo element"); - } - // Fetch the hash table from a zval - arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); - int sizeOfColumnInfo = (int) zend_hash_num_elements(arrColumnInfo); - if (sizeOfColumnInfo != 2) { - SWIG_PHP_Error(E_ERROR, "Expected two elements for columnInfo property"); - } - - // Get column name - zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); - if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as column name"); - } - - $2[i].name = Z_STRVAL_P(columnName); - - // Get column type - zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); - if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); - } - $2[i].type = Z_LVAL_P(columnType); - i++; - } - } + // Fetch the hash table from a zval + arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); + int sizeOfColumnInfo = zend_hash_num_elements(arrColumnInfo); + if (sizeOfColumnInfo != 2) { + SWIG_PHP_Error(E_ERROR, "Expected two elements for" + " columnInfo property"); } - else if (strcmp(name, "type") == 0) { - if (Z_TYPE_P(dataContainerInfo) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected integer as input for type property"); - } - $4 = Z_LVAL_P(dataContainerInfo); + + // Get column name + zend_hash_internal_pointer_reset_ex(arrColumnInfo, + &posColumnInfo); + if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex( + arrColumnInfo, &posColumnInfo)) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as column name"); } - else if (strcmp(name, "rowKey") == 0) { - if (Z_TYPE_P(dataContainerInfo) == IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected boolean as input for rowKey property"); - } - $5 = (bool) zval_is_true(dataContainerInfo); + + $2[i].name = Z_STRVAL_P(columnName); + + // Get column type + zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex( + arrColumnInfo, &posColumnInfo)) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected an integer as" + " column type"); } - else if (strcmp(name, "expiration") == 0) { - int res = SWIG_ConvertPtr(dataContainerInfo, (void**)&expiration, - $descriptor(griddb::ExpirationInfo*), 0 | 0 ); - if (!SWIG_IsOK(res)) { - SWIG_PHP_Error(E_ERROR, "Expected expiration object as input for expiration property"); - } - $6 = (griddb::ExpirationInfo *) expiration; - } else { - SWIG_PHP_Error(E_ERROR, "Invalid Property"); - }; + $2[i].type = Z_LVAL_P(columnType); + i++; + } + } else if (strcmp(name, "type") == 0) { + if (Z_TYPE_P(dataContainerInfo) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected integer as input" + " for type property"); } + $4 = Z_LVAL_P(dataContainerInfo); + } else if (strcmp(name, "rowKey") == 0) { + if (Z_TYPE_P(dataContainerInfo) == IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected boolean as input" + " for rowKey property"); + } + $5 = static_cast (zval_is_true(dataContainerInfo)); + } else if (strcmp(name, "expiration") == 0) { + int res = SWIG_ConvertPtr(dataContainerInfo, + reinterpret_cast(&expiration), + $descriptor(griddb::ExpirationInfo*), + 0 | 0); + if (!SWIG_IsOK(res)) { + SWIG_PHP_Error(E_ERROR, "Expected expiration object" + " as input for expiration property"); + } + $6 = (griddb::ExpirationInfo *) expiration; + } else { + SWIG_PHP_Error(E_ERROR, "Invalid Property"); } } } @@ -333,7 +365,7 @@ static void throwGSException(griddb::GSException* exception) { int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) { if ($2) { - free((void *) $2); + delete[] $2; } } @@ -341,7 +373,8 @@ static void throwGSException(griddb::GSException* exception) { fragment = "convertZvalValueToFloat", fragment = "convertZvalValueToDouble", fragment = "convertDateTimeObjectToGSTimestamp") { -static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { +static bool convertToFieldWithType(GSRow *row, int column, + zval* value, GSType type) { GSResult returnCode; bool isSuccess; @@ -374,7 +407,7 @@ static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType t return false; } bool boolVal; - boolVal = (bool) zval_is_true(value); + boolVal = static_cast (zval_is_true(value)); returnCode = gsSetRowFieldByBool(row, column, boolVal); break; } @@ -437,7 +470,8 @@ static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType t } case GS_TYPE_TIMESTAMP: { GSTimestamp timestampValue; - isSuccess = convertDateTimeObjectToGSTimestamp(value, ×tampValue); + isSuccess = convertDateTimeObjectToGSTimestamp(value, + ×tampValue); if (!isSuccess) { return false; } @@ -454,7 +488,8 @@ static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType t blobVal.data = Z_STRVAL_P(value); size = Z_STRLEN_P(value); blobVal.size = size; - returnCode = gsSetRowFieldByBlob(row, column, (const GSBlob *)&blobVal); + returnCode = gsSetRowFieldByBlob(row, column, + (const GSBlob *)&blobVal); break; } default: @@ -476,7 +511,8 @@ static bool convertZvalValueToDouble(zval* value, double* doubleValPtr) { int64_t intVal; intVal = Z_LVAL_P(value); *doubleValPtr = intVal; - // When input value is integer, it should be between -9007199254740992(-2^53)/9007199254740992(2^53). + // When input value is integer, it should be between + // -9007199254740992(-2^53)/9007199254740992(2^53). return (-9007199254740992 <= intVal && 9007199254740992 >= intVal); } else if (Z_TYPE_P(value) == IS_DOUBLE) { *doubleValPtr = Z_DVAL_P(value); @@ -499,7 +535,8 @@ static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { int64_t intVal; intVal = Z_LVAL_P(value); *floatValPtr = intVal; - // When input value is integer, it should be between -16777216(-2^24)/16777216(2^24). + // When input value is integer, it should be between + // -16777216(-2^24)/16777216(2^24). return (-16777216 <= intVal && 16777216 >= intVal); } else if (Z_TYPE_P(value) == IS_DOUBLE) { *floatValPtr = Z_DVAL_P(value); @@ -512,15 +549,18 @@ static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { } /** - * Support convert type from object to GSTimestamp : input in target language can be : datetime object + * Support convert type from object to GSTimestamp : + * Input in target language can be : datetime object */ -%fragment("convertDateTimeObjectToGSTimestamp", "header"){ -static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* timestamp) { +%fragment("convertDateTimeObjectToGSTimestamp", "header") { +static bool convertDateTimeObjectToGSTimestamp(zval* datetime, + GSTimestamp* timestamp) { // Check DateTime class exist or not zend_class_entry *ce = NULL; const char* dateTimeClassName = "DateTime"; - zend_string *zstrClassName = zend_string_init(dateTimeClassName, strlen(dateTimeClassName ), 0); + zend_string *zstrClassName = zend_string_init(dateTimeClassName, + strlen(dateTimeClassName), 0); ce = zend_lookup_class(zstrClassName); zend_string_release(zstrClassName); if (!ce) { @@ -544,7 +584,7 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* time bool isDateTime = zval_is_true(&isDateTimeZval); if (!isDateTime) { return false; - }; + } // Convert from datetime to timestamp // (1)Get timestamp with seconds @@ -584,8 +624,10 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* time /** * Typemaps for RowSet::update() and Container::put() function -* The argument "GSRow *row" is not used in the function body, it only for the purpose of typemap matching pattern -* The actual input data is store in class member and can be get by function getGSRowPtr() +* The argument "GSRow *row" is not used in the function body, +* It only for the purpose of typemap matching pattern +* The actual input data is store in class member and can be get +* by function getGSRowPtr() */ %typemap(in, fragment = "convertToFieldWithType") (GSRow *row) (HashTable *arr, HashPosition pos, zval* data) { @@ -594,7 +636,7 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* time SWIG_PHP_Error(E_ERROR, "Expected an array as input"); } arr = Z_ARRVAL_P(&$input); - int length = (int) zend_hash_num_elements(arr); + int length = zend_hash_num_elements(arr); GSRow *tmpRow = arg1->getGSRowPtr(); int colNum = arg1->getColumnCount(); GSType* typeList = arg1->getGSTypeList(); @@ -609,22 +651,25 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSTimestamp* time GSType type = typeList[pos]; if (!(convertToFieldWithType(tmpRow, pos, data, type))) { char gsType[SIZE]; - sprintf(gsType, "Invalid value for column %d, type should be : %d", pos, type); + snprintf(gsType, SIZE, "Invalid value for column %d," + " type should be : %d", pos, type); SWIG_PHP_Error(E_ERROR, gsType); } } } /** - * Support convert row key Field from zval* in target language to C Object with specific type + * Support convert row key Field from zval* in target language to + * C Object with specific type */ %fragment("convertToRowKeyFieldWithType", "header") { -static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSType type) { +static bool convertToRowKeyFieldWithType(griddb::Field &field, + zval* value, GSType type) { bool isSuccess; field.type = type; if (Z_TYPE_P(value) == IS_NULL) { - //Not support NULL + // Not support NULL return false; } @@ -654,13 +699,14 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy field.value.asLong = Z_LVAL_P(value); break; case (GS_TYPE_TIMESTAMP): - isSuccess = convertDateTimeObjectToGSTimestamp(value, &field.value.asTimestamp); + isSuccess = convertDateTimeObjectToGSTimestamp( + value, &field.value.asTimestamp); if (!isSuccess) { return false; } break; default: - //Not support for now + // Not support for now return false; break; } @@ -692,14 +738,15 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, zval* value, GSTy /** * Support convert data from GSRow* row to zval array */ -%fragment("getRowFields", "header", fragment = "convertTimestampToDateTimeObject") { +%fragment("getRowFields", "header", + fragment = "convertTimestampToDateTimeObject") { static bool getRowFields(GSRow* row, int columnCount, GSType* typeList, int* columnError, GSType* fieldTypeError, zval* outList) { GSResult returnCode; bool returnValue = true; for (int i = 0; i < columnCount; i++) { - //Check NULL value + // Check NULL value GSBool nullValue; returnCode = gsGetRowFieldNull(row, (int32_t) i, &nullValue); if (!GS_SUCCEEDED(returnCode)) { @@ -724,7 +771,8 @@ static bool getRowFields(GSRow* row, int columnCount, } case GS_TYPE_STRING: { GSChar* stringValue; - returnCode = gsGetRowFieldAsString(row, (int32_t) i, (const GSChar **)&stringValue); + returnCode = gsGetRowFieldAsString(row, (int32_t) i, + (const GSChar **)&stringValue); if (!GS_SUCCEEDED(returnCode)) { break; } @@ -737,7 +785,8 @@ static bool getRowFields(GSRow* row, int columnCount, if (!GS_SUCCEEDED(returnCode)) { break; } - add_index_string(outList, i, (char*)blobValue.data); + add_index_string(outList, i, + reinterpret_cast(blobValue.data)); break; } case GS_TYPE_BOOL: { @@ -747,7 +796,7 @@ static bool getRowFields(GSRow* row, int columnCount, if (!GS_SUCCEEDED(returnCode)) { break; } - if (boolValue == GS_TRUE){ + if (boolValue == GS_TRUE) { boolVal = true; } else { boolVal = false; @@ -785,7 +834,8 @@ static bool getRowFields(GSRow* row, int columnCount, case GS_TYPE_TIMESTAMP: { GSTimestamp timestampValue; zval dateTime; - returnCode = gsGetRowFieldAsTimestamp(row, (int32_t) i, ×tampValue); + returnCode = gsGetRowFieldAsTimestamp(row, + (int32_t) i, ×tampValue); if (!GS_SUCCEEDED(returnCode)) { break; } @@ -832,7 +882,8 @@ static bool getRowFields(GSRow* row, int columnCount, * Support convert data from timestamp to DateTime object in target language */ %fragment("convertTimestampToDateTimeObject", "header") { -static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateTime) { +static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, + zval* dateTime) { const int SIZE = 60; char timeStr[SIZE]; zval functionNameZval; @@ -846,7 +897,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT // Get time with microSeconds int64_t microSecond = (*timestamp % 1000) * 1000; - sprintf(timeStr, "%ld.%06d", second, microSecond); + snprintf(timeStr, SIZE, "%ld.%06d", second, microSecond); ZVAL_STRING(&functionNameZval, functionName); ZVAL_STRING(&formatStringZval, formatString); @@ -863,7 +914,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT /* * This typemap argument out does not get data from argument "GSRow *rowdata" -* The argument "GSRow *rowdata" is not used in the function Container::get(), it only for the purpose of typemap matching pattern +* The argument "GSRow *rowdata" is not used in the function Container::get(), +* it only for the purpose of typemap matching pattern * The actual output data is store in class member and can be get by function getGSRowPtr() */ %typemap(argout, fragment = "getRowFields") (GSRow *rowdata) { @@ -887,7 +939,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT if (returnValue == false) { char errorMsg[SIZE]; - sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); + snprintf(errorMsg, SIZE, "Can't get data for field %d with type %d", + errorColumn, errorType); SWIG_PHP_Error(E_ERROR, errorMsg); } } @@ -897,9 +950,11 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT * Type map for Rowset::next() */ %typemap(in, numinputs = 0) (GSRowSetType* type, bool* hasNextRow, - griddb::QueryAnalysisEntry** queryAnalysis, griddb::AggregationResult** aggResult) + griddb::QueryAnalysisEntry** queryAnalysis, + griddb::AggregationResult** aggResult) (GSRowSetType typeTmp, bool hasNextRowTmp, - griddb::QueryAnalysisEntry* queryAnalysisTmp = NULL, griddb::AggregationResult* aggResultTmp = NULL) { + griddb::QueryAnalysisEntry* queryAnalysisTmp = NULL, + griddb::AggregationResult* aggResultTmp = NULL) { $1 = &typeTmp; hasNextRowTmp = true; $2 = &hasNextRowTmp; @@ -907,34 +962,37 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT $4 = &aggResultTmp; } -%typemap(argout, fragment = "getRowFields") (GSRowSetType* type, bool* hasNextRow, - griddb::QueryAnalysisEntry** queryAnalysis, griddb::AggregationResult** aggResult) { - +%typemap(argout, fragment = "getRowFields") (GSRowSetType* type, + bool* hasNextRow, griddb::QueryAnalysisEntry** queryAnalysis, + griddb::AggregationResult** aggResult) { const int SIZE = 60; + if (*$2 == false) { + RETURN_NULL(); + } switch (*$1) { case (GS_ROW_SET_CONTAINER_ROWS): { bool returnValue; int errorColumn; - if (*$2 == false) { - RETURN_NULL(); - } else { - GSRow* row = arg1->getGSRowPtr(); - array_init_size(return_value, arg1->getColumnCount()); - GSType errorType; - returnValue = getRowFields(row, arg1->getColumnCount(), - arg1->getGSTypeList(), - &errorColumn, &errorType, return_value); - if (returnValue == false) { - char errorMsg[SIZE]; - sprintf(errorMsg, "Can't get data for field %d with type %d", errorColumn, errorType); - SWIG_PHP_Error(E_ERROR, errorMsg); + + GSRow* row = arg1->getGSRowPtr(); + array_init_size(return_value, arg1->getColumnCount()); + GSType errorType; + returnValue = getRowFields(row, arg1->getColumnCount(), + arg1->getGSTypeList(), + &errorColumn, &errorType, return_value); + + if (returnValue == false) { + char errorMsg[SIZE]; + snprintf(errorMsg, SIZE, "Can't get data for field" + " %d with type %d", errorColumn, errorType); + SWIG_PHP_Error(E_ERROR, errorMsg); } - } break; } case (GS_ROW_SET_AGGREGATION_RESULT): { - SWIG_SetPointerZval(return_value, (void *) (*$4), - $descriptor(griddb::AggregationResult *), SWIG_CAST_NEW_MEMORY); + SWIG_SetPointerZval(return_value, reinterpret_cast (*$4), + $descriptor(griddb::AggregationResult *), + SWIG_CAST_NEW_MEMORY); break; } @@ -944,7 +1002,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT break; } default: { - SWIG_PHP_Error(E_ERROR, "Invalid type"); + SWIG_PHP_Error(E_ERROR, "Invalid Rowset type"); break; } } @@ -953,7 +1011,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT /* * Typemap for get function in AggregationResult class */ -%typemap(in, numinputs = 0) (griddb::Field *agValue) (griddb::Field tmpAgValue){ +%typemap(in, numinputs = 0) (griddb::Field *agValue) + (griddb::Field tmpAgValue) { $1 = &tmpAgValue; } @@ -968,7 +1027,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT break; } case GS_TYPE_TIMESTAMP: - convertTimestampToDateTimeObject(&($1->value.asTimestamp), return_value); + convertTimestampToDateTimeObject(&($1->value.asTimestamp), + return_value); default: RETURN_NULL(); } @@ -978,11 +1038,12 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT * Typemap for TimestampUtils::get_time_millis: convert DateTime object from * target language to timestamp with millisecond in C++ layer */ -%typemap(in, fragement = "convertDateTimeObjectToGSTimestamp") (int64_t timestamp){ +%typemap(in, fragement = "convertDateTimeObjectToGSTimestamp") + (int64_t timestamp) { bool isSuccess; GSTimestamp timestampValue; isSuccess = convertDateTimeObjectToGSTimestamp(&$input, ×tampValue); - if (!isSuccess){ + if (!isSuccess) { SWIG_PHP_Error(E_ERROR, "Expected a DateTime object as input"); } $1 = timestampValue; @@ -992,60 +1053,67 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT * Typemap for set attribute ContainerInfo::column_info_list */ %typemap(in, numinputs = 1) (ColumnInfoList*) - (HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, - HashTable *arrColumnInfo, HashPosition posColumnInfo, zval *dataColumnInfo, - zval *columnName, zval *columnType){ + (HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, + zval *dataColumnInfoArray, HashTable *arrColumnInfo, + HashPosition posColumnInfo, zval *dataColumnInfo, + zval *columnName, zval *columnType) { ColumnInfoList infolist; int i = 0; GSColumnInfo* containerInfo; $1 = &infolist; - if (Z_TYPE_P(&$input) != IS_ARRAY){ + if (Z_TYPE_P(&$input) != IS_ARRAY) { SWIG_PHP_Error(E_ERROR, "Expected an array as input"); } arrColumnInfoArray = Z_ARRVAL_P(&$input); - int length = (int) zend_hash_num_elements(arrColumnInfoArray); - - if (length > 0) { - containerInfo = (GSColumnInfo *) malloc(length*sizeof(GSColumnInfo)); - if (containerInfo == NULL) { - SWIG_PHP_Error(E_ERROR, "Memmory allocation error"); - } - memset(containerInfo, 0x0, length*sizeof(GSColumnInfo)); + int length = zend_hash_num_elements(arrColumnInfoArray); - // Set value for property of columnInfoList - $1->columnInfo = containerInfo; - $1->size = length; + if (length == 0) { + SWIG_PHP_Error(E_ERROR, "Expected not empty array as input"); + } - for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); - (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; - zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { - // Input valid is array only - if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array property as ColumnInfo element"); - } + containerInfo = new GSColumnInfo[length]; + if (containerInfo == NULL) { + SWIG_PHP_Error(E_ERROR, "Memmory allocation error"); + } + memset(containerInfo, 0x0, length*sizeof(GSColumnInfo)); + + // Set value for property of columnInfoList + $1->columnInfo = containerInfo; + $1->size = length; + + for (zend_hash_internal_pointer_reset_ex(arrColumnInfoArray, &posColumnInfoArray); + (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; + zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { + // Input valid is array only + if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { + SWIG_PHP_Error(E_ERROR, "Expected array property" + " as ColumnInfo element"); + } - arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); - int sizeColumn = (int) zend_hash_num_elements(arrColumnInfo); - if (sizeColumn != 2) { - SWIG_PHP_Error(E_ERROR, "Expected two elements for ColumnInfo property"); - } - // Get column name - zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); - if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as column name"); - } - containerInfo[i].name = Z_STRVAL_P(columnName); + arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); + int sizeColumn = zend_hash_num_elements(arrColumnInfo); + if (sizeColumn != 2) { + SWIG_PHP_Error(E_ERROR, "Expected two elements" + " for ColumnInfo property"); + } + // Get column name + zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex( + arrColumnInfo, &posColumnInfo)) != IS_STRING) { + SWIG_PHP_Error(E_ERROR, "Expected string as column name"); + } + containerInfo[i].name = Z_STRVAL_P(columnName); - // Get column type - zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); - if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex(arrColumnInfo, &posColumnInfo)) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); - } - containerInfo[i].type = Z_LVAL_P(columnType); - i++; + // Get column type + zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); + if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex( + arrColumnInfo, &posColumnInfo)) != IS_LONG) { + SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); } + containerInfo[i].type = Z_LVAL_P(columnType); + i++; } } @@ -1054,7 +1122,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT */ %typemap(freearg) (ColumnInfoList*) { if ($1->columnInfo) { - free((void*) $1->columnInfo); + delete[]($1->columnInfo); } } @@ -1084,17 +1152,19 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zval* dateT /** * Typemaps output for PartitionController::get_container_names */ -%typemap(in, numinputs = 0) (const GSChar *const ** stringList, size_t *size) (GSChar **nameList, size_t size) { +%typemap(in, numinputs = 0) (const GSChar *const ** stringList, size_t *size) + (GSChar **nameList, size_t size) { $1 = &nameList; $2 = &size; } -%typemap(argout, numinputs = 0) (const GSChar * const ** stringList, size_t *size) { +%typemap(argout, numinputs = 0) (const GSChar * const ** stringList, + size_t *size) { GSChar** nameList = *$1; size_t size = *$2; array_init_size(return_value, size); - for (int i = 0; i < size; i++){ + for (int i = 0; i < size; i++) { add_next_index_string(return_value, nameList[i]); } } From b2d8ce438160674113103be624d142ca1e036974 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:47:26 +0900 Subject: [PATCH 12/22] update src C++ layer, gstype.i, griddb.i file after checking static code using cpplint --- src/AggregationResult.cpp | 33 +-- src/AggregationResult.h | 19 +- src/Container.cpp | 169 ++++++++------- src/Container.h | 61 +++--- src/ContainerInfo.cpp | 147 +++++++------ src/ContainerInfo.h | 74 +++---- src/EnumValue.h | 100 +++++---- src/ExpirationInfo.h | 100 +++++---- src/Field.cpp | 151 ++++++------- src/Field.h | 17 +- src/GSException.h | 400 +++++++++++++++++++---------------- src/PartitionController.cpp | 22 +- src/PartitionController.h | 29 +-- src/Query.cpp | 23 +- src/Query.h | 35 ++- src/QueryAnalysisEntry.cpp | 31 +-- src/QueryAnalysisEntry.h | 23 +- src/RowKeyPredicate.cpp | 229 +++++++++++--------- src/RowKeyPredicate.h | 31 ++- src/RowSet.cpp | 108 +++++----- src/RowSet.h | 58 +++-- src/Store.cpp | 146 +++++++------ src/Store.h | 59 +++--- src/StoreFactory.cpp | 62 +++--- src/StoreFactory.h | 40 ++-- src/TimeSeriesProperties.cpp | 15 +- src/TimeSeriesProperties.h | 33 +-- src/TimestampUtils.cpp | 2 +- src/TimestampUtils.h | 13 +- src/Util.cpp | 8 +- src/Util.h | 8 +- src/griddb.i | 4 +- src/gstype.i | 4 - 33 files changed, 1191 insertions(+), 1063 deletions(-) diff --git a/src/AggregationResult.cpp b/src/AggregationResult.cpp index ad8b2c0..32918ce 100644 --- a/src/AggregationResult.cpp +++ b/src/AggregationResult.cpp @@ -22,8 +22,9 @@ 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) { + AggregationResult::AggregationResult(GSAggregationResult *aggResult) : + mAggResult(aggResult), + timestamp_output_with_float(false) { } AggregationResult::~AggregationResult() { @@ -50,22 +51,24 @@ namespace griddb { void *value; agValue->type = type; switch (type) { - case GS_TYPE_DOUBLE: - value = &agValue->value.asDouble; - break; - case GS_TYPE_LONG: - value = &agValue->value.asLong; - break; - case GS_TYPE_TIMESTAMP: - value = &agValue->value.asTimestamp; - break; - default: - throw GSException(mAggResult, "Not support type from Aggregation result"); - break; + case GS_TYPE_DOUBLE: + value = &agValue->value.asDouble; + break; + case GS_TYPE_LONG: + value = &agValue->value.asLong; + break; + case GS_TYPE_TIMESTAMP: + value = &agValue->value.asTimestamp; + break; + default: + throw GSException(mAggResult, + "Not support type from Aggregation result"); + break; } GSBool ret = gsGetAggregationValue(mAggResult, value, type); if (ret == GS_FALSE) { - throw GSException(mAggResult, + throw GSException( + mAggResult, "Value cannot be retrieved from Aggregation result"); } } diff --git a/src/AggregationResult.h b/src/AggregationResult.h index 3db594f..202e946 100644 --- a/src/AggregationResult.h +++ b/src/AggregationResult.h @@ -23,25 +23,20 @@ #include "Field.h" #include "gridstore.h" -using namespace std; - namespace griddb { class AggregationResult { - - GSAggregationResult* mAggResult; + GSAggregationResult *mAggResult; friend class RowSet; - public: - bool timestamp_output_with_float; - ~AggregationResult(); - void close(); - void get(GSType type, griddb::Field *agValue); - AggregationResult(GSAggregationResult* aggResult); - + public: + bool timestamp_output_with_float; + ~AggregationResult(); + void close(); + void get(GSType type, griddb::Field *agValue); + explicit AggregationResult(GSAggregationResult *aggResult); }; - } /* namespace griddb */ #endif /* _AGGREGATIONRESULT_H_ */ diff --git a/src/Container.cpp b/src/Container.cpp index b1df025..817306d 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"); @@ -15,13 +15,16 @@ */ #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) { + 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); @@ -29,12 +32,14 @@ namespace griddb { 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 + 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 try { mContainerInfo = new GSContainerInfo(); - (*mContainerInfo) = (*containerInfo); // this is for set for normal data (int, float, double..) + // This is for set for normal data (int, float, double..) + (*mContainerInfo) = (*containerInfo); mContainerInfo->name = NULL; if (containerInfo->name) { Util::strdup(&(mContainerInfo->name), containerInfo->name); @@ -46,18 +51,21 @@ namespace griddb { 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); + 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; + 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 + } catch (std::bad_alloc &ba) { + // Memory allocation error freeMemoryContainer(); throw GSException(mContainer, "Memory allocation error"); } @@ -67,21 +75,22 @@ namespace griddb { mContainerInfo->dataAffinity = NULL; if (mTypeList && mContainerInfo->columnInfoList) { - for (int i = 0; i < mContainerInfo->columnCount; i++){ + for (int i = 0; i < mContainerInfo->columnCount; i++) { mTypeList[i] = mContainerInfo->columnInfoList[i].type; } } } Container::~Container() { - // allRelated = FALSE, since all row object is managed by Row class + // 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++) { - if (mContainerInfo->columnInfoList && mContainerInfo->columnInfoList[i].name) { + if (mContainerInfo->columnInfoList + && mContainerInfo->columnInfoList[i].name) { delete[] mContainerInfo->columnInfoList[i].name; } } @@ -102,7 +111,8 @@ namespace griddb { /** * @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 + * @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) { @@ -110,7 +120,7 @@ namespace griddb { mRow = NULL; } - //Release container and all related resources + // Release container and all related resources if (mContainer != NULL) { gsCloseContainer(&mContainer, allRelated); mContainer = NULL; @@ -123,7 +133,8 @@ namespace griddb { * @param *column_name Column name * @param index_type Flag value which shows index classification */ - void Container::drop_index(const char* column_name, GSIndexTypeFlags index_type) { + void Container::drop_index(const char *column_name, + GSIndexTypeFlags index_type) { GSResult ret = gsDropIndex(mContainer, column_name, index_type); if (!GS_SUCCEEDED(ret)) { @@ -136,7 +147,8 @@ namespace griddb { * @param *column_name Column name * @param index_type Flag value which shows index classification */ - void Container::create_index(const char *column_name, GSIndexTypeFlags index_type) { + void Container::create_index(const char *column_name, + GSIndexTypeFlags index_type) { GSResult ret = gsCreateIndex(mContainer, column_name, index_type); if (!GS_SUCCEEDED(ret)) { @@ -145,7 +157,8 @@ namespace griddb { } /** - * @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. + * @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); @@ -185,7 +198,8 @@ namespace griddb { } /** - * @brief 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); @@ -200,7 +214,7 @@ namespace griddb { * @param *query TQL statement * @return Return a Query object */ - Query* Container::query(const char* query) { + Query* Container::query(const char *query) { GSQuery *pQuery; GSResult ret = gsQuery(mContainer, query, &pQuery); @@ -209,9 +223,9 @@ namespace griddb { } try { - Query* queryObj = new Query(pQuery, mContainerInfo, mRow); + Query *queryObj = new Query(pQuery, mContainerInfo, mRow); return queryObj; - } catch(bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseQuery(&pQuery); throw GSException(mContainer, "Memory allocation error"); } @@ -221,9 +235,9 @@ namespace griddb { * @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){ + void Container::set_auto_commit(bool enabled) { GSBool gsEnabled; - gsEnabled = (enabled == true ? GS_TRUE:GS_FALSE); + gsEnabled = (enabled == true ? GS_TRUE : GS_FALSE); GSResult ret = gsSetAutoCommit(mContainer, gsEnabled); if (!GS_SUCCEEDED(ret)) { throw GSException(mContainer, ret); @@ -246,38 +260,39 @@ namespace griddb { * @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) { + GSBool Container::get(Field *keyFields, GSRow *rowdata) { assert(keyFields != NULL); GSBool exists; GSResult ret; void *key = NULL; switch (keyFields->type) { - case GS_TYPE_STRING: - if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) { - throw GSException("wrong type of rowKey string"); - } - key = &keyFields->value.asString; - break; - case GS_TYPE_INTEGER: - if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) { - throw GSException("wrong type of rowKey integer"); - } - key = &keyFields->value.asInteger; - break; - case GS_TYPE_LONG: - if (mContainerInfo->columnInfoList[0].type != GS_TYPE_LONG) { - throw GSException("wrong type of rowKey long"); - } - key = &keyFields->value.asLong; - break; - case GS_TYPE_TIMESTAMP: - if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) { - throw GSException("wrong type of rowKey timestamp"); - } - key = &keyFields->value.asTimestamp; - break; - default: - throw GSException("wrong type of rowKey field"); + case GS_TYPE_STRING: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) { + throw GSException("wrong type of rowKey string"); + } + key = &keyFields->value.asString; + break; + case GS_TYPE_INTEGER: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) { + throw GSException("wrong type of rowKey integer"); + } + key = &keyFields->value.asInteger; + break; + case GS_TYPE_LONG: + if (mContainerInfo->columnInfoList[0].type != GS_TYPE_LONG) { + throw GSException("wrong type of rowKey long"); + } + key = &keyFields->value.asLong; + break; + case GS_TYPE_TIMESTAMP: + if (mContainerInfo->columnInfoList[0].type + != GS_TYPE_TIMESTAMP) { + throw GSException("wrong type of rowKey timestamp"); + } + key = &keyFields->value.asTimestamp; + break; + default: + throw GSException("wrong type of rowKey field"); } ret = gsGetRow(mContainer, key, mRow, &exists); @@ -293,49 +308,53 @@ namespace griddb { * @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) { + bool Container::remove(Field *keyFields) { assert(keyFields != NULL); GSBool exists = GS_FALSE; GSResult ret; - if (keyFields->type == GS_TYPE_NULL) { - ret = gsDeleteRow(mContainer, NULL, &exists); - } else { - switch (keyFields->type) { + switch (keyFields->type) { + case GS_TYPE_NULL: + ret = gsDeleteRow(mContainer, NULL, &exists); + break; case GS_TYPE_STRING: if (mContainerInfo->columnInfoList[0].type != GS_TYPE_STRING) { throw GSException("wrong type of rowKey string"); } - ret = gsDeleteRow(mContainer, &keyFields->value.asString, &exists); + ret = gsDeleteRow(mContainer, &keyFields->value.asString, + &exists); break; case GS_TYPE_INTEGER: if (mContainerInfo->columnInfoList[0].type != GS_TYPE_INTEGER) { throw GSException("wrong type of rowKey integer"); } - ret = gsDeleteRow(mContainer, &keyFields->value.asInteger, &exists); + ret = gsDeleteRow(mContainer, &keyFields->value.asInteger, + &exists); break; case GS_TYPE_LONG: if (mContainerInfo->columnInfoList[0].type != GS_TYPE_LONG) { throw GSException("wrong type of rowKey long"); } - ret = gsDeleteRow(mContainer, &keyFields->value.asLong, &exists); + ret = gsDeleteRow(mContainer, &keyFields->value.asLong, + &exists); break; case GS_TYPE_TIMESTAMP: - if (mContainerInfo->columnInfoList[0].type != GS_TYPE_TIMESTAMP) { + if (mContainerInfo->columnInfoList[0].type + != GS_TYPE_TIMESTAMP) { throw GSException("wrong type of rowKey timestamp"); } - ret = gsDeleteRow(mContainer, &keyFields->value.asTimestamp, &exists); + ret = gsDeleteRow(mContainer, &keyFields->value.asTimestamp, + &exists); break; default: throw GSException("wrong type of rowKey field"); - } } if (!GS_SUCCEEDED(ret)) { throw GSException(mContainer, ret); } - return (bool) exists; + return static_cast(exists); } /** @@ -343,12 +362,12 @@ namespace griddb { * @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) { + void Container::multi_put(GSRow **listRowdata, int rowCount) { GSResult ret; GSBool bExists; - //data for each container - ret = gsPutMultipleRows(mContainer, (const void * const *) listRowdata, - rowCount, &bExists); + // Data for each container + ret = gsPutMultipleRows(mContainer, (const void* const*) listRowdata, + rowCount, &bExists); if (!GS_SUCCEEDED(ret)) { throw GSException(mContainer, ret); } @@ -358,7 +377,7 @@ namespace griddb { * @brief Get GSContainer of Container object to support Store::multi_put * @return Return a pointer which store GSContainer of container */ - GSContainer* Container::getGSContainerPtr(){ + GSContainer* Container::getGSContainerPtr() { return mContainer; } @@ -366,7 +385,7 @@ namespace griddb { * @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(){ + GSType* Container::getGSTypeList() { return mTypeList; } @@ -374,7 +393,7 @@ namespace griddb { * @brief Get GSRow of Container object to support put row * @return Return a pointer which store GSRow of container */ - GSRow* Container::getGSRowPtr(){ + GSRow* Container::getGSRowPtr() { return mRow; } @@ -382,7 +401,7 @@ namespace griddb { * @brief Get number of column of row in container * @return Return number of column of row in container */ - int Container::getColumnCount(){ + int Container::getColumnCount() { return mContainerInfo->columnCount; } -} +} /* namespace griddb */ diff --git a/src/Container.h b/src/Container.h index 4569006..7c01c08 100644 --- a/src/Container.h +++ b/src/Container.h @@ -24,44 +24,43 @@ #include "GSException.h" #include "Util.h" -using namespace std; - namespace griddb { class Container { - - GSContainerInfo* mContainerInfo; + GSContainerInfo *mContainerInfo; GSContainer *mContainer; friend class Store; - GSRow* mRow; - GSType* mTypeList; - - public: - bool timestamp_output_with_float; - ~Container(); - void close(GSBool allRelated = GS_FALSE); - GSContainerType get_type(); - void create_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT); - void drop_index(const char* column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT); - bool put(GSRow *row); - Query* query(const char *query); - void abort(); - void flush(); - void set_auto_commit(bool enabled); - void commit(); - GSBool get(Field* keyFields, GSRow *rowdata); - bool remove(Field* keyFields); - void multi_put(GSRow** listRowdata, int rowCount); - GSContainer* getGSContainerPtr(); - GSType* getGSTypeList(); - int getColumnCount(); - GSRow* getGSRowPtr(); - - private: - Container(GSContainer *container, GSContainerInfo* containerInfo); - void freeMemoryContainer(); + GSRow *mRow; + GSType *mTypeList; + + public: + bool timestamp_output_with_float; + ~Container(); + void close(GSBool allRelated = GS_FALSE); + GSContainerType get_type(); + void create_index(const char *column_name, GSIndexTypeFlags index_type = + GS_INDEX_FLAG_DEFAULT); + void drop_index(const char *column_name, GSIndexTypeFlags index_type = + GS_INDEX_FLAG_DEFAULT); + bool put(GSRow *row); + Query* query(const char *query); + void abort(); + void flush(); + void set_auto_commit(bool enabled); + void commit(); + GSBool get(Field *keyFields, GSRow *rowdata); + bool remove(Field *keyFields); + void multi_put(GSRow **listRowdata, int rowCount); + GSContainer* getGSContainerPtr(); + GSType* getGSTypeList(); + int getColumnCount(); + GSRow* getGSRowPtr(); + + private: + Container(GSContainer *container, GSContainerInfo *containerInfo); + void freeMemoryContainer(); }; } /* namespace griddb */ diff --git a/src/ContainerInfo.cpp b/src/ContainerInfo.cpp index 7fd2ba4..a49b529 100644 --- a/src/ContainerInfo.cpp +++ b/src/ContainerInfo.cpp @@ -25,11 +25,11 @@ namespace griddb { 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; + containerInfo->columnInfoList, containerInfo->columnCount, + containerInfo->rowKeyAssigned, NULL); + // Assign values from argument to mContainer + GSTimeSeriesProperties *gsProps = NULL; + GSTriggerInfo *triggerInfoList = NULL; try { if (containerInfo->timeSeriesProperties) { @@ -41,12 +41,13 @@ namespace griddb { } if (containerInfo->dataAffinity) { - Util::strdup(&mContainerInfo.dataAffinity, containerInfo->dataAffinity); + Util::strdup(&mContainerInfo.dataAffinity, + containerInfo->dataAffinity); } else { mContainerInfo.dataAffinity = NULL; } - } catch (bad_alloc& ba) { - //case allocation memory error + } catch (std::bad_alloc &ba) { + // Case allocation memory error if (gsProps) { delete gsProps; } @@ -60,17 +61,20 @@ namespace griddb { } if (containerInfo->timeSeriesProperties) { - memcpy(gsProps, containerInfo->timeSeriesProperties, sizeof(GSTimeSeriesProperties)); + memcpy(gsProps, containerInfo->timeSeriesProperties, + sizeof(GSTimeSeriesProperties)); } mContainerInfo.timeSeriesProperties = gsProps; if (containerInfo->triggerInfoList) { - memcpy(triggerInfoList, containerInfo->triggerInfoList, sizeof(GSTriggerInfo)); + memcpy(triggerInfoList, containerInfo->triggerInfoList, + sizeof(GSTriggerInfo)); } mContainerInfo.triggerInfoList = triggerInfoList; - mContainerInfo.columnOrderIgnorable = containerInfo->columnOrderIgnorable; + mContainerInfo.columnOrderIgnorable = containerInfo + ->columnOrderIgnorable; mContainerInfo.triggerInfoCount = containerInfo->triggerInfoCount; mColumnInfoList.columnInfo = NULL; mColumnInfoList.size = 0; @@ -85,27 +89,29 @@ namespace griddb { * @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) { + 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); } /** * Initialize values of Container Info object */ - void ContainerInfo::init(const GSChar* name, - GSContainerType type, const GSColumnInfo* props, - int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration) { - GSColumnInfo* columnInfoList = NULL; - GSChar* containerName = NULL; - GSTimeSeriesProperties* timeProps = NULL; + void ContainerInfo::init(const GSChar *name, GSContainerType type, + const GSColumnInfo *props, int propsCount, + bool rowKeyAssigned, ExpirationInfo *expiration) { + GSColumnInfo *columnInfoList = NULL; + GSChar *containerName = NULL; + GSTimeSeriesProperties *timeProps = 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 + // 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); @@ -119,11 +125,11 @@ namespace griddb { timeProps = new GSTimeSeriesProperties(); } - //Container name memory is copied via strdup function + // Container name memory is copied via strdup function if (name != NULL) { - Util::strdup((const GSChar**)&containerName, name); + Util::strdup((const GSChar**) &containerName, name); } - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { if (columnInfoList) { for (int i = 0; i < propsCount; i++) { if (columnInfoList[i].name) { @@ -142,10 +148,12 @@ namespace griddb { } if (expiration != NULL) { - memcpy(timeProps, expiration->gs_ts(), sizeof(GSTimeSeriesProperties)); + memcpy(timeProps, expiration->gs_ts(), + sizeof(GSTimeSeriesProperties)); } - mContainerInfo = {containerName, type, (size_t)propsCount, columnInfoList, rowKeyAssigned}; + mContainerInfo = { containerName, type, (size_t) propsCount, + columnInfoList, rowKeyAssigned }; if (timeProps != NULL) { mContainerInfo.timeSeriesProperties = timeProps; } @@ -155,34 +163,34 @@ namespace griddb { } ContainerInfo::~ContainerInfo() { - //Free memory for the copy of container name + // Free memory for the copy of container name if (mContainerInfo.name) { delete[] mContainerInfo.name; } - //Free memory for the copy of ColumnInfo list + // Free memory for the copy of ColumnInfo list if (mContainerInfo.columnInfoList) { - //Free memory of columns name - for(int i = 0; i < mContainerInfo.columnCount; i++) { - if(mContainerInfo.columnInfoList[i].name) { + // Free memory of columns name + for (int i = 0; i < mContainerInfo.columnCount; i++) { + if (mContainerInfo.columnInfoList[i].name) { delete[] mContainerInfo.columnInfoList[i].name; } } delete[] mContainerInfo.columnInfoList; } - //Free memory of TimeSeriesProperties if existed + // Free memory of TimeSeriesProperties if existed if (mContainerInfo.timeSeriesProperties) { delete mContainerInfo.timeSeriesProperties; } - //Free memory of dataAffinity if existed + // Free memory of dataAffinity if existed if (mContainerInfo.dataAffinity) { delete[] mContainerInfo.dataAffinity; } - //Free memory of triggerInfoList if existed - if(mContainerInfo.triggerInfoList) { + // Free memory of triggerInfoList if existed + if (mContainerInfo.triggerInfoList) { delete mContainerInfo.triggerInfoList; } if (mExpInfo != NULL) { @@ -194,7 +202,7 @@ namespace griddb { * @brief Set name of Container which is stored in ContainerInfo * @param *containerName Stores the name of Container */ - void ContainerInfo::set_name(GSChar* containerName) { + void ContainerInfo::set_name(GSChar *containerName) { if (mContainerInfo.name) { delete[] mContainerInfo.name; } @@ -203,7 +211,7 @@ namespace griddb { } else { try { Util::strdup(&(mContainerInfo.name), containerName); - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException("Memory allocation error"); } } @@ -274,10 +282,10 @@ namespace griddb { * @param columnInfoList A struct which store information of column */ void ContainerInfo::set_column_info_list(ColumnInfoList columnInfoList) { - //Free current stored ColumnInfo list + // Free current stored ColumnInfo list if (mContainerInfo.columnInfoList) { - //Free memory of columns name - for(int i = 0; i < mContainerInfo.columnCount; i++) { + // Free memory of columns name + for (int i = 0; i < mContainerInfo.columnCount; i++) { delete[] mContainerInfo.columnInfoList[i].name; } delete[] mContainerInfo.columnInfoList; @@ -289,22 +297,24 @@ namespace griddb { if (columnInfoList.size == 0 || columnInfoList.columnInfo == NULL) { return; } - - GSColumnInfo* tmpColumnInfoList; + + GSColumnInfo *tmpColumnInfoList; try { tmpColumnInfoList = new GSColumnInfo[columnInfoList.size](); - } catch (bad_alloc& ba) { + } catch (std::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 + + // 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) { + Util::strdup(&(tmpColumnInfoList[i].name), + columnInfoList.columnInfo[i].name); + } catch (std::bad_alloc &ba) { delete[] tmpColumnInfoList; tmpColumnInfoList = NULL; throw GSException("Memory allocation error"); @@ -321,25 +331,28 @@ namespace griddb { * @return A struct which store information of column */ ColumnInfoList ContainerInfo::get_column_info_list() { - mColumnInfoList.columnInfo = (GSColumnInfo*) mContainerInfo.columnInfoList; + mColumnInfoList.columnInfo = const_cast(mContainerInfo + .columnInfoList); mColumnInfoList.size = mContainerInfo.columnCount; return mColumnInfoList; } /** * @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 + * @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) { + void ContainerInfo::set_expiration_info(ExpirationInfo *expirationInfo) { if (mContainerInfo.timeSeriesProperties != NULL) { delete mContainerInfo.timeSeriesProperties; mContainerInfo.timeSeriesProperties = NULL; } if (expirationInfo) { - GSTimeSeriesProperties* ts; + GSTimeSeriesProperties *ts; try { ts = new GSTimeSeriesProperties(); - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException("Memory allocation error"); } @@ -351,20 +364,26 @@ namespace griddb { /** * @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 + * @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){ + const GSTimeSeriesProperties *timeSeriesProperties = mContainerInfo + .timeSeriesProperties; + if (timeSeriesProperties != NULL) { if (mExpInfo != NULL) { - mExpInfo->set_time(mContainerInfo.timeSeriesProperties->rowExpirationTime); - mExpInfo->set_time_unit(mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit); - mExpInfo->set_division_count(mContainerInfo.timeSeriesProperties->expirationDivisionCount); + mExpInfo->set_time(timeSeriesProperties->rowExpirationTime); + mExpInfo->set_time_unit( + timeSeriesProperties->rowExpirationTimeUnit); + mExpInfo->set_division_count( + timeSeriesProperties->expirationDivisionCount); } else { try { - mExpInfo = new ExpirationInfo(mContainerInfo.timeSeriesProperties->rowExpirationTime, - mContainerInfo.timeSeriesProperties->rowExpirationTimeUnit, - mContainerInfo.timeSeriesProperties->expirationDivisionCount); - } catch (bad_alloc& ba) { + mExpInfo = new ExpirationInfo( + timeSeriesProperties->rowExpirationTime, + timeSeriesProperties->rowExpirationTimeUnit, + timeSeriesProperties->expirationDivisionCount); + } catch (std::bad_alloc &ba) { throw GSException("Memory allocation error"); } } diff --git a/src/ContainerInfo.h b/src/ContainerInfo.h index d9c262a..14996e1 100644 --- a/src/ContainerInfo.h +++ b/src/ContainerInfo.h @@ -17,62 +17,62 @@ #ifndef _CONTAINERINFO_H_ #define _CONTAINERINFO_H_ +#include #include #include #include -#include #include "TimeSeriesProperties.h" #include "ExpirationInfo.h" #include "GSException.h" #include "Util.h" -//Support column_info_list attribute +// Support column_info_list attribute struct ColumnInfoList { - GSColumnInfo* columnInfo; + GSColumnInfo *columnInfo; size_t size; }; -using namespace std; - namespace griddb { class ContainerInfo { /** * Contains information about a specific container */ - private: - GSContainerInfo mContainerInfo; - - //tmp attribute to get column info list - ColumnInfoList mColumnInfoList; - - //tmp attribute support get expiration attribute - ExpirationInfo* mExpInfo; - - public: - ContainerInfo(GSContainerInfo *containerInfo); - ContainerInfo(const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, - bool row_key, ExpirationInfo* expiration); - ~ContainerInfo(); - - void set_name(GSChar* containerName); - void set_type(GSContainerType containerType); - void set_row_key_assigned(bool rowKeyAssigned); - const GSChar* get_name(); - GSContainerType get_type(); - GSColumnInfo get_column_info(size_t column); - ColumnInfoList get_column_info_list(); - void set_column_info_list(ColumnInfoList columnInfoList); - ExpirationInfo* get_expiration_info(); - void set_expiration_info(ExpirationInfo* expirationInfo); - bool get_row_key_assigned(); - GSContainerInfo* gs_info(); - - private: - void init(const GSChar* name, GSContainerType type, const GSColumnInfo* props, - int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration); + private: + GSContainerInfo mContainerInfo; + + // tmp attribute to get column info list + ColumnInfoList mColumnInfoList; + + // tmp attribute support get expiration attribute + ExpirationInfo *mExpInfo; + + public: + explicit ContainerInfo(GSContainerInfo *containerInfo); + + ContainerInfo(const GSChar *name, const GSColumnInfo *props, int propsCount, + GSContainerType type, bool row_key, + ExpirationInfo *expiration); + ~ContainerInfo(); + + void set_name(GSChar *containerName); + void set_type(GSContainerType containerType); + void set_row_key_assigned(bool rowKeyAssigned); + const GSChar* get_name(); + GSContainerType get_type(); + GSColumnInfo get_column_info(size_t column); + ColumnInfoList get_column_info_list(); + void set_column_info_list(ColumnInfoList columnInfoList); + ExpirationInfo* get_expiration_info(); + void set_expiration_info(ExpirationInfo *expirationInfo); + bool get_row_key_assigned(); + GSContainerInfo* gs_info(); + + private: + void init(const GSChar *name, GSContainerType type, + const GSColumnInfo *props, int propsCount, bool rowKeyAssigned, + ExpirationInfo *expiration); }; } /* namespace griddb */ diff --git a/src/EnumValue.h b/src/EnumValue.h index dfbffbd..ea0451f 100644 --- a/src/EnumValue.h +++ b/src/EnumValue.h @@ -17,34 +17,32 @@ #ifndef _ENUM_VALUE_H_ #define _ENUM_VALUE_H_ -using namespace std; - namespace griddb { // Represents the type(s) of a Container. class ContainerType { - public: - static const int COLLECTION = 0; - static const int TIME_SERIES = 1; + public: + static const int COLLECTION = 0; + static const int TIME_SERIES = 1; }; // Represents the type(s) of indexes set on a Container. class IndexType { - public: - static const int DEFAULT = -1; - static const int TREE = 1 << 0; - static const int HASH = 1 << 1; - static const int SPATIAL = 1 << 2; + public: + static const int DEFAULT = -1; + static const int TREE = 1 << 0; + static const int HASH = 1 << 1; + static const int SPATIAL = 1 << 2; }; // The type of content that can be extracted from GSRowSet. class RowSetType { - public: - static const int CONTAINER_ROWS = 0; - static const int AGGREGATION_RESULT = 1; - static const int QUERY_ANALYSIS = 2; + public: + static const int CONTAINER_ROWS = 0; + static const int AGGREGATION_RESULT = 1; + static const int QUERY_ANALYSIS = 2; }; // The options for fetching the result of a query. class FetchOption { - public: - static const int LIMIT = 0; + public: + static const int LIMIT = 0; #if GS_INTERNAL_DEFINITION_VISIBLE #if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE @@ -58,48 +56,48 @@ class FetchOption { }; // Represents the time unit(s) used in TimeSeries data operation. class TimeUnit { - public: - static const int YEAR = 0; - static const int MONTH = 1; - static const int DAY = 2; - static const int HOUR = 3; - static const int MINUTE = 4; - static const int SECOND = 5; - static const int MILLISECOND = 6; + public: + static const int YEAR = 0; + static const int MONTH = 1; + static const int DAY = 2; + static const int HOUR = 3; + static const int MINUTE = 4; + static const int SECOND = 5; + static const int MILLISECOND = 6; }; // Represents the type(s) of field values in GridDB. class Type { - public: - static const int STRING = 0; - static const int BOOL = 1; - static const int BYTE = 2; - static const int SHORT = 3; - static const int INTEGER = 4; - static const int LONG = 5; - static const int FLOAT = 6; - static const int DOUBLE = 7; - static const int TIMESTAMP = 8; - static const int GEOMETRY = 9; - static const int BLOB = 10; - static const int STRING_ARRAY = 11; - static const int BOOL_ARRAY = 12; - static const int BYTE_ARRAY = 13; - static const int SHORT_ARRAY = 14; - static const int INTEGER_ARRAY = 15; - static const int LONG_ARRAY = 16; - static const int FLOAT_ARRAY = 17; - static const int DOUBLE_ARRAY = 18; - static const int TIMESTAMP_ARRAY = 19; + public: + static const int STRING = 0; + static const int BOOL = 1; + static const int BYTE = 2; + static const int SHORT = 3; + static const int INTEGER = 4; + static const int LONG = 5; + static const int FLOAT = 6; + static const int DOUBLE = 7; + static const int TIMESTAMP = 8; + static const int GEOMETRY = 9; + static const int BLOB = 10; + static const int STRING_ARRAY = 11; + static const int BOOL_ARRAY = 12; + static const int BYTE_ARRAY = 13; + static const int SHORT_ARRAY = 14; + static const int INTEGER_ARRAY = 15; + static const int LONG_ARRAY = 16; + static const int FLOAT_ARRAY = 17; + static const int DOUBLE_ARRAY = 18; + static const int TIMESTAMP_ARRAY = 19; - // Can't use NULL because it is keyword of C language - static const int NULL_TYPE = -1; + // Can't use NULL because it is keyword of C language + static const int NULL_TYPE = -1; }; // Sum of bits of value of the flag indicating the option setting for Column. class TypeOption { - public: - static const int NULLABLE = 1 << 1; - static const int NOT_NULL = 1 << 2; + public: + static const int NULLABLE = 1 << 1; + static const int NOT_NULL = 1 << 2; }; -} +} /* namespace griddb */ #endif diff --git a/src/ExpirationInfo.h b/src/ExpirationInfo.h index c59a972..f80b51a 100644 --- a/src/ExpirationInfo.h +++ b/src/ExpirationInfo.h @@ -20,8 +20,6 @@ #include #include -using namespace std; - namespace griddb { class ExpirationInfo { /* @@ -29,51 +27,59 @@ class ExpirationInfo { */ GSTimeSeriesProperties mTimeSeriesProps; - public: - ExpirationInfo(const GSTimeSeriesProperties* timeSeriesProps) { - mTimeSeriesProps.rowExpirationTime = timeSeriesProps->rowExpirationTime; - mTimeSeriesProps.rowExpirationTimeUnit = timeSeriesProps->rowExpirationTimeUnit; - mTimeSeriesProps.expirationDivisionCount = timeSeriesProps->expirationDivisionCount; - mTimeSeriesProps.compressionList = NULL; - mTimeSeriesProps.compressionListSize = 0; - mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; - mTimeSeriesProps.compressionWindowSize = 0; - mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; - }; - ExpirationInfo(int time, GSTimeUnit unit, int division_count) { - mTimeSeriesProps.rowExpirationTime = time; - mTimeSeriesProps.rowExpirationTimeUnit = unit; - mTimeSeriesProps.expirationDivisionCount = division_count; - mTimeSeriesProps.compressionList = NULL; - mTimeSeriesProps.compressionListSize = 0; - mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; - mTimeSeriesProps.compressionWindowSize = 0; - mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; - }; - ~ExpirationInfo() { - //nothing to do - }; - int get_time() { - return mTimeSeriesProps.rowExpirationTime; - }; - void set_time(int time) { - mTimeSeriesProps.rowExpirationTime = time; - }; - GSTimeUnit get_time_unit() { - return mTimeSeriesProps.rowExpirationTimeUnit; - }; - void set_time_unit(GSTimeUnit unit) { - mTimeSeriesProps.rowExpirationTimeUnit = unit; - }; - int get_division_count() { - return mTimeSeriesProps.expirationDivisionCount; - }; - void set_division_count(int division_count) { - mTimeSeriesProps.expirationDivisionCount = division_count; - }; - GSTimeSeriesProperties* gs_ts() { - return &mTimeSeriesProps; - }; + public: + explicit ExpirationInfo(const GSTimeSeriesProperties *timeSeriesProps) { + mTimeSeriesProps.rowExpirationTime = timeSeriesProps->rowExpirationTime; + mTimeSeriesProps.rowExpirationTimeUnit = timeSeriesProps + ->rowExpirationTimeUnit; + mTimeSeriesProps.expirationDivisionCount = timeSeriesProps + ->expirationDivisionCount; + mTimeSeriesProps.compressionList = NULL; + mTimeSeriesProps.compressionListSize = 0; + mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; + mTimeSeriesProps.compressionWindowSize = 0; + mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; + } + ExpirationInfo(int time, GSTimeUnit unit, int division_count) { + mTimeSeriesProps.rowExpirationTime = time; + mTimeSeriesProps.rowExpirationTimeUnit = unit; + mTimeSeriesProps.expirationDivisionCount = division_count; + mTimeSeriesProps.compressionList = NULL; + mTimeSeriesProps.compressionListSize = 0; + mTimeSeriesProps.compressionMethod = GS_COMPRESSION_NO; + mTimeSeriesProps.compressionWindowSize = 0; + mTimeSeriesProps.compressionWindowSizeUnit = GS_TIME_UNIT_YEAR; + } + ~ExpirationInfo() { + // Nothing to do + } + + int get_time() { + return mTimeSeriesProps.rowExpirationTime; + } + void set_time(int time) { + mTimeSeriesProps.rowExpirationTime = time; + } + + GSTimeUnit get_time_unit() { + return mTimeSeriesProps.rowExpirationTimeUnit; + } + + void set_time_unit(GSTimeUnit unit) { + mTimeSeriesProps.rowExpirationTimeUnit = unit; + } + + int get_division_count() { + return mTimeSeriesProps.expirationDivisionCount; + } + + void set_division_count(int division_count) { + mTimeSeriesProps.expirationDivisionCount = division_count; + } + + GSTimeSeriesProperties* gs_ts() { + return &mTimeSeriesProps; + } }; } /* namespace griddb */ diff --git a/src/Field.cpp b/src/Field.cpp index d1eaa13..3964bfd 100644 --- a/src/Field.cpp +++ b/src/Field.cpp @@ -21,86 +21,87 @@ namespace griddb { /** * @brief Constructor a new Field:: Field object */ - Field::Field() : type(GS_TYPE_STRING) { + 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 [] (char*)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]; + case GS_TYPE_STRING: + if (value.asString) { + delete[] value.asString; + value.asString = NULL; + } + break; + case GS_TYPE_BLOB: + if (value.asBlob.data) { + delete[] reinterpret_cast(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; } - 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; + break; + default: + // Not need to free allocation + break; } } -} +} /* namespace griddb */ diff --git a/src/Field.h b/src/Field.h index 15e3f36..1a1660a 100644 --- a/src/Field.h +++ b/src/Field.h @@ -17,23 +17,20 @@ #ifndef _FIELD_H_ #define _FIELD_H_ -#include #include +#include #include "gridstore.h" -using namespace std; - namespace griddb { class Field { - public: - GSType type; - GSValue value; - Field(); - ~Field(); + public: + GSType type; + GSValue value; + Field(); + ~Field(); }; - -} +} /* namespace griddb */ #endif /* _FIELD_H_ */ diff --git a/src/GSException.h b/src/GSException.h index c2090ed..b652cc5 100644 --- a/src/GSException.h +++ b/src/GSException.h @@ -22,7 +22,8 @@ #include "gridstore.h" -using namespace std; +using std::string; +using std::exception; #define DEFAULT_ERROR_CODE -1 #define DEFAULT_ERROR_STACK_SIZE 1 @@ -33,21 +34,65 @@ namespace griddb { * This class creates exception corresponding to error code */ class GSException : public exception { - private: - bool mIsTimeout; - int32_t mCode; - string mMessage; - void *mResource; - - bool hasInnerError; - size_t mInnerErrStackSize; - GSResult* mInnerErrCodeStack; - string* mInnerMessagesStack; - string* mInnerErrorLocationStack; - - public: - GSException(const char* message) : exception(), - mCode(DEFAULT_ERROR_CODE), mMessage(message), mResource(NULL) { + private: + bool mIsTimeout; + int32_t mCode; + string mMessage; + void *mResource; + bool hasInnerError; + size_t mInnerErrStackSize; + GSResult *mInnerErrCodeStack; + string *mInnerMessagesStack; + string *mInnerErrorLocationStack; + + public: + explicit GSException(const char *message) + : + exception(), + mCode(DEFAULT_ERROR_CODE), + mMessage(message), + mResource(NULL) { + 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) { + hasInnerError = false; + mInnerErrStackSize = 0; + mInnerErrCodeStack = NULL; + mInnerMessagesStack = NULL; + mInnerErrorLocationStack = NULL; + mIsTimeout = false; + } + GSException(const GSException &e) + : + exception() { + mCode = e.mCode; + mResource = e.mResource; + mIsTimeout = e.mIsTimeout; + mMessage = "Error with number " + std::to_string(mCode); + if (mCode != DEFAULT_ERROR_CODE && mResource != NULL) { + mIsTimeout = gsIsTimeoutError(mCode); + 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; @@ -55,9 +100,28 @@ class GSException : public exception { mInnerErrorLocationStack = NULL; mIsTimeout = false; } - - GSException(void *resource, const char* message) : exception(), - mCode(DEFAULT_ERROR_CODE), mMessage(message), mResource(resource) { + } + GSException(void *resource, int32_t code) + : + exception(), + mCode(code), + mResource(resource) { + mMessage = "Error with number " + std::to_string(mCode); + if (mCode != DEFAULT_ERROR_CODE && mResource != NULL) { + // Case exception with error code from c layer + mIsTimeout = gsIsTimeoutError(mCode); + // 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; @@ -65,188 +129,148 @@ class GSException : public exception { mInnerErrorLocationStack = NULL; mIsTimeout = false; } - GSException(const GSException&e) : exception() { - mCode = e.mCode; - mResource = e.mResource; - mIsTimeout = e.mIsTimeout; - mMessage = "Error with number " + to_string((long long int)mCode); - if (mCode != DEFAULT_ERROR_CODE && mResource != NULL) { - mIsTimeout = gsIsTimeoutError(mCode); - 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; + } + explicit GSException(const GSException *exception) { + mCode = exception->mCode; + 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(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 && mResource != NULL) { - //Case exception with error code from c layer - mIsTimeout = gsIsTimeoutError(mCode); - // 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; - } - } - GSException(const GSException* exception) { - mCode = exception->mCode; - 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(); - } + } + ~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; - } - } - int32_t get_code() { - return mCode; + void close() { + if (mInnerErrCodeStack != NULL) { + delete[] mInnerErrCodeStack; + mInnerErrCodeStack = NULL; } - virtual const char* what() const throw() { - return mMessage.c_str(); + if (mInnerMessagesStack != NULL) { + delete[] mInnerMessagesStack; + mInnerMessagesStack = NULL; } - /* - * Check timeout. Convert from C-API: gsIsTimeoutError - */ - bool is_timeout() { - return mIsTimeout; + if (mInnerErrorLocationStack != NULL) { + delete[] mInnerErrorLocationStack; + mInnerErrorLocationStack = NULL; } - /** - * Get error stack size. Convert from C-API: gsGetErrorStackSize. - */ - size_t get_error_stack_size() { - if (hasInnerError == false) { - return DEFAULT_ERROR_STACK_SIZE; - } - return mInnerErrStackSize; + } + int32_t get_code() { + return mCode; + } + virtual const char* what() const throw() { + return mMessage.c_str(); + } + /* + * Check timeout. Convert from C-API: gsIsTimeoutError + */ + bool is_timeout() { + return mIsTimeout; + } + /** + * Get error stack size. Convert from C-API: gsGetErrorStackSize. + */ + size_t get_error_stack_size() { + if (hasInnerError == false) { + return DEFAULT_ERROR_STACK_SIZE; } - /** - * Get error code. Convert from C-API: gsGetErrorCode. - */ - GSResult get_error_code(size_t stack_index) { - if (hasInnerError == false) { - if (stack_index == 0) return mCode; + return mInnerErrStackSize; + } + /** + * Get error code. Convert from C-API: gsGetErrorCode. + */ + GSResult get_error_code(size_t stack_index) { + if (hasInnerError == false) { + if (stack_index == 0) + return mCode; + return 0; + } else { + if (stack_index >= mInnerErrStackSize) return 0; - } else { - if (stack_index >= mInnerErrStackSize) return 0; - return mInnerErrCodeStack[stack_index]; - } + 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; + } + /** + * 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 ""; - } else { - if (stack_index >= mInnerErrStackSize) return ""; - return mInnerMessagesStack[stack_index]; - } + 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) { + } + /** + * 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 ""; - } 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); - delete [] strBuf; - return ret; - } - /** - * Get error location. Convert from C-API: gsFormatErrorLocation. - */ - 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); - delete [] strBuf; - return ret; + 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); + delete[] strBuf; + return ret; + } + /** + * Get error location. Convert from C-API: gsFormatErrorLocation. + */ + 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); + delete[] strBuf; + return ret; + } }; } /* namespace griddb */ diff --git a/src/PartitionController.cpp b/src/PartitionController.cpp index 639b0fc..60cb1c4 100644 --- a/src/PartitionController.cpp +++ b/src/PartitionController.cpp @@ -23,7 +23,7 @@ namespace griddb { * @param *controller A pointer for acquiring and processing the partition status */ PartitionController::PartitionController(GSPartitionController *controller) : - mController(controller) { + mController(controller) { } /** @@ -65,7 +65,8 @@ namespace griddb { */ int64_t PartitionController::get_container_count(int32_t partition_index) { int64_t value; - GSResult ret = gsGetPartitionContainerCount(mController, partition_index, &value); + GSResult ret = gsGetPartitionContainerCount(mController, + partition_index, &value); // Check ret, if error, throw exception if (!GS_SUCCEEDED(ret)) { @@ -82,15 +83,18 @@ namespace griddb { * @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) { - int64_t* limitPtr; + void PartitionController::get_container_names( + int32_t partition_index, int64_t start, + const GSChar *const**stringList, size_t *size, int64_t limit) { + int64_t *limitPtr; if (limit >= 0) { limitPtr = &limit; } else { limitPtr = NULL; } - GSResult ret = gsGetPartitionContainerNames(mController, partition_index, start, limitPtr, stringList, size); + GSResult ret = gsGetPartitionContainerNames(mController, + partition_index, start, + limitPtr, stringList, size); if (!GS_SUCCEEDED(ret)) { throw GSException(mController, ret); @@ -102,9 +106,11 @@ namespace griddb { * @param *container_name Container name * @return The partition index */ - int32_t PartitionController::get_partition_index_of_container(const GSChar* container_name) { + int32_t PartitionController::get_partition_index_of_container( + const GSChar *container_name) { int32_t value; - GSResult ret = gsGetPartitionIndexOfContainer(mController, container_name, &value); + GSResult ret = gsGetPartitionIndexOfContainer(mController, + container_name, &value); // Check ret, if error, throw exception if (!GS_SUCCEEDED(ret)) { diff --git a/src/PartitionController.h b/src/PartitionController.h index 6945e3a..02c04fa 100644 --- a/src/PartitionController.h +++ b/src/PartitionController.h @@ -25,20 +25,21 @@ namespace griddb { class PartitionController { friend class Store; - private: - GSPartitionController *mController; - - public: - ~PartitionController(); - void close(); - 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); - int32_t get_partition_index_of_container(const GSChar *container_name); - - private: - PartitionController(GSPartitionController *controller); + private: + GSPartitionController *mController; + + public: + ~PartitionController(); + void close(); + 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); + int32_t get_partition_index_of_container(const GSChar *container_name); + + private: + explicit PartitionController(GSPartitionController *controller); }; } /* namespace griddb */ diff --git a/src/Query.cpp b/src/Query.cpp index c4166ff..eacbc9a 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -24,8 +24,10 @@ namespace griddb { * @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(GSQuery *query, GSContainerInfo *containerInfo, GSRow *gsRow) : + mQuery(query), + mContainerInfo(containerInfo), + mRow(gsRow) { } Query::~Query() { @@ -50,7 +52,7 @@ namespace griddb { RowSet* Query::fetch(bool for_update) { GSRowSet *gsRowSet; // Call method from C-Api. - GSBool gsForUpdate = (for_update == true ? GS_TRUE:GS_FALSE); + GSBool gsForUpdate = (for_update == true ? GS_TRUE : GS_FALSE); GSResult ret = gsFetch(mQuery, gsForUpdate, &gsRowSet); // Check ret, if error, throw exception @@ -59,9 +61,9 @@ namespace griddb { } try { - RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow); + RowSet *rowset = new RowSet(gsRowSet, mContainerInfo, mRow); return rowset; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseRowSet(&gsRowSet); throw GSException(mQuery, "Memory allocation error"); } @@ -81,9 +83,9 @@ namespace griddb { } try { - RowSet* rowset = new RowSet(gsRowSet, mContainerInfo, mRow); + RowSet *rowset = new RowSet(gsRowSet, mContainerInfo, mRow); return rowset; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseRowSet(&gsRowSet); throw GSException(mQuery, "Memory allocation error"); } @@ -101,15 +103,16 @@ namespace griddb { * @brief Set fetch limit option for a result acquisition. * @param limit The maximum number of Rows to be fetched. */ - void Query::set_fetch_options(int limit){ + void Query::set_fetch_options(int limit) { GSFetchOption fetchOption; GSResult ret; if (limit >= 0) { fetchOption = GS_FETCH_LIMIT; - ret = gsSetFetchOption(mQuery, fetchOption, &limit, GS_TYPE_INTEGER); + ret = gsSetFetchOption(mQuery, fetchOption, &limit, + GS_TYPE_INTEGER); if (!GS_SUCCEEDED(ret)) { throw GSException(mQuery, ret); } } } -} +} /* namespace griddb */ diff --git a/src/Query.h b/src/Query.h index da2406e..e7ba9a1 100644 --- a/src/Query.h +++ b/src/Query.h @@ -22,7 +22,6 @@ #include "gridstore.h" #include "RowSet.h" #include "GSException.h" -using namespace std; namespace griddb { @@ -32,24 +31,22 @@ namespace griddb { class Query { friend class Container; - private: - GSQuery *mQuery; - GSContainerInfo *mContainerInfo; - GSRow* mRow; - - public: - ~Query(); - void close(); - RowSet* fetch(bool for_update = false); - void set_fetch_options(int limit); - RowSet* get_row_set(); - GSQuery* gs_ptr(); - - private: - Query(GSQuery *query, GSContainerInfo *containerInfo, GSRow *gsRow); - + private: + GSQuery *mQuery; + GSContainerInfo *mContainerInfo; + GSRow *mRow; + + public: + ~Query(); + void close(); + RowSet* fetch(bool for_update = false); + void set_fetch_options(int limit); + RowSet* get_row_set(); + GSQuery* gs_ptr(); + + private: + Query(GSQuery *query, GSContainerInfo *containerInfo, GSRow *gsRow); }; - -} +} /* namespace griddb */ #endif /* _QUERY_H_ */ diff --git a/src/QueryAnalysisEntry.cpp b/src/QueryAnalysisEntry.cpp index daffdf0..cf3c384 100644 --- a/src/QueryAnalysisEntry.cpp +++ b/src/QueryAnalysisEntry.cpp @@ -24,7 +24,8 @@ 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) { + QueryAnalysisEntry::QueryAnalysisEntry(GSQueryAnalysisEntry *queryAnalysis) : + mQueryAnalysis(NULL) { if (!queryAnalysis) { return; } @@ -38,28 +39,30 @@ namespace griddb { mQueryAnalysis->type = NULL; mQueryAnalysis->value = NULL; mQueryAnalysis->valueType = NULL; - + if (queryAnalysis->statement) { - Util::strdup(&(mQueryAnalysis->statement), queryAnalysis->statement); + Util::strdup(&(mQueryAnalysis->statement), + queryAnalysis->statement); } - + if (queryAnalysis->type) { Util::strdup(&(mQueryAnalysis->type), queryAnalysis->type); } - + if (queryAnalysis->value) { Util::strdup(&(mQueryAnalysis->value), queryAnalysis->value); } if (queryAnalysis->valueType) { - Util::strdup(&(mQueryAnalysis->valueType), queryAnalysis->valueType); + Util::strdup(&(mQueryAnalysis->valueType), + queryAnalysis->valueType); } - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { this->freeMemory(); throw GSException(mQueryAnalysis, "Memory allocation error"); } - //Copy value which queryAnalysis point to + // Copy value which queryAnalysis point to mQueryAnalysis->id = queryAnalysis->id; mQueryAnalysis->depth = queryAnalysis->depth; } @@ -100,7 +103,7 @@ namespace griddb { * @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) { + void QueryAnalysisEntry::get(GSQueryAnalysisEntry *queryAnalysis) { assert(queryAnalysis != NULL); queryAnalysis->id = mQueryAnalysis->id; queryAnalysis->depth = mQueryAnalysis->depth; @@ -111,7 +114,8 @@ namespace griddb { try { if (mQueryAnalysis->statement) { - Util::strdup(&(queryAnalysis->statement), mQueryAnalysis->statement); + Util::strdup(&(queryAnalysis->statement), + mQueryAnalysis->statement); } if (mQueryAnalysis->type) { @@ -123,9 +127,10 @@ namespace griddb { } if (mQueryAnalysis->valueType) { - Util::strdup(&(queryAnalysis->valueType), mQueryAnalysis->valueType); + Util::strdup(&(queryAnalysis->valueType), + mQueryAnalysis->valueType); } - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { if (queryAnalysis->statement) { delete[] queryAnalysis->statement; } @@ -141,4 +146,4 @@ namespace griddb { throw GSException(mQueryAnalysis, "Memory allocation error"); } } -} +} /* namespace griddb */ diff --git a/src/QueryAnalysisEntry.h b/src/QueryAnalysisEntry.h index 107839b..d6769d3 100644 --- a/src/QueryAnalysisEntry.h +++ b/src/QueryAnalysisEntry.h @@ -24,23 +24,20 @@ #include "GSException.h" #include "Util.h" -using namespace std; - namespace griddb { class QueryAnalysisEntry { - private: - GSQueryAnalysisEntry* mQueryAnalysis; - void freeMemory(); - - public: - QueryAnalysisEntry(GSQueryAnalysisEntry* queryAnalysis); - ~QueryAnalysisEntry(); - void close(); - void get(GSQueryAnalysisEntry* queryAnalysis); - + private: + GSQueryAnalysisEntry *mQueryAnalysis; + void freeMemory(); + + public: + explicit QueryAnalysisEntry(GSQueryAnalysisEntry *queryAnalysis); + ~QueryAnalysisEntry(); + void close(); + void get(GSQueryAnalysisEntry *queryAnalysis); }; +} /* namespace griddb */ -} #endif /* SRC_QUERYANALYSISENTRY_H_ */ diff --git a/src/RowKeyPredicate.cpp b/src/RowKeyPredicate.cpp index 2370426..122a4bf 100644 --- a/src/RowKeyPredicate.cpp +++ b/src/RowKeyPredicate.cpp @@ -23,8 +23,10 @@ namespace griddb { * @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){ + RowKeyPredicate::RowKeyPredicate(GSRowKeyPredicate *predicate, GSType type) : + mPredicate(predicate), + mType(type), + timestamp_output_with_float(false) { } /** @@ -57,11 +59,13 @@ namespace griddb { * @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) { + 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 + // For all versions which do not support GS_TYPE_NULL + startField->type = -1; + // For all versions which do not support GS_TYPE_NULL + finishField->type = -1; GSType key_type = get_key_type(); const GSValue *startKey = NULL; const GSValue *endKey = NULL; @@ -74,9 +78,11 @@ namespace griddb { if (startField->type == GS_TYPE_STRING) { if (startKey->asString) { try { - Util::strdup(&(startField->value.asString), startKey->asString); - } catch (bad_alloc& ba) { - throw GSException(mPredicate, "Memory allocation error"); + Util::strdup(&(startField->value.asString), + startKey->asString); + } catch (std::bad_alloc &ba) { + throw GSException(mPredicate, + "Memory allocation error"); } } else { startField->value.asString = NULL; @@ -87,7 +93,8 @@ namespace griddb { } ret = gsGetPredicateFinishKeyGeneral(mPredicate, &endKey); if (!GS_SUCCEEDED(ret)) { - if (startField->type == GS_TYPE_STRING && startField->value.asString) { + if (startField->type == GS_TYPE_STRING + && startField->value.asString) { delete[] startField->value.asString; } throw GSException(mPredicate, ret); @@ -97,12 +104,15 @@ namespace griddb { if (finishField->type == GS_TYPE_STRING) { if (endKey->asString) { try { - Util::strdup(&(finishField->value.asString), endKey->asString); - } catch (bad_alloc& ba) { - if (startField->type == GS_TYPE_STRING && startField->value.asString) { + Util::strdup(&(finishField->value.asString), + endKey->asString); + } catch (std::bad_alloc &ba) { + if (startField->type == GS_TYPE_STRING + && startField->value.asString) { delete[] startField->value.asString; } - throw GSException(mPredicate, "Memory allocation error"); + throw GSException(mPredicate, + "Memory allocation error"); } } else { finishField->value.asString = NULL; @@ -118,97 +128,63 @@ namespace griddb { * @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) { + 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 (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - ret = gsSetPredicateFinishKeyByLong(mPredicate, (int64_t *) &finishKey->value.asLong); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - break; - case GS_TYPE_INTEGER: - ret = gsSetPredicateStartKeyByInteger(mPredicate, (const int32_t *) &startKey->value.asInteger); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - ret = gsSetPredicateFinishKeyByInteger(mPredicate, (const int32_t *)&finishKey->value.asInteger); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - break; - case GS_TYPE_STRING: - ret = gsSetPredicateStartKeyByString(mPredicate, startKey->value.asString); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - ret = gsSetPredicateFinishKeyByString(mPredicate, finishKey->value.asString); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - break; - case GS_TYPE_TIMESTAMP: - ret = gsSetPredicateStartKeyByTimestamp(mPredicate, - (const GSTimestamp *) &(startKey->value.asTimestamp)); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - ret = gsSetPredicateFinishKeyByTimestamp(mPredicate, - (const GSTimestamp *) &(finishKey->value.asTimestamp)); - if (!GS_SUCCEEDED(ret)) { - throw GSException(mPredicate, ret); - } - break; - default: - throw GSException(mPredicate, "Not support type"); - break; - } - } - - /** - * @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); + ret = gsSetPredicateStartKeyByLong( + mPredicate, + reinterpret_cast(&startKey->value.asLong)); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByLong( + mPredicate, + reinterpret_cast(&finishKey->value.asLong)); if (!GS_SUCCEEDED(ret)) { throw GSException(mPredicate, ret); } break; case GS_TYPE_INTEGER: - ret = gsAddPredicateKeyByInteger(mPredicate, - key->value.asInteger); + ret = gsSetPredicateStartKeyByInteger( + mPredicate, + (const int32_t*) &startKey->value.asInteger); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByInteger( + mPredicate, + (const int32_t*) &finishKey->value.asInteger); if (!GS_SUCCEEDED(ret)) { throw GSException(mPredicate, ret); } break; case GS_TYPE_STRING: - ret = gsAddPredicateKeyByString(mPredicate, key->value.asString); + ret = gsSetPredicateStartKeyByString(mPredicate, + startKey->value.asString); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByString( + mPredicate, finishKey->value.asString); if (!GS_SUCCEEDED(ret)) { throw GSException(mPredicate, ret); } - break; case GS_TYPE_TIMESTAMP: - ret = gsAddPredicateKeyByTimestamp(mPredicate, - key->value.asTimestamp); + ret = gsSetPredicateStartKeyByTimestamp( + mPredicate, + (const GSTimestamp*) &(startKey->value.asTimestamp)); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + ret = gsSetPredicateFinishKeyByTimestamp( + mPredicate, + (const GSTimestamp*) &(finishKey->value.asTimestamp)); if (!GS_SUCCEEDED(ret)) { throw GSException(mPredicate, ret); } @@ -216,6 +192,55 @@ namespace griddb { default: throw GSException(mPredicate, "Not support type"); break; + } + } + + /** + * @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 (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_INTEGER: + ret = gsAddPredicateKeyByInteger(mPredicate, + key->value.asInteger); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + case GS_TYPE_STRING: + ret = gsAddPredicateKeyByString(mPredicate, + key->value.asString); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + + break; + case GS_TYPE_TIMESTAMP: + ret = gsAddPredicateKeyByTimestamp(mPredicate, + key->value.asTimestamp); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mPredicate, ret); + } + break; + default: + throw GSException(mPredicate, "Not support type"); + break; } } } @@ -225,42 +250,45 @@ namespace griddb { * @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) { + 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); + GSValue *keyList; + GSResult ret = gsGetPredicateDistinctKeysGeneral( + mPredicate, (const GSValue**) &keyList, &size); if (!GS_SUCCEEDED(ret)) { throw GSException(mPredicate, ret); } *keyCount = size; - Field* keyFields; + Field *keyFields; try { - keyFields = new Field[size](); //will be free in typemap out + 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; + 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; } } *keys = keyFields; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { if (keyFields) { for (int i = 0; i < size; i++) { - if (keyFields[i].type == GS_TYPE_STRING && keyFields[i].value.asString) { + if (keyFields[i].type == GS_TYPE_STRING + && keyFields[i].value.asString) { delete[] keyFields[i].value.asString; } } @@ -269,7 +297,6 @@ namespace griddb { throw GSException(mPredicate, "Memory allocation error"); } - } /** diff --git a/src/RowKeyPredicate.h b/src/RowKeyPredicate.h index 0134a17..bcae4e9 100644 --- a/src/RowKeyPredicate.h +++ b/src/RowKeyPredicate.h @@ -17,18 +17,16 @@ #ifndef _ROWKEYPREDICATE_H_ #define _ROWKEYPREDICATE_H_ -#include -#include #include #include +#include +#include #include "gridstore.h" #include "Field.h" #include "GSException.h" #include "Util.h" -using namespace std; - namespace griddb { class RowKeyPredicate { @@ -37,21 +35,20 @@ class RowKeyPredicate { friend class Store; - public: - bool timestamp_output_with_float; - ~RowKeyPredicate(); - void close(); - - void get_range(Field* startField, Field* finishField); - void set_range(Field* startKey, Field* finishKey); - void set_distinct_keys(const Field *keys, size_t keyCount); - void get_distinct_keys(Field **keys, size_t* keyCount); - GSRowKeyPredicate* gs_ptr(); - GSType get_key_type(); + public: + bool timestamp_output_with_float; + ~RowKeyPredicate(); + void close(); - private: - RowKeyPredicate(GSRowKeyPredicate *predicate, GSType type); + void get_range(Field *startField, Field *finishField); + void set_range(Field *startKey, Field *finishKey); + void set_distinct_keys(const Field *keys, size_t keyCount); + void get_distinct_keys(Field **keys, size_t *keyCount); + GSRowKeyPredicate* gs_ptr(); + GSType get_key_type(); + private: + RowKeyPredicate(GSRowKeyPredicate *predicate, GSType type); }; } /* namespace griddb */ diff --git a/src/RowSet.cpp b/src/RowSet.cpp index b0ce22e..f31ec2d 100644 --- a/src/RowSet.cpp +++ b/src/RowSet.cpp @@ -24,9 +24,13 @@ namespace griddb { * @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) { + RowSet::RowSet(GSRowSet *rowSet, GSContainerInfo *containerInfo, + GSRow *gsRow) : + mRowSet(rowSet), + mContainerInfo(containerInfo), + mRow(gsRow), + timestamp_output_with_float(false), + typeList(NULL) { if (mRowSet != NULL) { mType = gsGetRowSetType(mRowSet); } else { @@ -41,13 +45,13 @@ namespace griddb { bool RowSet::has_next() { GSRowSetType type; type = this->type(); - switch(type) { - case (GS_ROW_SET_CONTAINER_ROWS): - case (GS_ROW_SET_AGGREGATION_RESULT): - case (GS_ROW_SET_QUERY_ANALYSIS): - return (bool) gsHasNextRow(mRowSet); - default: - return false; + switch (type) { + case (GS_ROW_SET_CONTAINER_ROWS): + case (GS_ROW_SET_AGGREGATION_RESULT): + case (GS_ROW_SET_QUERY_ANALYSIS): + return static_cast(gsHasNextRow(mRowSet)); + default: + return false; } } @@ -72,7 +76,7 @@ namespace griddb { * @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) { + void RowSet::update(GSRow *row) { GSResult ret = gsUpdateCurrentRow(mRowSet, mRow); if (!GS_SUCCEEDED(ret)) { @@ -84,7 +88,7 @@ namespace griddb { * @brief Get next row data. * @param *hasNextRow Indicate whether there is any row in RowSet or not */ - void RowSet::next_row(bool* hasNextRow) { + void RowSet::next_row(bool *hasNextRow) { *hasNextRow = this->has_next(); if (*hasNextRow) { GSResult ret = gsGetNextRow(mRowSet, mRow); @@ -101,27 +105,28 @@ namespace griddb { * @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){ + 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): - this->next_row(hasNextRow); - break; - case (GS_ROW_SET_AGGREGATION_RESULT): - *hasNextRow = this->has_next(); - *aggResult = this->get_next_aggregation(); - break; - case (GS_ROW_SET_QUERY_ANALYSIS): - *queryAnalysis = this->get_next_query_analysis(); - *hasNextRow = true; - break; - default: - throw GSException(mRowSet, "type for rowset is not correct"); + switch (*type) { + case (GS_ROW_SET_CONTAINER_ROWS): + this->next_row(hasNextRow); + break; + case (GS_ROW_SET_AGGREGATION_RESULT): + *hasNextRow = this->has_next(); + *aggResult = this->get_next_aggregation(); + break; + case (GS_ROW_SET_QUERY_ANALYSIS): + *queryAnalysis = this->get_next_query_analysis(); + *hasNextRow = true; + break; + default: + throw GSException(mRowSet, "type for rowset is not correct"); } } @@ -148,7 +153,7 @@ namespace griddb { * @return A pointer Stores the result of an aggregation operation. */ AggregationResult* RowSet::get_next_aggregation() { - GSAggregationResult* pAggResult; + GSAggregationResult *pAggResult; GSResult ret = gsGetNextAggregation(mRowSet, &pAggResult); if (!GS_SUCCEEDED(ret)) { @@ -156,9 +161,9 @@ namespace griddb { } try { - AggregationResult* aggResult = new AggregationResult(pAggResult); + AggregationResult *aggResult = new AggregationResult(pAggResult); return aggResult; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseAggregationResult(&pAggResult); throw GSException(mRowSet, "Memory allocation error"); } @@ -168,7 +173,7 @@ namespace griddb { * @brief Get current row type. * @return The type of content that can be extracted from GSRowSet. */ - GSRowSetType RowSet::type(){ + GSRowSetType RowSet::type() { return mType; } @@ -176,8 +181,9 @@ namespace griddb { * @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 gsQueryAnalysis = GS_QUERY_ANALYSIS_ENTRY_INITIALIZER; + QueryAnalysisEntry* RowSet::get_next_query_analysis() { + GSQueryAnalysisEntry gsQueryAnalysis = + GS_QUERY_ANALYSIS_ENTRY_INITIALIZER; GSResult ret; ret = gsGetNextQueryAnalysis(mRowSet, &gsQueryAnalysis); if (!GS_SUCCEEDED(ret)) { @@ -185,9 +191,10 @@ namespace griddb { } try { - QueryAnalysisEntry* queryAnalysis = new QueryAnalysisEntry(&gsQueryAnalysis); + QueryAnalysisEntry *queryAnalysis = new QueryAnalysisEntry( + &gsQueryAnalysis); return queryAnalysis; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException(mRowSet, "Memory allocation error"); } } @@ -197,26 +204,27 @@ namespace griddb { * @param ***listName List name of column * @param *num Number of column */ - void RowSet::get_column_names(char*** listName, int* num){ + void RowSet::get_column_names(char ***listName, int *num) { assert(listName != NULL); assert(num != NULL); - if (!mContainerInfo){ + if (!mContainerInfo) { return; } - //Memory will be free from typemap + // Memory will be free from typemap try { (*listName) = new char*[mContainerInfo->columnCount](); *num = mContainerInfo->columnCount; - for (int i = 0; i < mContainerInfo->columnCount; i++){ + for (int i = 0; i < mContainerInfo->columnCount; i++) { if (mContainerInfo->columnInfoList[i].name) { - Util::strdup((const GSChar**)(&((*listName)[i])), 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++){ + } catch (std::bad_alloc &ba) { + for (int i = 0; i < mContainerInfo->columnCount; i++) { if ((*listName)[i]) { delete[] (*listName)[i]; } @@ -232,15 +240,15 @@ namespace griddb { * @brief Get list type of column in row * @return A list type of column in row */ - GSType* RowSet::getGSTypeList(){ + GSType* RowSet::getGSTypeList() { if (typeList == NULL) { try { typeList = new GSType[mContainerInfo->columnCount](); - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException(mRowSet, "Memory allocation error"); } - - for (int i = 0; i < mContainerInfo->columnCount; i++){ + + for (int i = 0; i < mContainerInfo->columnCount; i++) { typeList[i] = mContainerInfo->columnInfoList[i].type; } } @@ -251,7 +259,7 @@ namespace griddb { * @brief Get number of column in row * @return Number of column in row */ - int RowSet::getColumnCount(){ + int RowSet::getColumnCount() { return mContainerInfo->columnCount; } @@ -259,8 +267,8 @@ namespace griddb { * @brief Get row data in RowSet object * @return A pointer stores row data in RowSet object */ - GSRow* RowSet::getGSRowPtr(){ + GSRow* RowSet::getGSRowPtr() { return mRow; } -} +} /* namespace griddb */ diff --git a/src/RowSet.h b/src/RowSet.h index 9dad3d8..57053ff 100644 --- a/src/RowSet.h +++ b/src/RowSet.h @@ -17,11 +17,11 @@ #ifndef _ROWSET_H_ #define _ROWSET_H_ -#include -#include #include #include #include +#include +#include #include "gridstore.h" #include "Field.h" @@ -30,8 +30,6 @@ #include "GSException.h" #include "Util.h" -using namespace std; - namespace griddb { /** @@ -41,37 +39,37 @@ class RowSet { GSRowSet *mRowSet; GSContainerInfo *mContainerInfo; GSRow *mRow; - GSType* typeList; + GSType *typeList; friend class Query; GSRowSetType mType; - public: - bool timestamp_output_with_float; - ~RowSet(); - void close(); - int32_t size(); - // Iterator - bool has_next(); - void next(GSRowSetType* type, bool* hasNextRow, - QueryAnalysisEntry** queryAnalysis, AggregationResult** aggResult); - void update(GSRow* row); - void remove(); - GSRowSetType type(); - void get_column_names(char*** listName, int* num); - QueryAnalysisEntry* get_next_query_analysis(); - AggregationResult* get_next_aggregation(); - void next_row(bool* hasNextRow); - GSType* getGSTypeList(); - int getColumnCount(); - - GSRow* getGSRowPtr(); - - private: - RowSet(GSRowSet *rowSet, GSContainerInfo *containerInfo, GSRow *mRow); + public: + bool timestamp_output_with_float; + ~RowSet(); + void close(); + int32_t size(); + // Iterator + bool has_next(); + void next(GSRowSetType *type, bool *hasNextRow, + QueryAnalysisEntry **queryAnalysis, + AggregationResult **aggResult); + void update(GSRow *row); + void remove(); + GSRowSetType type(); + void get_column_names(char ***listName, int *num); + QueryAnalysisEntry* get_next_query_analysis(); + AggregationResult* get_next_aggregation(); + void next_row(bool *hasNextRow); + GSType* getGSTypeList(); + int getColumnCount(); + + GSRow* getGSRowPtr(); + + private: + RowSet(GSRowSet *rowSet, GSContainerInfo *containerInfo, GSRow *mRow); }; - -} +} /* namespace griddb */ #endif /* _ROWSET_H_ */ diff --git a/src/Store.cpp b/src/Store.cpp index b6660ba..99a031c 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -22,11 +22,14 @@ 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(GSGridStore *store) : + mStore(store), + timestamp_output_with_float(false) { } Store::~Store() { - // allRelated = FALSE, since all container object is managed by Container class + // allRelated = FALSE, + // since all container object is managed by Container class close(GS_FALSE); } @@ -45,7 +48,7 @@ namespace griddb { * @brief Delete container with specified name * @param *name Container name */ - void Store::drop_container(const char* name) { + void Store::drop_container(const char *name) { GSResult ret = gsDropContainer(mStore, name); if (!GS_SUCCEEDED(ret)) { throw GSException(mStore, ret); @@ -57,10 +60,11 @@ namespace griddb { * @param *name Container name * @return Return a pointer which stores all information of container */ - ContainerInfo* Store::get_container_info(const char* name) { + ContainerInfo* Store::get_container_info(const char *name) { GSContainerInfo gsContainerInfo = GS_CONTAINER_INFO_INITIALIZER; GSChar bExists; - GSResult ret = gsGetContainerInfo(mStore, name, &gsContainerInfo, &bExists); + GSResult ret = gsGetContainerInfo(mStore, name, &gsContainerInfo, + &bExists); if (!GS_SUCCEEDED(ret)) { throw GSException(mStore, ret); } @@ -69,9 +73,9 @@ namespace griddb { } try { - ContainerInfo* containerInfo = new ContainerInfo(&gsContainerInfo); + ContainerInfo *containerInfo = new ContainerInfo(&gsContainerInfo); return containerInfo; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException(mStore, "Memory allocation error"); } } @@ -82,24 +86,26 @@ namespace griddb { * @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) { + 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"); + 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; + GSContainerInfo *gsInfo = info->gs_info(); + GSContainer *pContainer = NULL; // Create new gsContainer - GSResult ret = gsPutContainerGeneral(mStore, gsInfo->name, gsInfo, modifiable, &pContainer); + GSResult ret = gsPutContainerGeneral(mStore, gsInfo->name, gsInfo, + modifiable, &pContainer); if (!GS_SUCCEEDED(ret)) { throw GSException(mStore, ret); } try { - Container* container = new Container(pContainer, gsInfo); + Container *container = new Container(pContainer, gsInfo); return container; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseContainer(&pContainer, GS_FALSE); throw GSException(mStore, "Memory allocation error"); } @@ -110,14 +116,14 @@ namespace griddb { * @param *name Container name * @return The pointer to a pointer variable to store Container instance */ - Container* Store::get_container(const char* name) { - GSContainer* pContainer; + Container* Store::get_container(const char *name) { + GSContainer *pContainer; GSResult ret = gsGetContainerGeneral(mStore, name, &pContainer); if (!GS_SUCCEEDED(ret)) { throw GSException(mStore, ret); } if (pContainer == NULL) { - //If not found container, return NULL in target language + // If not found container, return NULL in target language return NULL; } GSContainerInfo containerInfo = GS_CONTAINER_INFO_INITIALIZER; @@ -128,9 +134,9 @@ namespace griddb { throw GSException(mStore, ret); } try { - Container* container = new Container(pContainer, &containerInfo); + Container *container = new Container(pContainer, &containerInfo); return container; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseContainer(&pContainer, GS_FALSE); throw GSException(mStore, "Memory allocation error"); } @@ -141,7 +147,7 @@ namespace griddb { * @param **queryList A list of query * @param queryCount Number of element in query list */ - void Store::fetch_all(GSQuery* const* queryList, size_t queryCount) { + void Store::fetch_all(GSQuery *const*queryList, size_t queryCount) { GSResult ret = gsFetchAll(mStore, queryList, queryCount); if (!GS_SUCCEEDED(ret)) { throw GSException(mStore, ret); @@ -153,7 +159,7 @@ namespace griddb { * @return The pointer to a pointer variable to store PartitionController instance */ PartitionController* Store::partition_info() { - GSPartitionController* partitionController; + GSPartitionController *partitionController; GSResult ret = gsGetPartitionController(mStore, &partitionController); @@ -162,9 +168,10 @@ namespace griddb { } try { - PartitionController* partition = new PartitionController(partitionController); + PartitionController *partition = new PartitionController( + partitionController); return partition; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsClosePartitionController(&partitionController); throw GSException(mStore, "Memory allocation error"); } @@ -176,7 +183,7 @@ namespace griddb { * @return The pointer to a pointer variable to store RowKeyPredicate instance */ RowKeyPredicate* Store::create_row_key_predicate(GSType type) { - GSRowKeyPredicate* predicate; + GSRowKeyPredicate *predicate; GSResult ret = gsCreateRowKeyPredicate(mStore, type, &predicate); @@ -185,9 +192,10 @@ namespace griddb { } try { - RowKeyPredicate* rowKeyPredicate = new RowKeyPredicate(predicate, type); + RowKeyPredicate *rowKeyPredicate = new RowKeyPredicate(predicate, + type); return rowKeyPredicate; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseRowKeyPredicate(&predicate); throw GSException(mStore, "Memory allocation error"); } @@ -200,19 +208,20 @@ namespace griddb { * @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) { + 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 *entryList; + try { entryList = new GSContainerRowEntry[containerCount](); - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { throw GSException(mStore, "Memory allocation error"); } - for (int i= 0; i < containerCount; i++) { + for (int i = 0; i < containerCount; i++) { entryList[i].containerName = listContainerName[i]; entryList[i].rowCount = listRowContainerCount[i]; entryList[i].rowList = (void* const*) listRow[i]; @@ -234,9 +243,11 @@ namespace griddb { * @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) { + 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); @@ -247,37 +258,44 @@ namespace griddb { *typeList = NULL; *orderFromInput = NULL; *containerCount = 0; - int length = (int) predicateCount; + int length = static_cast(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); + *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 (std::bad_alloc &ba) { + this->freeMemoryMultiGet(colNumList, typeList, length, + orderFromInput); throw GSException(mStore, "Memory allocation error"); } - bool setNumList = this->setMultiContainerNumList(predicateList, - length, &colNumList, &typeList); + bool setNumList = this->setMultiContainerNumList(predicateList, length, + &colNumList, + &typeList); if (!setNumList) { - this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput); - throw GSException(mStore, "Set multi containers number list and type list error"); + 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); + GSResult ret = gsGetMultipleContainerRows( + mStore, predicateList, predicateCount, + (const GSContainerRowEntry**) entryList, containerCount); if (!GS_SUCCEEDED(ret)) { - this->freeMemoryMultiGet(colNumList, typeList, length, orderFromInput); + this->freeMemoryMultiGet(colNumList, typeList, length, + orderFromInput); throw GSException(mStore, ret); } // set data for orderFromInput for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { - if (strcmp((*predicateList)[i].containerName, (*entryList)[j].containerName) == 0){ + if (strcmp((*predicateList)[i].containerName, + (*entryList)[j].containerName) == 0) { (*orderFromInput)[i] = j; } } @@ -287,10 +305,10 @@ namespace griddb { /** * Support free memory in multi_get function when exception happen */ - void Store::freeMemoryMultiGet(int **colNumList, GSType*** typeList, - int length, int **orderFromInput) { + void Store::freeMemoryMultiGet(int **colNumList, GSType ***typeList, + int length, int **orderFromInput) { if (*colNumList) { - delete [] *colNumList; + delete[] *colNumList; *colNumList = NULL; } @@ -300,11 +318,11 @@ namespace griddb { delete[] (*typeList)[i]; } } - delete [] *typeList; + delete[] *typeList; *typeList = NULL; } if (*orderFromInput) { - delete [] *orderFromInput; + delete[] *orderFromInput; *orderFromInput = NULL; } } @@ -312,12 +330,14 @@ namespace griddb { /** * Support multi_get function to put data into colNumList and typeList */ - bool Store::setMultiContainerNumList(const GSRowKeyPredicateEntry* const * predicateList, - int length, int ***colNumList, GSType**** typeList) { + bool Store::setMultiContainerNumList( + const GSRowKeyPredicateEntry *const*predicateList, int length, + int ***colNumList, GSType ****typeList) { for (int i = 0; i < length; i++) { Container *tmpContainer; try { - tmpContainer = this->get_container((*predicateList)[i].containerName); + tmpContainer = this->get_container( + (*predicateList)[i].containerName); } catch (GSException e) { return false; } @@ -327,13 +347,14 @@ namespace griddb { (**colNumList)[i] = tmpContainer->getColumnCount(); try { - //(**typeList)[i] will be freed in freeMemoryMultiGet() function or argout + // (**typeList)[i] will be freed in freeMemoryMultiGet() + // function or argout (**typeList)[i] = new GSType[(**colNumList)[i]](); - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { delete tmpContainer; return false; } - + for (int j = 0; j < (**colNumList)[i]; j++) { (**typeList)[i][j] = tmpContainer->getGSTypeList()[j]; } @@ -341,5 +362,4 @@ namespace griddb { } return true; } - -} +} /* namespace griddb */ diff --git a/src/Store.h b/src/Store.h index 7de25c6..44ecea7 100644 --- a/src/Store.h +++ b/src/Store.h @@ -17,9 +17,9 @@ #ifndef _STORE_H_ #define _STORE_H_ +#include #include #include -#include #include "ContainerInfo.h" #include "Container.h" @@ -27,8 +27,6 @@ #include "RowKeyPredicate.h" #include "GSException.h" -using namespace std; - namespace griddb { class Store { @@ -36,33 +34,36 @@ class Store { friend class StoreFactory; - public: - bool timestamp_output_with_float; - ~Store(); - void close(GSBool allRelated = GS_FALSE); - - Container* put_container(ContainerInfo* info, bool modifiable = false); - Container* get_container(const char* name); - void drop_container(const char *name); - - void fetch_all(GSQuery* const * queryList, size_t queryCount); - void multi_put(GSRow*** listRow, const int *listRowContainerCount, - const char ** listContainerName, size_t containerCount); - void multi_get(const GSRowKeyPredicateEntry* const * predicateList, - size_t predicateCount, GSContainerRowEntry **entryList, size_t* containerCount, - int **colNumList, GSType*** typeList, int **orderFromInput); - - ContainerInfo* get_container_info(const char *name); - PartitionController* partition_info(); - RowKeyPredicate* create_row_key_predicate(GSType type); - - private: - Store(GSGridStore* store); - void freeMemoryMultiGet(int** colNumList, GSType*** typeList, int length, int** orderFromInput); - bool setMultiContainerNumList(const GSRowKeyPredicateEntry* const * predicateList, - int length, int*** colNumList, GSType**** typeList); + public: + bool timestamp_output_with_float; + ~Store(); + void close(GSBool allRelated = GS_FALSE); + + Container* put_container(ContainerInfo *info, bool modifiable = false); + Container* get_container(const char *name); + void drop_container(const char *name); + + void fetch_all(GSQuery *const*queryList, size_t queryCount); + void multi_put(GSRow ***listRow, const int *listRowContainerCount, + const char **listContainerName, size_t containerCount); + void multi_get(const GSRowKeyPredicateEntry *const*predicateList, + size_t predicateCount, GSContainerRowEntry **entryList, + size_t *containerCount, int **colNumList, GSType ***typeList, + int **orderFromInput); + + ContainerInfo* get_container_info(const char *name); + PartitionController* partition_info(); + RowKeyPredicate* create_row_key_predicate(GSType type); + + private: + explicit Store(GSGridStore *store); + void freeMemoryMultiGet(int **colNumList, GSType ***typeList, int length, + int **orderFromInput); + bool setMultiContainerNumList( + const GSRowKeyPredicateEntry *const*predicateList, int length, + int ***colNumList, GSType ****typeList); }; -} +} /* namespace griddb */ #endif /* Define _STORE_H */ diff --git a/src/StoreFactory.cpp b/src/StoreFactory.cpp index 617e99f..8f3dde3 100644 --- a/src/StoreFactory.cpp +++ b/src/StoreFactory.cpp @@ -20,11 +20,12 @@ namespace griddb { - StoreFactory::StoreFactory() : mFactory(NULL) { + StoreFactory::StoreFactory() : + mFactory(NULL) { } StoreFactory::~StoreFactory() { - //allRelated = FALSE, since Gridstore object is managed by Store class + // allRelated = FALSE, since Gridstore object is managed by Store class close(GS_FALSE); } @@ -43,14 +44,14 @@ namespace griddb { * @return The pointer to a pointer variable to store StoreFactory instance */ StoreFactory* StoreFactory::get_instance() { - GSGridStoreFactory* pFactory = gsGetDefaultFactory(); + GSGridStoreFactory *pFactory = gsGetDefaultFactory(); try { - StoreFactory* factory(new StoreFactory()); + StoreFactory *factory(new StoreFactory()); factory->set_factory(pFactory); return factory; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseFactory(&pFactory, GS_FALSE); throw GSException("Memory allocation error"); } @@ -59,7 +60,8 @@ namespace griddb { /* * set GSPropertyEntry */ - void StoreFactory::set_property_entry(GSPropertyEntry *prop, const char* name, const char* value) { + void StoreFactory::set_property_entry(GSPropertyEntry *prop, + const char *name, const char *value) { prop->name = name; prop->value = value; } @@ -67,16 +69,17 @@ namespace griddb { /* * Check whether in MULTICAST mode */ - bool StoreFactory::check_multicast(const char* address) { + bool StoreFactory::check_multicast(const char *address) { if (address && address[0] != '\0') { - char* tmp; + char *tmp; + char *savePtr; try { - Util::strdup((const GSChar**)&tmp, address); - } catch (bad_alloc& ba) { + Util::strdup((const GSChar**) &tmp, address); + } catch (std::bad_alloc &ba) { throw GSException("Memory allocation error"); } - char *octets = strtok((char*)tmp, "."); + char *octets = strtok_r(tmp, ".", &savePtr); if (octets) { int firstOctet = atoi(octets); int first4Bits = firstOctet >> 4 & 0x0f; @@ -102,16 +105,20 @@ namespace griddb { * @param *notification_provider A URL of address provider * @return The pointer to a pointer variable to store Store instance */ - Store* StoreFactory::get_store(const char* host, int32_t port, const char* cluster_name, - const char* database, const char* user, const char* password, - const char* notification_member, const char* notification_provider) { + Store* StoreFactory::get_store(const char *host, int32_t port, + const char *cluster_name, + const char *database, const char *user, + const char *password, + const char *notification_member, + const char *notification_provider) { size_t index = 0; - GSPropertyEntry local_props[MAX_PROPS] = {0}; - std::string lport = std::to_string((long long int)port); + GSPropertyEntry local_props[MAX_PROPS] = { 0 }; + std::string lport = std::to_string(port); if (check_multicast(host)) { set_property_entry(&local_props[0], "notificationAddress", host); - set_property_entry(&local_props[1], "notificationPort", lport.c_str()); + set_property_entry(&local_props[1], "notificationPort", + lport.c_str()); index += 2; } else if (host && host[0] != '\0') { set_property_entry(&local_props[0], "host", host); @@ -120,15 +127,18 @@ namespace griddb { } if (notification_member && notification_member[0] != '\0') { - set_property_entry(&local_props[index], "notificationMember", notification_member); + set_property_entry(&local_props[index], "notificationMember", + notification_member); index++; } if (notification_provider && notification_provider[0] != '\0') { - set_property_entry(&local_props[index], "notificationProvider", notification_provider); + set_property_entry(&local_props[index], "notificationProvider", + notification_provider); index++; } if (cluster_name && cluster_name[0] != '\0') { - set_property_entry(&local_props[index], "clusterName", cluster_name); + set_property_entry(&local_props[index], "clusterName", + cluster_name); index++; } if (database && database[0] != '\0') { @@ -138,7 +148,6 @@ namespace griddb { if (user && user[0] != '\0') { set_property_entry(&local_props[index], "user", user); index++; - } if (password && password[0] != '\0') { set_property_entry(&local_props[index], "password", password); @@ -154,10 +163,10 @@ namespace griddb { } try { - //return new Store(store); - Store* store = new Store(gsStore); + // Return new Store(store); + Store *store = new Store(gsStore); return store; - } catch (bad_alloc& ba) { + } catch (std::bad_alloc &ba) { gsCloseGridStore(&gsStore, GS_FALSE); throw GSException(mFactory, "Memory allocation error"); } @@ -174,8 +183,7 @@ namespace griddb { /* * Set attribute: mFactory */ - void StoreFactory::set_factory(GSGridStoreFactory* factory) { + void StoreFactory::set_factory(GSGridStoreFactory *factory) { mFactory = factory; } - -} +} /* namespace griddb */ diff --git a/src/StoreFactory.h b/src/StoreFactory.h index 411e348..43b9760 100644 --- a/src/StoreFactory.h +++ b/src/StoreFactory.h @@ -26,8 +26,6 @@ #include "GSException.h" #include "Util.h" -using namespace std; - namespace griddb { /** @@ -35,25 +33,27 @@ namespace griddb { * This class is implemented as singleton. */ class StoreFactory { - private: - GSGridStoreFactory* mFactory; - - public: - ~StoreFactory(); - void close(GSBool allRelated = GS_FALSE); - static StoreFactory* get_instance(); - Store* get_store(const char* host, int32_t port, const char* cluster_name, - const char* database, const char* username, const char* password, - const char* notification_member, const char* notification_provider); - string get_version(); - - private: - StoreFactory(); - void set_property_entry(GSPropertyEntry *prop, const char* name, const char* value); - bool check_multicast(const char* address); - void set_factory(GSGridStoreFactory* factory); + private: + GSGridStoreFactory *mFactory; + + public: + ~StoreFactory(); + void close(GSBool allRelated = GS_FALSE); + static StoreFactory* get_instance(); + Store* get_store(const char *host, int32_t port, const char *cluster_name, + const char *database, const char *username, + const char *password, const char *notification_member, + const char *notification_provider); + string get_version(); + + private: + StoreFactory(); + void set_property_entry(GSPropertyEntry *prop, const char *name, + const char *value); + bool check_multicast(const char *address); + void set_factory(GSGridStoreFactory *factory); }; -} +} /* namespace griddb */ #endif diff --git a/src/TimeSeriesProperties.cpp b/src/TimeSeriesProperties.cpp index 0c05f50..98105c6 100644 --- a/src/TimeSeriesProperties.cpp +++ b/src/TimeSeriesProperties.cpp @@ -22,7 +22,9 @@ namespace griddb { * @brief Constructor a new TimeSeriesProperties::TimeSeriesProperties object * @param *timeSeriesProps Represents the information about optional configuration settings used for newly creating or updating a TimeSeries */ - TimeSeriesProperties::TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps) : mTsProps(*timeSeriesProps) { + TimeSeriesProperties::TimeSeriesProperties( + const GSTimeSeriesProperties *timeSeriesProps) : + mTsProps(*timeSeriesProps) { } /** @@ -31,9 +33,11 @@ namespace griddb { * @param timeUnit The unit of elapsed time referenced for the expiration date of a Row * @param ExpirationDivisionCount The division number for the validity period as the number of expired Row data units to be released */ - TimeSeriesProperties::TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, - int32_t ExpirationDivisionCount) : mTsProps{elapsedTime, timeUnit, -1, - timeUnit, GS_COMPRESSION_NO, 0, NULL, ExpirationDivisionCount} { + TimeSeriesProperties::TimeSeriesProperties(int32_t elapsedTime, + GSTimeUnit timeUnit, + int32_t ExpirationDivisionCount) : + mTsProps { elapsedTime, timeUnit, -1, timeUnit, GS_COMPRESSION_NO, + 0, NULL, ExpirationDivisionCount } { } TimeSeriesProperties::~TimeSeriesProperties() { @@ -44,7 +48,8 @@ namespace griddb { * @param elapsedTime The elapsed time period of a Row to be used as the basis of the validity period * @param timeUnit The unit of elapsed time referenced for the expiration date of a Row */ - void TimeSeriesProperties::set_row_expiration_time(int elapsedTime, GSTimeUnit timeUnit) { + void TimeSeriesProperties::set_row_expiration_time(int elapsedTime, + GSTimeUnit timeUnit) { mTsProps.rowExpirationTime = elapsedTime; mTsProps.rowExpirationTimeUnit = timeUnit; } diff --git a/src/TimeSeriesProperties.h b/src/TimeSeriesProperties.h index a44b051..da2c1e9 100644 --- a/src/TimeSeriesProperties.h +++ b/src/TimeSeriesProperties.h @@ -22,21 +22,24 @@ namespace griddb { class TimeSeriesProperties { - private: - GSTimeSeriesProperties mTsProps; - - public: - TimeSeriesProperties(const GSTimeSeriesProperties* timeSeriesProps); - TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, int32_t ExpirationDivisionCount); - ~TimeSeriesProperties(); - // APIs to set values for expiration_time and expiration_division_count - void set_row_expiration_time(int32_t elapsedTime, GSTimeUnit timeUnit); - void set_expiration_division_count(int32_t count); - // APIs to get values of expiration_time, expiration_time_unit, expiration_division_count and TimeSeriesProperties - int get_row_expiration_time(); - GSTimeUnit get_row_expiration_time_unit(); - int get_expiration_division_count(); - GSTimeSeriesProperties* gs_ptr(); + private: + GSTimeSeriesProperties mTsProps; + + public: + explicit TimeSeriesProperties( + const GSTimeSeriesProperties *timeSeriesProps); + TimeSeriesProperties(int32_t elapsedTime, GSTimeUnit timeUnit, + int32_t ExpirationDivisionCount); + ~TimeSeriesProperties(); + // APIs to set values for expiration_time and expiration_division_count + void set_row_expiration_time(int32_t elapsedTime, GSTimeUnit timeUnit); + void set_expiration_division_count(int32_t count); + // APIs to get values of expiration_time, expiration_time_unit, + // expiration_division_count and TimeSeriesProperties + int get_row_expiration_time(); + GSTimeUnit get_row_expiration_time_unit(); + int get_expiration_division_count(); + GSTimeSeriesProperties* gs_ptr(); }; } /* namespace griddb */ diff --git a/src/TimestampUtils.cpp b/src/TimestampUtils.cpp index f32bd1c..66371f0 100644 --- a/src/TimestampUtils.cpp +++ b/src/TimestampUtils.cpp @@ -27,7 +27,7 @@ namespace griddb { /** * Convert from PHP DateTime to GridDB timestamp */ - int64_t TimestampUtils::get_time_millis(int64_t timestamp){ + int64_t TimestampUtils::get_time_millis(int64_t timestamp) { return timestamp; } diff --git a/src/TimestampUtils.h b/src/TimestampUtils.h index ce71d7c..0a30806 100644 --- a/src/TimestampUtils.h +++ b/src/TimestampUtils.h @@ -16,20 +16,17 @@ #ifndef _TIMESTAMPUTILS_H_ #define _TIMESTAMPUTILS_H_ -#include "gridstore.h" #include +#include "gridstore.h" #include "GSException.h" -using namespace std; - namespace griddb { class TimestampUtils { - - public: - TimestampUtils(); - ~TimestampUtils(); - static int64_t get_time_millis(int64_t timestamp); + public: + TimestampUtils(); + ~TimestampUtils(); + static int64_t get_time_millis(int64_t timestamp); }; } /* namespace griddb */ diff --git a/src/Util.cpp b/src/Util.cpp index 8adacba..c002897 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -23,9 +23,9 @@ namespace griddb { * @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); + void Util::strdup(const GSChar **const to, const GSChar *from) { + GSChar *temp = new char[strlen(from) + 1](); + strncpy(temp, from, strlen(from)); *to = temp; } -} +} /* namespace griddb */ diff --git a/src/Util.h b/src/Util.h index 5217469..e57651e 100644 --- a/src/Util.h +++ b/src/Util.h @@ -20,15 +20,13 @@ #include #include "GSException.h" -using namespace std; - namespace griddb { class Util { - public: - static void strdup(const GSChar** const to, const GSChar* from); + public: + static void strdup(const GSChar **const to, const GSChar *from); }; } -#endif \ No newline at end of file +#endif diff --git a/src/griddb.i b/src/griddb.i index 20a11fc..8e05896 100644 --- a/src/griddb.i +++ b/src/griddb.i @@ -35,9 +35,9 @@ %include -//Mark these methods below return new object, need to be free by target language +// Mark these methods below return new object, need to be free by target language %feature("new") griddb::Container::query; -//%feature("new") griddb::ContainerInfo::get_time_series_properties; +// %feature("new") griddb::ContainerInfo::get_time_series_properties; %feature("new") griddb::Query::fetch; %feature("new") griddb::Query::get_row_set; %feature("new") griddb::RowSet::get_next_query_analysis; diff --git a/src/gstype.i b/src/gstype.i index 2c84eea..c3ab4bd 100644 --- a/src/gstype.i +++ b/src/gstype.i @@ -91,7 +91,6 @@ enum GSIndexTypeFlagTag { #endif enum GSFetchOptionTag { - GS_FETCH_LIMIT, #if GS_INTERNAL_DEFINITION_VISIBLE @@ -104,7 +103,6 @@ enum GSFetchOptionTag { #if !defined(SWIGGO) enum GSTimeUnitTag { - GS_TIME_UNIT_YEAR, GS_TIME_UNIT_MONTH, @@ -122,13 +120,11 @@ enum GSTimeUnitTag { #endif enum GSTypeOptionTag { - GS_TYPE_OPTION_KEY = 1 << 0, GS_TYPE_OPTION_NULLABLE = 1 << 1, GS_TYPE_OPTION_NOT_NULL = 1 << 2, - }; typedef int32_t GSTypeOption; From 7e220a3496d96e43852e3d7080d7da35baea1d35 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:48:15 +0900 Subject: [PATCH 13/22] update src using SWIG_exception() --- src/gstype_php.i | 165 ++++++++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 66 deletions(-) diff --git a/src/gstype_php.i b/src/gstype_php.i index 5202e66..c5ced4f 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -129,12 +129,13 @@ static void throwGSException(griddb::GSException* exception) { * "password " : str, "notificationMember" : str, "notificationProvider" : str) */ %typemap(in, numinputs = 1) -(const char* host, int32_t port, const char* cluster_name, const char* database, - const char* username, const char* password, - const char* notification_member, const char* notification_provider) + (const char* host, int32_t port, const char* cluster_name, + const char* database, const char* username, + const char* password, const char* notification_member, + const char* notification_provider) (HashTable *arr, HashPosition pos, zval *data) { if (Z_TYPE_P(&$input) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); + SWIG_exception(E_ERROR, "Expected associative array as input"); } arr = Z_ARRVAL_P(&$input); @@ -151,7 +152,7 @@ static void throwGSException(griddb::GSException* exception) { $8 = NULL; if (length == 0) { - SWIG_PHP_Error(E_ERROR, "Expect not empty array as input"); + SWIG_exception(E_ERROR, "Expected not empty array as input"); } zend_string *key; @@ -162,61 +163,61 @@ static void throwGSException(griddb::GSException* exception) { zend_hash_move_forward_ex(arr, &pos)) { if (zend_hash_get_current_key_ex(arr, &key, &index, &pos) != HASH_KEY_IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); + SWIG_exception(E_ERROR, "Expected string as input for key"); } name = ZSTR_VAL(key); if (strcmp(name, "host") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for host property"); } $1 = Z_STRVAL_P(data); } else if (strcmp(name, "port") == 0) { // Input valid is number only if (Z_TYPE_P(data) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected integer as" + SWIG_exception(E_ERROR, "Expected integer as" " input for port number property"); } $2 = Z_LVAL_P(data); } else if (strcmp(name, "clusterName") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for clusterName property"); } $3 = Z_STRVAL_P(data); } else if (strcmp(name, "database") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for database property"); } $4 = Z_STRVAL_P(data); } else if (strcmp(name, "username") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for username property"); } $5 = Z_STRVAL_P(data); } else if (strcmp(name, "password") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for password property"); } $6 = Z_STRVAL_P(data); } else if (strcmp(name, "notificationMember") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for notificationMember property"); } $7 = Z_STRVAL_P(data); } else if (strcmp(name, "notificationProvider") == 0) { if (Z_TYPE_P(data) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as" + SWIG_exception(E_ERROR, "Expected string as" " input for host notificationProvider property"); } $8 = Z_STRVAL_P(data); } else { - SWIG_PHP_Error(E_ERROR, "Invalid Property"); + SWIG_exception(E_ERROR, "Invalid Property"); } } } @@ -224,18 +225,19 @@ static void throwGSException(griddb::GSException* exception) { /** * Typemaps for ContainerInfo : support keyword parameter ("name" : str, * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, - * "expiration" : expiraion object) + * "expiration" : expiration object) */ -%typemap(in, numinputs = 1) (const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, bool row_key, - griddb::ExpirationInfo* expiration) +%typemap(in, numinputs = 1, fragment = "freeArgContainerInfo") + (const GSChar* name, const GSColumnInfo* props, int propsCount, + GSContainerType type, bool row_key, + griddb::ExpirationInfo* expiration) (HashTable *arrContainerInfo, HashPosition posContainerInfo, - zval *dataContainerInfo, HashTable *arrColumnInfoArray, - HashPosition posColumnInfoArray, zval *dataColumnInfoArray, - HashTable *arrColumnInfo, HashPosition posColumnInfo, - zval *columnName, zval *columnType) { + zval *dataContainerInfo, HashTable *arrColumnInfoArray, + HashPosition posColumnInfoArray, zval *dataColumnInfoArray, + HashTable *arrColumnInfo, HashPosition posColumnInfo, + zval *columnName, zval *columnType) { if (Z_TYPE_P(&$input) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected associative array as input"); + SWIG_exception(E_ERROR, "Expected associative array as input"); } char* name = 0; @@ -253,7 +255,7 @@ static void throwGSException(griddb::GSException* exception) { int sizeOfContainerInfo = zend_hash_num_elements(arrContainerInfo); if (sizeOfContainerInfo == 0) { - SWIG_PHP_Error(E_ERROR, "Expect not empty array as input" + SWIG_exception(E_ERROR, "Expected not empty array as input" " for ContainerInfo"); } @@ -264,20 +266,23 @@ static void throwGSException(griddb::GSException* exception) { (dataContainerInfo = zend_hash_get_current_data_ex(arrContainerInfo, &posContainerInfo)) != NULL; zend_hash_move_forward_ex(arrContainerInfo, &posContainerInfo)) { if (zend_hash_get_current_key_ex(arrContainerInfo, &key, &index, &posContainerInfo) != HASH_KEY_IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as input for key"); + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected string as input for key"); } name = ZSTR_VAL(key); if (strcmp(name, "name") == 0) { if (Z_TYPE_P(dataContainerInfo) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as input" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected string as input" " for name property"); } $1 = Z_STRVAL_P(dataContainerInfo); } else if (strcmp(name, "columnInfoArray") == 0) { // Input valid is array only if (Z_TYPE_P(dataContainerInfo) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array as input" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected array as input" " for columnInfo property"); } // Fetch the hash table from a zval @@ -285,11 +290,12 @@ static void throwGSException(griddb::GSException* exception) { int sizeOfColumnInfoArray = zend_hash_num_elements(arrColumnInfoArray); $3 = sizeOfColumnInfoArray; if ($3 == 0) { - SWIG_PHP_Error(E_ERROR, "Expect not empty array"); + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected not empty array"); } $2 = new GSColumnInfo[$3]; if ($2 == NULL) { - SWIG_PHP_Error(E_ERROR, "Memory allocation error"); + SWIG_exception(E_ERROR, "Memory allocation error"); } memset($2, 0x0, $3*sizeof(GSColumnInfo)); @@ -299,14 +305,16 @@ static void throwGSException(griddb::GSException* exception) { (dataColumnInfoArray = zend_hash_get_current_data_ex(arrColumnInfoArray, &posColumnInfoArray)) != NULL; zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array property as" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected array property as" " ColumnInfo element"); } // Fetch the hash table from a zval arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); int sizeOfColumnInfo = zend_hash_num_elements(arrColumnInfo); if (sizeOfColumnInfo != 2) { - SWIG_PHP_Error(E_ERROR, "Expected two elements for" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected two elements for" " columnInfo property"); } @@ -315,7 +323,8 @@ static void throwGSException(griddb::GSException* exception) { &posColumnInfo); if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex( arrColumnInfo, &posColumnInfo)) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as column name"); + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected string as column name"); } $2[i].name = Z_STRVAL_P(columnName); @@ -324,7 +333,8 @@ static void throwGSException(griddb::GSException* exception) { zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex( arrColumnInfo, &posColumnInfo)) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected an integer as" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected an integer as" " column type"); } $2[i].type = Z_LVAL_P(columnType); @@ -332,13 +342,15 @@ static void throwGSException(griddb::GSException* exception) { } } else if (strcmp(name, "type") == 0) { if (Z_TYPE_P(dataContainerInfo) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected integer as input" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected integer as input" " for type property"); } $4 = Z_LVAL_P(dataContainerInfo); } else if (strcmp(name, "rowKey") == 0) { if (Z_TYPE_P(dataContainerInfo) == IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected boolean as input" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected boolean as input" " for rowKey property"); } $5 = static_cast (zval_is_true(dataContainerInfo)); @@ -348,12 +360,14 @@ static void throwGSException(griddb::GSException* exception) { $descriptor(griddb::ExpirationInfo*), 0 | 0); if (!SWIG_IsOK(res)) { - SWIG_PHP_Error(E_ERROR, "Expected expiration object" + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected expiration object" " as input for expiration property"); } $6 = (griddb::ExpirationInfo *) expiration; } else { - SWIG_PHP_Error(E_ERROR, "Invalid Property"); + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Invalid Property"); } } } @@ -361,13 +375,21 @@ static void throwGSException(griddb::GSException* exception) { /** * Cleanup argument data for ContainerInfo constructor */ -%typemap(freearg) (const GSChar* name, const GSColumnInfo* props, - int propsCount, GSContainerType type, bool row_key, - griddb::ExpirationInfo* expiration) { - if ($2) { - delete[] $2; +%typemap(freearg, fragment = "freeArgContainerInfo") + (const GSChar* name, const GSColumnInfo* props, + int propsCount, GSContainerType type, bool row_key, + griddb::ExpirationInfo* expiration) { + freeArgContainerInfo($2); +} + +%fragment("freeArgContainerInfo", "header") { + //SWIG_exception does not include freearg, so we need this function + static void freeArgContainerInfo(const GSColumnInfo* props) { + if (props) { + delete[] props; } } +} %fragment("convertToFieldWithType", "header", fragment = "convertZvalValueToFloat", @@ -550,7 +572,7 @@ static bool convertZvalValueToFloat(zval* value, float* floatValPtr) { /** * Support convert type from object to GSTimestamp : - * Input in target language can be : datetime object + * input in target language can be : datetime object */ %fragment("convertDateTimeObjectToGSTimestamp", "header") { static bool convertDateTimeObjectToGSTimestamp(zval* datetime, @@ -633,7 +655,7 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, (HashTable *arr, HashPosition pos, zval* data) { const int SIZE = 60; if (Z_TYPE_P(&$input) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected an array as input"); + SWIG_exception(E_ERROR, "Expected an array as input"); } arr = Z_ARRVAL_P(&$input); int length = zend_hash_num_elements(arr); @@ -642,7 +664,7 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, GSType* typeList = arg1->getGSTypeList(); if (length != colNum) { - SWIG_PHP_Error(E_ERROR, "Num row is different with container info"); + SWIG_exception(E_ERROR, "Num row is different with container info"); } for (zend_hash_internal_pointer_reset_ex(arr, &pos); @@ -653,7 +675,7 @@ static bool convertDateTimeObjectToGSTimestamp(zval* datetime, char gsType[SIZE]; snprintf(gsType, SIZE, "Invalid value for column %d," " type should be : %d", pos, type); - SWIG_PHP_Error(E_ERROR, gsType); + SWIG_exception(E_ERROR, gsType); } } } @@ -726,7 +748,7 @@ static bool convertToRowKeyFieldWithType(griddb::Field &field, GSType* typeList = arg1->getGSTypeList(); GSType type = typeList[0]; if (!convertToRowKeyFieldWithType(*$1, &$input, type)) { - SWIG_PHP_Error(E_ERROR, "Can not convert to row field"); + SWIG_exception(E_ERROR, "Can not convert to row field"); } } } @@ -756,7 +778,7 @@ static bool getRowFields(GSRow* row, int columnCount, return returnValue; } if (nullValue) { - add_index_zval(outList, i, NULL); + add_index_null(outList, i); continue; } switch (typeList[i]) { @@ -941,7 +963,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, char errorMsg[SIZE]; snprintf(errorMsg, SIZE, "Can't get data for field %d with type %d", errorColumn, errorType); - SWIG_PHP_Error(E_ERROR, errorMsg); + SWIG_exception(E_ERROR, errorMsg); } } } @@ -985,8 +1007,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, char errorMsg[SIZE]; snprintf(errorMsg, SIZE, "Can't get data for field" " %d with type %d", errorColumn, errorType); - SWIG_PHP_Error(E_ERROR, errorMsg); - } + SWIG_exception(E_ERROR, errorMsg); + } break; } case (GS_ROW_SET_AGGREGATION_RESULT): { @@ -998,11 +1020,11 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, } case (GS_ROW_SET_QUERY_ANALYSIS): { // Not support now - SWIG_PHP_Error(E_ERROR, "Function is not supportted now"); + SWIG_exception(E_ERROR, "Function is not supportted now"); break; } default: { - SWIG_PHP_Error(E_ERROR, "Invalid Rowset type"); + SWIG_exception(E_ERROR, "Invalid Rowset type"); break; } } @@ -1044,7 +1066,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, GSTimestamp timestampValue; isSuccess = convertDateTimeObjectToGSTimestamp(&$input, ×tampValue); if (!isSuccess) { - SWIG_PHP_Error(E_ERROR, "Expected a DateTime object as input"); + SWIG_exception(E_ERROR, "Expected a DateTime object as input"); } $1 = timestampValue; } @@ -1052,7 +1074,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, /* * Typemap for set attribute ContainerInfo::column_info_list */ -%typemap(in, numinputs = 1) (ColumnInfoList*) +%typemap(in, numinputs = 1, fragment = "freeArgColumnInfoList") (ColumnInfoList*) (HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, HashTable *arrColumnInfo, HashPosition posColumnInfo, zval *dataColumnInfo, @@ -1063,19 +1085,19 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, $1 = &infolist; if (Z_TYPE_P(&$input) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected an array as input"); + SWIG_exception(E_ERROR, "Expected an array as input"); } arrColumnInfoArray = Z_ARRVAL_P(&$input); int length = zend_hash_num_elements(arrColumnInfoArray); if (length == 0) { - SWIG_PHP_Error(E_ERROR, "Expected not empty array as input"); + SWIG_exception(E_ERROR, "Expected not empty array as input"); } containerInfo = new GSColumnInfo[length]; if (containerInfo == NULL) { - SWIG_PHP_Error(E_ERROR, "Memmory allocation error"); + SWIG_exception(E_ERROR, "Memmory allocation error"); } memset(containerInfo, 0x0, length*sizeof(GSColumnInfo)); @@ -1088,21 +1110,24 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zend_hash_move_forward_ex(arrColumnInfoArray, &posColumnInfoArray)) { // Input valid is array only if (Z_TYPE_P(dataColumnInfoArray) != IS_ARRAY) { - SWIG_PHP_Error(E_ERROR, "Expected array property" + freeArgColumnInfoList($1); + SWIG_exception(E_ERROR, "Expected array property" " as ColumnInfo element"); } arrColumnInfo = Z_ARRVAL_P(dataColumnInfoArray); int sizeColumn = zend_hash_num_elements(arrColumnInfo); if (sizeColumn != 2) { - SWIG_PHP_Error(E_ERROR, "Expected two elements" + freeArgColumnInfoList($1); + SWIG_exception(E_ERROR, "Expected two elements" " for ColumnInfo property"); } // Get column name zend_hash_internal_pointer_reset_ex(arrColumnInfo, &posColumnInfo); if (Z_TYPE_P(columnName = zend_hash_get_current_data_ex( arrColumnInfo, &posColumnInfo)) != IS_STRING) { - SWIG_PHP_Error(E_ERROR, "Expected string as column name"); + freeArgColumnInfoList($1); + SWIG_exception(E_ERROR, "Expected string as column name"); } containerInfo[i].name = Z_STRVAL_P(columnName); @@ -1110,7 +1135,8 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, zend_hash_move_forward_ex(arrColumnInfo, &posColumnInfo); if (Z_TYPE_P(columnType = zend_hash_get_current_data_ex( arrColumnInfo, &posColumnInfo)) != IS_LONG) { - SWIG_PHP_Error(E_ERROR, "Expected an integer as column type"); + freeArgColumnInfoList($1); + SWIG_exception(E_ERROR, "Expected an integer as column type"); } containerInfo[i].type = Z_LVAL_P(columnType); i++; @@ -1120,9 +1146,16 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, /** * Cleanup argument data for set attribute ContainerInfo::column_info_list */ -%typemap(freearg) (ColumnInfoList*) { - if ($1->columnInfo) { - delete[]($1->columnInfo); +%typemap(freearg, fragment = "freeArgColumnInfoList") (ColumnInfoList*) { + freeArgColumnInfoList($1); +} + +%fragment("freeArgColumnInfoList", "header") { + //SWIG_exception does not include freearg, so we need this function + static void freeArgColumnInfoList(ColumnInfoList* infoList) { + if (infoList->columnInfo) { + delete[](infoList->columnInfo); + } } } From c9b922a0ad1b0b66ba9c01760e3e3b1dc8387abe Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:48:46 +0900 Subject: [PATCH 14/22] fix attribute --- src/Container.cpp | 8 ++ src/Container.h | 1 + src/PartitionController.cpp | 7 ++ src/PartitionController.h | 1 + src/RowSet.cpp | 14 +++ src/RowSet.h | 2 + src/Store.cpp | 7 ++ src/Store.h | 1 + src/gstype_php.i | 171 ++++++++++++++++++++++++++---------- 9 files changed, 164 insertions(+), 48 deletions(-) diff --git a/src/Container.cpp b/src/Container.cpp index 817306d..a454900 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -197,6 +197,14 @@ namespace griddb { return containerType; } + /** + * @brief Thrown exception when set current container type + */ + void Container::set_type(GSContainerType type) { + throw GSException(mContainer, + "Can't not set value for Container::type attribute"); + } + /** * @brief Rolls back the result of the current transaction and starts a * new transaction in the manual commit mode. diff --git a/src/Container.h b/src/Container.h index 7c01c08..3fe13df 100644 --- a/src/Container.h +++ b/src/Container.h @@ -40,6 +40,7 @@ class Container { ~Container(); void close(GSBool allRelated = GS_FALSE); GSContainerType get_type(); + void set_type(GSContainerType type); void create_index(const char *column_name, GSIndexTypeFlags index_type = GS_INDEX_FLAG_DEFAULT); void drop_index(const char *column_name, GSIndexTypeFlags index_type = diff --git a/src/PartitionController.cpp b/src/PartitionController.cpp index 60cb1c4..afb473d 100644 --- a/src/PartitionController.cpp +++ b/src/PartitionController.cpp @@ -58,6 +58,13 @@ namespace griddb { return value; } + /** + * @brief Thrown exception when set partition count + */ + void PartitionController::set_partition_count(int32_t partition_count) { + throw GSException(mController, "Can't not set value for" + " PartitionController::partitionCount attribute"); + } /** * @brief Get container partition count * @param partition_index The partition index, from 0 to the number of partitions minus one diff --git a/src/PartitionController.h b/src/PartitionController.h index 02c04fa..3adb3b0 100644 --- a/src/PartitionController.h +++ b/src/PartitionController.h @@ -32,6 +32,7 @@ class PartitionController { ~PartitionController(); void close(); int32_t get_partition_count(); + void set_partition_count(int32_t 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, diff --git a/src/RowSet.cpp b/src/RowSet.cpp index f31ec2d..6168a33 100644 --- a/src/RowSet.cpp +++ b/src/RowSet.cpp @@ -138,6 +138,13 @@ namespace griddb { return gsGetRowSetSize(mRowSet); } + /** + * @brief Thrown exception when set size of this rowset + */ + void RowSet::set_size(int32_t size) { + throw GSException(mRowSet, + "Can't not set value for RowSet::size attribute"); + } /** * @brief Delete current row data. */ @@ -177,6 +184,13 @@ namespace griddb { return mType; } + /** + * @brief Thrown exception when set current row type. + */ + void RowSet::set_type(GSRowSetType type) { + throw GSException(mRowSet, + "Can't not set value for RowSet::type attribute"); + } /** * @brief Get next query analysis * @return Represents one of information entries composing a query plan and the results of analyzing a query operation. diff --git a/src/RowSet.h b/src/RowSet.h index 57053ff..1092d8c 100644 --- a/src/RowSet.h +++ b/src/RowSet.h @@ -50,6 +50,7 @@ class RowSet { ~RowSet(); void close(); int32_t size(); + void set_size(int32_t size); // Iterator bool has_next(); void next(GSRowSetType *type, bool *hasNextRow, @@ -58,6 +59,7 @@ class RowSet { void update(GSRow *row); void remove(); GSRowSetType type(); + void set_type(GSRowSetType type); void get_column_names(char ***listName, int *num); QueryAnalysisEntry* get_next_query_analysis(); AggregationResult* get_next_aggregation(); diff --git a/src/Store.cpp b/src/Store.cpp index 99a031c..b98c781 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -177,6 +177,13 @@ namespace griddb { } } + /** + * @brief Thrown exception when set Partition controller. + */ + void Store::set_partition_info(PartitionController *pattition_controller) { + throw GSException(mStore, + "Can't not set value for Store::partitionController attribute"); + } /** * @brief Create row key predicate. * @param type The type of Row key used as a matching condition diff --git a/src/Store.h b/src/Store.h index 44ecea7..47b445a 100644 --- a/src/Store.h +++ b/src/Store.h @@ -53,6 +53,7 @@ class Store { ContainerInfo* get_container_info(const char *name); PartitionController* partition_info(); + void set_partition_info(PartitionController *pattition_controller); RowKeyPredicate* create_row_key_predicate(GSType type); private: diff --git a/src/gstype_php.i b/src/gstype_php.i index c5ced4f..724304d 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -36,40 +36,40 @@ %include // Read only attribute Container::type -%attribute(griddb::Container, int, type, get_type); +%attribute(griddb::Container, int, type, get_type, set_type); // Read only attribute GSException::isTimeout %attribute(griddb::GSException, bool, isTimeout, is_timeout); // Read only attribute RowSet::size -%attribute(griddb::RowSet, int32_t, size, size); +%attribute(griddb::RowSet, int32_t, size, size, set_size); // Read only attribute RowSet::type -%attribute(griddb::RowSet, GSRowSetType, type, type); -// Read only attribute ContainerInfo::name +%attribute(griddb::RowSet, GSRowSetType, type, type, set_type); +// Read and write attribute ContainerInfo::name %attribute(griddb::ContainerInfo, GSChar*, name, get_name, set_name); -// Read only attribute ContainerInfo::type +// Read and write attribute ContainerInfo::type %attribute(griddb::ContainerInfo, GSContainerType, type, get_type, set_type); -// Read only attribute ContainerInfo::rowKey +// Read and write attribute ContainerInfo::rowKey %attribute(griddb::ContainerInfo, bool, rowKey, get_row_key_assigned, set_row_key_assigned); -// Read only attribute ContainerInfo::columnInfoArray +// Read and write attribute ContainerInfo::columnInfoArray %attributeval(griddb::ContainerInfo, ColumnInfoList, columnInfoArray, get_column_info_list, set_column_info_list); -// Read only attribute ContainerInfo::expiration +// Read and write attribute ContainerInfo::expiration %attribute(griddb::ContainerInfo, griddb::ExpirationInfo*, expiration, get_expiration_info, set_expiration_info); -// Read only attribute ExpirationInfo::time +// Read and write attribute ExpirationInfo::time %attribute(griddb::ExpirationInfo, int, time, get_time, set_time); -// Read only attribute ExpirationInfo::unit +// Read and write attribute ExpirationInfo::unit %attribute(griddb::ExpirationInfo, GSTimeUnit, unit, get_time_unit, set_time_unit); -// Read only attribute ExpirationInfo::divisionCount +// Read and write attribute ExpirationInfo::divisionCount %attribute(griddb::ExpirationInfo, int, divisionCount, get_division_count, set_division_count); // Read only attribute Store::partitionController %attribute(griddb::Store, griddb::PartitionController*, - partitionController, partition_info); + partitionController, partition_info, set_partition_info); // Read only attribute PartitionController::partitionCount %attribute(griddb::PartitionController, int, partitionCount, - get_partition_count); + get_partition_count, set_partition_count); /* * Ignore unnecessary functions @@ -108,6 +108,8 @@ static void throwGSException(griddb::GSException* exception) { zend_function* constructor = zend_std_get_constructor(Z_OBJ(ex)); zend_call_method(&ex, ce, &constructor, NULL, 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); + + // Check if no references remaining to ctorRv variable, then destroy it if (Z_TYPE(ctorRv) != IS_UNDEF) { zval_ptr_dtor(&ctorRv); } @@ -227,7 +229,8 @@ static void throwGSException(griddb::GSException* exception) { * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, * "expiration" : expiration object) */ -%typemap(in, numinputs = 1, fragment = "freeArgContainerInfo") +%typemap(in, numinputs = 1, fragment = "freeArgContainerInfo", + fragment = "checkTypeIsLongBool") (const GSChar* name, const GSColumnInfo* props, int propsCount, GSContainerType type, bool row_key, griddb::ExpirationInfo* expiration) @@ -348,7 +351,7 @@ static void throwGSException(griddb::GSException* exception) { } $4 = Z_LVAL_P(dataContainerInfo); } else if (strcmp(name, "rowKey") == 0) { - if (Z_TYPE_P(dataContainerInfo) == IS_STRING) { + if (!checkTypeIsLongBool(dataContainerInfo)) { freeArgContainerInfo($2); SWIG_exception(E_ERROR, "Expected boolean as input" " for rowKey property"); @@ -383,10 +386,10 @@ static void throwGSException(griddb::GSException* exception) { } %fragment("freeArgContainerInfo", "header") { - //SWIG_exception does not include freearg, so we need this function - static void freeArgContainerInfo(const GSColumnInfo* props) { +//SWIG_exception does not include freearg, so we need this function +static void freeArgContainerInfo(const GSColumnInfo* props) { if (props) { - delete[] props; + delete[] props; } } } @@ -394,7 +397,8 @@ static void throwGSException(griddb::GSException* exception) { %fragment("convertToFieldWithType", "header", fragment = "convertZvalValueToFloat", fragment = "convertZvalValueToDouble", - fragment = "convertDateTimeObjectToGSTimestamp") { + fragment = "convertDateTimeObjectToGSTimestamp", + fragment = "checkTypeIsLongBool") { static bool convertToFieldWithType(GSRow *row, int column, zval* value, GSType type) { GSResult returnCode; @@ -425,7 +429,7 @@ static bool convertToFieldWithType(GSRow *row, int column, break; } case GS_TYPE_BOOL: { - if (Z_TYPE_P(value) == IS_STRING) { + if (!checkTypeIsLongBool(value)) { return false; } bool boolVal; @@ -515,8 +519,8 @@ static bool convertToFieldWithType(GSRow *row, int column, break; } default: - return false; - break; + return false; + break; } return (GS_SUCCEEDED(returnCode)); } @@ -807,8 +811,9 @@ static bool getRowFields(GSRow* row, int columnCount, if (!GS_SUCCEEDED(returnCode)) { break; } - add_index_string(outList, i, - reinterpret_cast(blobValue.data)); + add_index_stringl(outList, i, + reinterpret_cast(blobValue.data), + blobValue.size); break; } case GS_TYPE_BOOL: { @@ -968,6 +973,44 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, } } +/** + * Support convert AggregationResult object from C++ layer to PHP language + */ +%fragment("convertToAgrregationResultZvalObj", "header") { +static void convertToAgrregationResultZvalObj(griddb::AggregationResult* aggResult, + zval* AggregationResultZvalObject) { + const char* objTypename = "AggregationResult"; + size_t objTypenameLen = strlen(objTypename); + // Create a resource + zval resource; + + SWIG_SetPointerZval(&resource, reinterpret_cast(aggResult), + $descriptor(griddb::AggregationResult *), 1); + + // Create a PHP AggregationResult object + zend_string * objTypenameZend = zend_string_init(objTypename, + objTypenameLen, 0); + zend_class_entry* ce = zend_lookup_class(objTypenameZend); + zend_string_release(objTypenameZend); + if (!ce) { + SWIG_FAIL(); + } + + object_and_properties_init(AggregationResultZvalObject, ce, NULL); + + // Constructor, pass resource to constructor argument + zval ctorRv; + zend_function* constructor = zend_std_get_constructor(Z_OBJ(*AggregationResultZvalObject)); + zend_call_method(AggregationResultZvalObject, ce, &constructor, NULL, + 0, &ctorRv, 1, &resource, NULL TSRMLS_CC); + + // Check if no references remaining to ctorRv variable, then destroy it + if (Z_TYPE(ctorRv) != IS_UNDEF) { + zval_ptr_dtor(&ctorRv); + } +} +} + /** * Type map for Rowset::next() */ @@ -984,9 +1027,10 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, $4 = &aggResultTmp; } -%typemap(argout, fragment = "getRowFields") (GSRowSetType* type, - bool* hasNextRow, griddb::QueryAnalysisEntry** queryAnalysis, - griddb::AggregationResult** aggResult) { +%typemap(argout, fragment = "getRowFields", + fragment = "convertToAgrregationResultZvalObj")(GSRowSetType* type, + bool* hasNextRow, griddb::QueryAnalysisEntry** queryAnalysis, + griddb::AggregationResult** aggResult) { const int SIZE = 60; if (*$2 == false) { RETURN_NULL(); @@ -1011,22 +1055,16 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, } break; } - case (GS_ROW_SET_AGGREGATION_RESULT): { - SWIG_SetPointerZval(return_value, reinterpret_cast (*$4), - $descriptor(griddb::AggregationResult *), - SWIG_CAST_NEW_MEMORY); - + case (GS_ROW_SET_AGGREGATION_RESULT): + convertToAgrregationResultZvalObj(*$4, return_value); break; - } - case (GS_ROW_SET_QUERY_ANALYSIS): { + case (GS_ROW_SET_QUERY_ANALYSIS): // Not support now SWIG_exception(E_ERROR, "Function is not supportted now"); break; - } - default: { + default: SWIG_exception(E_ERROR, "Invalid Rowset type"); break; - } } } @@ -1040,17 +1078,16 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, %typemap(argout) (griddb::Field *agValue) { switch ($1->type) { - case GS_TYPE_LONG: { + case GS_TYPE_LONG: RETVAL_LONG($1->value.asLong); break; - } - case GS_TYPE_DOUBLE: { + case GS_TYPE_DOUBLE: RETVAL_DOUBLE($1->value.asDouble); break; - } case GS_TYPE_TIMESTAMP: convertTimestampToDateTimeObject(&($1->value.asTimestamp), return_value); + break; default: RETURN_NULL(); } @@ -1078,8 +1115,7 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, (HashTable *arrColumnInfoArray, HashPosition posColumnInfoArray, zval *dataColumnInfoArray, HashTable *arrColumnInfo, HashPosition posColumnInfo, zval *dataColumnInfo, - zval *columnName, zval *columnType) { - ColumnInfoList infolist; + zval *columnName, zval *columnType, ColumnInfoList infolist) { int i = 0; GSColumnInfo* containerInfo; $1 = &infolist; @@ -1151,13 +1187,13 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, } %fragment("freeArgColumnInfoList", "header") { - //SWIG_exception does not include freearg, so we need this function - static void freeArgColumnInfoList(ColumnInfoList* infoList) { - if (infoList->columnInfo) { - delete[](infoList->columnInfo); - } +//SWIG_exception does not include freearg, so we need this function +static void freeArgColumnInfoList(ColumnInfoList* infoList) { + if (infoList->columnInfo) { + delete[](infoList->columnInfo); } } +} /* * Typemap for get attribute ContainerInfo::column_info_list @@ -1201,3 +1237,42 @@ static void convertTimestampToDateTimeObject(GSTimestamp* timestamp, add_next_index_string(return_value, nameList[i]); } } + +/** +* Support to check type is long, bool +*/ +%fragment("checkTypeIsLongBool", "header") { +static bool checkTypeIsLongBool(zval* value) { + if (Z_TYPE_P(value) == IS_NULL || Z_TYPE_P(value) == IS_DOUBLE || + Z_TYPE_P(value) == IS_STRING || Z_TYPE_P(value) == IS_RESOURCE || + Z_TYPE_P(value) == IS_ARRAY || Z_TYPE_P(value) == IS_OBJECT) { + return false; + } + return true; +} +} + +/** +* Support to get bool value +*/ +%typemap(in, fragment = "checkTypeIsLongBool") bool { + if (!checkTypeIsLongBool(&$input)) { + SWIG_exception(E_ERROR, "Expected boolean value as input"); + } + $1 = zval_is_true(&$input); +} + +/** +* Support to get integer value +*/ +%typemap(in, fragment = "checkTypeIsLongBool") int { + if (!checkTypeIsLongBool(&$input)) { + SWIG_exception(E_ERROR, "Expected integer value as input"); + } + int64_t longVal = Z_LVAL_P(&$input); + if (longVal < std::numeric_limits::min() || + longVal > std::numeric_limits::max()) { + SWIG_exception(E_ERROR, "This value is out of integer range"); + } + $1 = longVal; +} From 386e77d4ab407fa70af8ee46b890aeabe4f9062a Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:51:16 +0900 Subject: [PATCH 15/22] update API Reference for v0.8 --- docs/PHPAPIReference.files/sheet001.htm | 151 +- docs/PHPAPIReference.files/sheet002.htm | 55862 +++++++++++++++++++- docs/PHPAPIReference.files/sheet003.htm | 9325 +++- docs/PHPAPIReference.files/sheet004.htm | 260 +- docs/PHPAPIReference.files/stylesheet.css | 398 +- docs/PHPAPIReference.files/tabstrip.htm | 6 +- docs/PHPAPIReference.htm | 21 +- 7 files changed, 64956 insertions(+), 1067 deletions(-) diff --git a/docs/PHPAPIReference.files/sheet001.htm b/docs/PHPAPIReference.files/sheet001.htm index 1237142..7fb1001 100644 --- a/docs/PHPAPIReference.files/sheet001.htm +++ b/docs/PHPAPIReference.files/sheet001.htm @@ -16,8 +16,8 @@ mso-displayed-thousand-separator:"\,";} @page {margin:.75in .7in .75in .7in; - mso-header-margin:.3in; - mso-footer-margin:.3in;} + mso-header-margin:.51in; + mso-footer-margin:.51in;} ruby {ruby-align:left;} rt @@ -26,8 +26,8 @@ font-weight:400; font-style:normal; text-decoration:none; - font-family:"MS Pゴシック", monospace; - mso-font-charset:128; + font-family:Calibri, sans-serif; + mso-font-charset:0; mso-char-type:katakana; display:none;} --> @@ -56,100 +56,87 @@ - - - - - - - - +
classdescription 
+ + + + + - - - - + + + - - - - + + + - - - - + + + - - - - + + + - - - - + + + - - - + + - - - - - + + + - - - - + + + - - - - - - - - + + - - - - - + + + + + + + + + + + - - - - + + + - - - + +
ClassDescription
AggregationResultStores - the result of an aggregation operation 
AggregationResultStores the result of an + aggregation operation
ContainerProvides - management functions for sets of row having same typeInherits Resource - class
ContainerProvides + management functions for sets of row having same type
ContainerInfoRepresents - the information about a specific Container 
QueryAnalysisEntryRepresents one + of information entries composing a query plan and the results of analyzing a + query operation.
GSExceptionException - for GridDB 
GSExceptionRepresents the + exception for GridDB
PartitionControllerController - for acquiring and processing the partition status 
PartitionControllerController for + acquiring and processing the partition status
QueryProvides - the functions of holding the information about a query related to a specific +
QueryProvides the + functions of holding the information about a query related to a specific Container, specifying the options for fetching and retrieving the resultInherits Resource - class
ResourceError - handling 
RowKeyPredicateRepresents the + condition that a row key satisfies
RowA - general-purpose Row for managing fields in any schemaInherits Resource - class
RowSetManages a set of + Rows obtained by a query
RowSetManages - a set of Rows obtained by a queryInherits Resource - class
StoreProvides +
StoreProvides functions to manipulate the entire data managed in one GridDB systemInherits Resource - class
StoreFactoryManages - a Store instanceInherits Resource - class
StoreFactoryManages a Store + instance
ContainerInfoRepresents the + information about a Container
ExpirationInfoRepresents the + information about a expiration
TimestampProvides - the utilities for manipulating time data 
TimestampUtilsProvides the + utilities for manipulating time data
diff --git a/docs/PHPAPIReference.files/sheet002.htm b/docs/PHPAPIReference.files/sheet002.htm index aafb6d8..031c73b 100644 --- a/docs/PHPAPIReference.files/sheet002.htm +++ b/docs/PHPAPIReference.files/sheet002.htm @@ -16,8 +16,9 @@ mso-displayed-thousand-separator:"\,";} @page {margin:.75in .71in .75in .71in; - mso-header-margin:.31in; - mso-footer-margin:.31in;} + mso-header-margin:.51in; + mso-footer-margin:.51in; + mso-page-orientation:landscape;} ruby {ruby-align:left;} rt @@ -26,8 +27,8 @@ font-weight:400; font-style:normal; text-decoration:none; - font-family:"MS Pゴシック", monospace; - mso-font-charset:128; + font-family:Calibri, sans-serif; + mso-font-charset:0; mso-char-type:katakana; display:none;} --> @@ -54,815 +55,55124 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
classmethoddescriptionthe correspond - C client API
+
ClassMethodDescriptionInput exampleOutput example
AggregationResultint - get_long()
- float get_double()
- GSTimestamp get_timestamp()
Returns - the aggregation result as the value with specified typeGSBool - gsGetAggregationValue (GSAggregationResult *aggregationResult, void *value, - GSType valueType)
Containervoid - create_index(string $columnName, GSIndexTypeFlags $indexType)Creates + object + get(Type $type)
+ ※object: integer or float or datetime
Returns + the aggregation result  
Containervoid + createIndex(string $columnName, IndexType $indexType=DEFAULT_TYPE)Creates a specified type of index on the specified ColumnGSResult - gsCreateIndex (GSContainer *container, const GSChar *columnName, - GSIndexTypeFlags flags)
void drop_index(string $columName, - GSIndexTypeFlags $indexType)Removes +   
void dropIndex(string $columnName, IndexType + $indexType=DEFAULT_TYPE)Removes the specified type of index among indexes on the specified ColumnGSResult - gsDropIndex (GSContainer *container, const GSChar *columnName, - GSIndexTypeFlags flags)
void flush()Writes +   
void flush()Writes the results of earlier updates to a non-volatile storage medium, such as SSD, so as to prevent the data loss even if all cluster nodes stop suddenlyGSResult - gsFlush (GSContainer *container)
bool put_row(Row $row)Newly +   
boolean put(array[object] $row)Newly creates or update a RowGSResult - gsPutRow (GSContainer *container, const void *key, const void *rowObj, GSBool - *exists)
Query query(string $queryString)Creates a query - to execute the specified TQL statementGSResult - gsQuery (GSContainer *container, const GSChar *queryString, GSQuery **query)
GSContainerType get_type()Return the type - of specified ContainerGSResult - gsGetContainerType (GSContainer *container, GSContainerType *type)
Row create_row()Create - a new Row object based on the column layout of specified ContainerGSResult - gsCreateRowByContainer (GSContainer *container, GSRow **row)
void abort()Rolls + $row + = [1, "val"] 
Query query(string $query)Creates a query to execute the + specified TQL statement  
ContainerType typeRead-only + attribute  
void abort()Rolls back the result of the current transaction and starts a new transaction in the manual commit modeGSResult - gsAbort (GSContainer *container)
void commit()Commits +   
void commit()Commits the result of the current transaction and start a new transaction in the manual commit modeGSResult - gsCommit (GSContainer *container)
void set_auto_commit(bool $enabled)Change +   
void setAutoCommit(boolean $enabled)Change the setting of the commit modeGSResult - gsSetAutoCommit (GSContainer *container, GSBool enabled)
bool get_row_by_integer(int $key, bool - $forUpdate, Row $row)Returns - the content of a Row corresponding to the INTEGER-type Row keyGSResult - gsGetRowByInteger (GSContainer *container, int32_t key, void *rowObj, GSBool - forUpdate, GSBool *exists)
bool get_row_by_long(int $key, bool $forUpdate, - Row $row)Returns - the content of a Row corresponding to the LONG-type Row keyGSResult - gsGetRowByLong (GSContainer *container, int64_t key, void *rowObj, GSBool - forUpdate, GSBool *exists)
bool get_row_by_timestamp(GSTimestamp $key, - bool $forUpdate, Row $row)Returns - the content of a Row corresponding to the TIMESTAMP-type Row keyGSResult - gsGetRowByTimestamp (GSContainer *container, GSTimestamp key, void *rowObj, - GSBool forUpdate, GSBool *exists)
bool get_row_by_string(string $key, bool - $forUpdate, Row $row)Returns - the content of a Row corresponding to the STRING-type Row keyGSResult - gsGetRowByString (GSContainer *container, const GSChar *key, void *rowObj, - GSBool forUpdate, GSBool *exists)
bool put_row_by_integer(int $key, Row $row)Newly - creates or update a Row by specifying the INTEGER type Row keyGSResult - gsPutRowByInteger (GSContainer *container, int32_t key, const void *rowObj, - GSBool *exists)
bool put_row_by_long(int $key, Row $row)Newly - creates or update a Row by specifying the LONG type Row keyGSResult - gsPutRowByLong (GSContainer *container, int64_t key, const void *rowObj, - GSBool *exists)
bool put_row_by_timestamp(GSTimestamp $key, Row - $row)Newly - creates or update a Row by specifying the TIMESTAMP type Row keyGSResult - gsPutRowByTimestamp (GSContainer *container, GSTimestamp key, const void - *rowObj, GSBool *exists)
bool put_row_by_string(string $key, Row $row)Newly - creates or update a Row by specifying the STRING type Row keyGSResult - gsPutRowByString (GSContainer *container, const GSChar *key, const void - *rowObj, GSBool *exists)
bool delete_row_by_integer(int $key)Deletes - a Row corresponding to the INTEGER-type Row keyGSResult - gsDeleteRowByInteger (GSContainer *container, int32_t key, GSBool *exists)
bool delete_row_by_long(int $key)Deletes - a Row corresponding to the LONG-type Row keyGSResult - gsDeleteRowByLong (GSContainer *container, int64_t key, GSBool *exists)
bool delete_row_by_timestamp(GSTimestamp $key)Deletes - a Row corresponding to the TIMESTAMP-type Row keyGSResult - gsDeleteRowByTimestamp (GSContainer *container, GSTimestamp key, GSBool - *exists)
bool delete_row_by_string(string $key)Deletes - a Row corresponding to the STRING-type Row keyGSResult - gsDeleteRowByString (GSContainer *container, const GSChar *key, GSBool - *exists)
GSExceptionbool - is_timeout()This - function can be used to determine whether the result of the requested process - shows the error code corresponding to the error that occurred when the - requested process is not completed within a predetermined timeGSBool - gsIsTimeoutError (GSResult result)
PartitionControllerint - get_partition_count()Get - the number of partitions in the target GridDB clusterGSResult - gsGetPartitionCount (GSPartitionController *controller, int32_t - *partitionCount)
int get_partition_container_count(int - $partitionIndex)Get +   
array[object] + get(object $key)Returns + the content of a Row corresponding to Row key [1, + "val"]
boolean remove(object $key)Deletes + a Row corresponding to Row key  
GSExceptionboolean + isTimeoutRead-only + attribute  
int getErrorStackSize()Returns + the stack size of last error information related to specified resource  
int getErrorCode(int $stackIndex)Returns + the error code of last error related to specified resource  
string getMessage(int $stackIndex)Returns + the message of last error related to specified resource  
string getLocation(int $stackIndex)Returns + the error location of the internal module to the message of last error + related to specified resource  
PartitionControllerint + partitionCountRead-only + attribute  
int getContainerCount(int $partitionIndex)Get the total number of containers belonging to a specified partitionGSResult - gsGetPartitionContainerCount (GSPartitionController *controller, int32_t - partitionIndex, int64_t *containerCount)
array get_partition_container_names(int +   
array[string] getContainerNames(int $partitionIndex, int $start, int $limit)Get - a list of the Container names belonging to a specified partitionGSResult - gsGetPartitionContainerNames (GSPartitionController *controller, int32_t - partitionIndex, int64_t start, const int64_t *limit, const GSChar *const - **nameList, size_t *size)limit is optional. If not - specified or limit < 0, it is considered as no upper limit
int get_partition_index_of_container(string + Get + a array of the Container names belonging to a specified partition ["container1", + "container2", "container3"]
int getPartitionIndexOfContainer(string $containerName)Get + Get the partition index corresponding to the specified Container nameGSResult - gsGetPartitionIndexOfContainer (GSPartitionController *controller, const - GSChar *containerName, int32_t *partitionIndex)
QueryRowSet - fetch(bool $forUpdate)Executes +   
QueryRowSet + fetch(boolean $forUpdate=False)Executes a specified query with the specified option and returns a set of Rows as an execution resultGSResult - gsFetch (GSQuery *query, GSBool forUpdate, GSRowSet **rowSet)
RowSet get_row_set()Returns +   
RowSet getRowSet()Returns RowSet as the latest resultGSResult - gsGetRowSet (GSQuery *query, GSRowSet **rowSet)
void set_fetch_option_integer(GSFetchOption - $fetchOption, int $value)
- void set_fetch_option_long(GSFetchOption $fetchOption, int $value)
Sets +   
void setFetchOptions(int $limit)Sets an fetch option for a result acquisitionGSResult - gsSetFetchOption (GSQuery *query, GSFetchOption fetchOption, const void - *value, GSType valueType)
Resourceint - get_error_stack_size()Returns - the stack size of last error information related to specified resourcesize_t - gsGetErrorStackSize (void *gsResource)
GSResult get_error_code(int $stackIndex)Returns - the error code of last error related to specified resourceGSResult - gsGetErrorCode (void *gsResource, size_t stackIndex)
string format_error_message(int $stackIndex, - int $bufSize)Returns - the message of last error related to specified resourcesize_t - gsFormatErrorMessage (void *gsResource, size_t stackIndex, GSChar *strBuf, - size_t bufSize)
string format_error_location(int $stackIndex, - int $bufSize)Returns - the error location of the internal module to the message of last error - related to specified resourcesize_t - gsFormatErrorLocation (void *gsResource, size_t stackIndex, GSChar *strBuf, - size_t bufSize)
Rowvoid - set_field_by_string(int $column, string $value)Sets - the STRING-type value to the specified fieldGSResult - gsSetRowFieldByString (GSRow *row, int32_t column, const GSChar *fieldValue)
string get_field_as_string(int $column)Returns - the STRING-type value in the specified fieldGSResult - gsGetRowFieldAsString (GSRow *row, int32_t column, const GSChar **fieldValue)
void set_field_by_bool(int $column, bool - $value)Sets - the BOOL-type value to the specified fieldGSResult - gsSetRowFieldByBool (GSRow *row, int32_t column, GSBool fieldValue)
bool get_field _as_bool(int $column)Returns - the BOOL-type value in the specified fieldGSResult - gsGetRowFieldAsBool (GSRow *row, int32_t column, GSBool *fieldValue)
void set_field_by_byte(int $column, int $value)Sets - the BYTE-type value to the specified fieldGsResult - gsSetRowFieldByByte (GSRow *row, int32_t column, int8_t fieldValue)
int get_field _as_byte(int $column)Returns - the BYTE-type value in the specified fieldGSResult - gsGetRowFieldAsByte (GSRow *row, int32_t column, int8_t *fieldValue)
void set_field_by_short(int $column, int - $value)Sets - the SHORT-type value to the specified fieldGSResult - gsSetRowFieldByShort (GSRow *row, int32_t column, int16_t fieldValue)
int get_field _as_short(int $column)Returns - the SHORT-type value in the specified fieldGSResult - gsGetRowFieldAsShort (GSRow *row, int32_t column, int16_t *fieldValue)
void set_field_by_integer(int $column, int - $value)Sets - the INTEGER-type value to the specified fieldGSResult - gsSetRowFieldByInteger (GSRow *row, int32_t column, int32_t fieldValue)
int get_field _as_integer(int $column)Returns - the INTEGER-type value in the specified fieldGSResult - gsGetRowFieldAsInteger (GSRow *row, int32_t column, int32_t *fieldValue)
void set_field_by_long(int $column, int $value)Sets - the LONG-type value to the specified fieldGSResult - gsSetRowFieldByLong (GSRow *row, int32_t column, int64_t fieldValue)
int get_field _as_long(int $column)Returns - the LONG-type value in the specified fieldGSResult - gsGetRowFieldAsLong (GSRow *row, int32_t column, int64_t *fieldValue)
void set_field_by_float(int $column, float - $value)Sets - the FLOAT-type value to the specified fieldGSResult - gsSetRowFieldByFloat (GSRow *row, int32_t column, float fieldValue)
float get_field_as_float(int $column)Returns - the FLOAT-type value in the specified fieldGSResult - gsGetRowFieldAsFloat (GSRow *row, int32_t column, float *fieldValue)
void set_field_by_double(int $column, float - $value)Sets - the DOUBLE-type value to the specified fieldGSResult - gsSetRowFieldByDouble (GSRow *row, int32_t column, double fieldValue)
float get_field_as_double(int $column)Returns - the DOUBLE-type value in the specified fieldGSResult - gsGetRowFieldAsDouble (GSRow *row, int32_t column, double *fieldValue)
void set_field_by_timestamp (int $column, - GSTimestamp $value)Sets - the TIMESTAMP-type value to the specified fieldGSResult - gsSetRowFieldByTimestamp (GSRow *row, int32_t column, GSTimestamp fieldValue)
GSTimestamp get_field _as_timestamp(int - $column)Returns - the TIMESTAMP-type value in the specified fieldGSResult - gsGetRowFieldAsTimestamp (GSRow *row, int32_t column, GSTimestamp - *fieldValue)
void set_field_by_blob(int $column, string - $value)Sets - the BLOB-type value to the specified fieldGSResult - gsSetRowFieldByBlob (GSRow *row, int32_t column, const GSBlob *fieldValue)
string get_field_as_blob(int $column)Returns - the BLOB-type value in the specified fieldGSResult - gsGetRowFieldAsBlob (GSRow *row, int32_t column, GSBlob *fieldValue)
ContainerInfo get_schema()Returns - the schema corresponding to the specified RowGSResult - gsGetRowSchema (GSRow *row, GSContainerInfo *schemaInfo)
RowSetvoid - delete_current()Deletes +   
RowSetvoid + remove()Deletes the Row at the current cursor positionGSResult - gsDeleteCurrentRow (GSRowSet *rowSet)
void get_next(Row $row)Moves - the cursor to the next Row in a Row set and returns the Row object at the +   
object next()
+ ※object: AggregationResult  or + array[object]
Moves + the cursor to the next element in a object set and returns the object at the moved positionGSResult - gsGetNextRow (GSRowSet *rowSet, void *rowObj)
AggregationResult get_next_aggregation()Moves - the cursor to the next Row in a Row set and returns the aggregation result at - the moved positionGSResult - gsGetNextAggregation (GSRowSet *rowSet, GSAggregationResult - **aggregationResult)
GSRowSetType get_type()Returns - the type of Row setGSRowSetType - gsGetRowSetType (GSRowSet *rowSet)
int get_size()Returns - the size of Row set, i.e. the number of Row when a Row set is createdint32_t - gsGetRowSetSize (GSRowSet *rowSet)
bool has_next()Returns +  [1, + "val"]
RowSetType typeRead-only + attribute  
int sizeRead-only + attribute  
boolean hasNext()Returns whether a Row set has at least one Row ahead of the current cursor positionGSBool - gsHasNextRow (GSRowSet *rowSet)
void update_current(Row $row)Updates +   
void update(array[object] $row)Updates the values except a Row key of the Row at the cursor position, using the specified Row objectGSResult - gsUpdateCurrentRow (GSRowSet *rowSet, const void *rowObj)$row + = [1, "val"] 
+ StoreContainer - put_container(string $containerName, array<array columnInfo> - $columnInfolist, GSContainerType $containerType, bool $modifiable=false, bool - $rowKeyAssigned=true, bool $columnOrderIgnorable=false, int - $rowExpirationTime=null, GSTimeUnit $rowExpirationTimeUnit=null, int - $expirationDivisionCount=null)Newly + Container + putContainer(ContainerInfo $info, boolean $modifiable=False)Newly creates or update a Container with the specified Container propertiesGSResult - gsPutContainerGeneral (GSGridStore *store, const GSChar *name, const - GSContainerInfo *info, GSBool modifiable, GSContainer **container)                  containerName, columnInfolist - and containerType are required parameteres. Other parameters are - optional. 
Container get_container(string $containerName)Get +   
Container getContainer(string $name)Get a Container instance whose rows can be processed using a Row objectGSResult - gsGetContainerGeneral (GSGridStore *store, const GSChar *name, GSContainer - **container)         
void drop_container(string $containerName)Delete +   
void dropContainer(string $name)Delete a Container with the specified nameGSResult - gsDropContainer (GSGridStore *store, const GSChar *name)  
ContainerInfo get_container_info(string - $containerName)Get +
ContainerInfo getContainerInfo(string $name)Get information related to a Container with the specified nameGSResult - gsGetContainerInfo (GSGridStore *store, const GSChar *name, GSContainerInfo - *info, GSBool *exists)
PartitionController get_partition_controller()Returns - PartitionController corresponding to GridDB clusterGSResult - gsGetPartitionController (GSGridStore *store, GSPartitionController - **partitionController)
StoreFactoryStoreFactory - StoreFactory.get_default()Returns +   
PartitionController partitionControllerRead-only + attribute  
StoreFactory@staticmethod StoreFactory getInstance()Returns a default StoreFactory instanceGSGridStoreFactory* - gsGetDefaultFactory ()
Store get_store(array $StoreProperties)Returns - a Store with the specified propertiesGSResult - gsGetGridStore (GSGridStoreFactory *factory, const GSPropertyEntry - *properties, size_t propertyCount, GSGridStore **store)
void set_properties(array $propslist)Changes - the settings for specified FactoryGSResult - gsSetFactoryProperties (GSGridStoreFactory *factory, const GSPropertyEntry - *properties, size_t propertyCount)
string get_version()Return +   
Store getStore(array[string $name => object $value] $options + )
+
+ In that, $options is:
+ - host=NULL: A destination host name
+ - port=NULL: A destination port number
+ - clusterName=NULL: A cluster name
+ - database=NULL: Name of the database to be connected
+ - username=NULL: A user name
+ - password=NULL: A password for user authentication
+ - notificationMember=NULL: A list of address and port pairs in + cluster
+ - notificationProvider=NULL: A URL of address provider
+
+
Returns + a Store with the specified properties
+
+ Note: If this host is multicast address, host/port means + notificationAddress/notificationPort for C Client. 
$options + = ["host" => $argv[1],
+                      "port" + => $argv[2],
+                      + "clusterName" => $argv[3],
+                      + "username" => $argv[4],
+                      + "password" => $argv[5]]
+
 
string getVersion()Returns the current version of clientNA
TimestampUtilsstatic - GSTimestamp current()Returns - the current timeGSTimestamp - gsCurrentTime ()
static GSTimestamp add_time(GSTimestamp - $timestamp, int $amount, GSTimeUnit $timeUnit)Adds - a specific value to the specified timeGSTimestamp - gsAddTime (GSTimestamp timestamp, int32_t amount, GSTimeUnit timeUnit)
static string format_time(GSTimestamp - $timestamp, int $bufSize)Returns - the string representing the specified time, according to the TIMESTAMP value - notation of TQLsize_t - gsFormatTime (GSTimestamp timestamp, GSChar *strBuf, size_t bufSize)
static GSTimestamp parse(string $str)Returns - the GSTimestampa value corresponding to the specified string, according to - the TIMESTAMP value notation of TQLGSBool - gsParseTime (const GSChar *str, GSTimestamp *timestamp)  
ContainerInfoContainerInfo(array[string + $name => object $value] $options)
+
+ In that, $options is:
+ - name=NULL: Name of container.
+ - columnInfoArray=NULL: List of the information of Columns
+ - type=ContainerType::COLLECTION: Type of container
+ - rowKey=True: The boolean value indicating whether the Row key Column is + assigned
+ - expiration=NULL: expiration information of a row
Constructor$options + =
+ ["name" => "containerName",
+ "columnInfoArray" => [["id", Type::INTEGER],
+                                         + ["productName", Type::STRING],
+                                         + ["count", Type::INTEGER]],
+ "type" => ContainerType::COLLECTION,
+ "rowKey" => True,
+ "expiration" => [7, TimeUnit::DAY, 8]]
+
 
string nameattribute  
array[array[string, Type]] columnInfoArray
+
+
attribute[["ts", + Type::TIMESTAMP],
+ ["val", Type::LONG,]]
[["ts", + Type::TIMESTAMP],
+ ["val", Type::LONG]]
ContainerType typeattribute  
boolean rowKeyattribute  
ExpirationInfo expirationattribute  
ExpirationInfoExpirationInfo(int + $time, TimeUnit $unit, int $divisionCount)Constructor  
int timeattribute  
TimeUnit unitattribute  
int divisionCountattribute  
TimestampUtils@staticmethod int getTimeMillis(DateTime $dt)Calculate + integer-type timestamp in millisecond from DateTime object  
diff --git a/docs/PHPAPIReference.files/sheet003.htm b/docs/PHPAPIReference.files/sheet003.htm index 906ca38..99c84e5 100644 --- a/docs/PHPAPIReference.files/sheet003.htm +++ b/docs/PHPAPIReference.files/sheet003.htm @@ -16,8 +16,8 @@ mso-displayed-thousand-separator:"\,";} @page {margin:.75in .7in .75in .7in; - mso-header-margin:.3in; - mso-footer-margin:.3in;} + mso-header-margin:.51in; + mso-footer-margin:.51in;} ruby {ruby-align:left;} rt @@ -26,8 +26,8 @@ font-weight:400; font-style:normal; text-decoration:none; - font-family:"MS Pゴシック", monospace; - mso-font-charset:128; + font-family:Calibri, sans-serif; + mso-font-charset:0; mso-char-type:katakana; display:none;} --> @@ -54,46 +54,5175 @@ - + - - - - - - +
data - typevalue
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + - - - - + GS_TYPE_BLOB, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeValueOld value
GSContainerTypeGS_CONTAINER_COLLECTION,
- GS_CONTAINER_TIME_SERIES
GSIndexTypeFlagsGS_INDEX_FLAG_TREE,
- GS_INDEX_FLAG_HASH
ContainerTypeContainerType::COLLECTION,
+ ContainerType::TIME_SERIES
GS_CONTAINER_COLLECTION,
+ GS_CONTAINER_TIME_SERIES
GSTimestampmilliseconds since - the UNIX epoch (January 1, 1970 00:00:00 UTC) with int type
IndexTypeIndexType::TREE,
+ IndexType::HASH,
+ IndexType::DEFAULT_TYPE
GS_INDEX_FLAG_TREE,
+ GS_INDEX_FLAG_HASH,
+ GS_INDEX_FLAG_DEFAULT
GSRowSetTypeGS_ROW_SET_CONTAINER_ROWS,
- GS_ROW_SET_AGGREGATION_RESULT,
RowSetTypeRowSetType::CONTAINER_ROWS,
+ RowSetType::AGGREGATION_RESULT,
+ RowSetType::QUERY_ANALYSIS
GS_ROW_SET_CONTAINER_ROWS,
+ GS_ROW_SET_AGGREGATION_RESULT,
+ GS_ROW_SET_QUERY_ANALYSIS
GSResultThe type of result code for GridDB instructions with int type
GSTypeGS_TYPE_STRING,
+
TypeType::STRING,
+ Type::BOOL,
+ Type::BYTE,
+ Type::SHORT,
+ Type::INTEGER,
+ Type::LONG,
+ Type::FLOAT,
+ Type::DOUBLE,
+ Type::TIMESTAMP,
+ Type::BLOB
GS_TYPE_STRING,
GS_TYPE_BOOL,
GS_TYPE_BYTE,
GS_TYPE_SHORT,
@@ -102,26 +5231,4126 @@ GS_TYPE_FLOAT,
GS_TYPE_DOUBLE,
GS_TYPE_TIMESTAMP,
- GS_TYPE_BLOB
GSFetchOptionGS_FETCH_LIMIT
GSTimeUnitGS_TIME_UNIT_YEAR,
+
TimeUnitTimeUnit::YEAR,
+ TimeUnit::MONTH,
+ TimeUnit::DAY,
+ TimeUnit::HOUR,
+ TimeUnit::MINUTE,
+ TimeUnit::SECOND,
+ TimeUnit::MILLISECOND
GS_TIME_UNIT_YEAR,
GS_TIME_UNIT_MONTH,
GS_TIME_UNIT_DAY,
GS_TIME_UNIT_HOUR,
GS_TIME_UNIT_MINUTE,
GS_TIME_UNIT_SECOND,
GS_TIME_UNIT_MILLISECOND
TypeOptionTypeOption::NULLABLE,
+ TypeOption::NOT_NULL
GS_TYPE_OPTION_NULLABLE,
+ GS_TYPE_OPTION_NOT_NULL
diff --git a/docs/PHPAPIReference.files/sheet004.htm b/docs/PHPAPIReference.files/sheet004.htm index f3cceee..d0744a3 100644 --- a/docs/PHPAPIReference.files/sheet004.htm +++ b/docs/PHPAPIReference.files/sheet004.htm @@ -16,8 +16,8 @@ mso-displayed-thousand-separator:"\,";} @page {margin:.75in .7in .75in .7in; - mso-header-margin:.3in; - mso-footer-margin:.3in;} + mso-header-margin:.51in; + mso-footer-margin:.51in;} ruby {ruby-align:left;} rt @@ -26,8 +26,8 @@ font-weight:400; font-style:normal; text-decoration:none; - font-family:"MS Pゴシック", monospace; - mso-font-charset:128; + font-family:Calibri, sans-serif; + mso-font-charset:0; mso-char-type:katakana; display:none;} --> @@ -56,129 +56,167 @@ - - - - - - +
Correspondence table about primitive data type between C Client - and PHP Client
+ + + + + + + + + + - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + - - - - - - - + + - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + - - - - - - - + + + + - - - - - - - + + + + - - - - - - - + + + + - - - - - - - + + + + - - - - - - - + + + + + - - - - - - + + + + + + + + + + + + +
 ExampleConverted + data-type (GS_TYPE_XXX)
GridDB data typeC clientPHP client
BOOLBYTESHORTINTEGERLONGFLOATDOUBLESTRINGTIMESTAMPBLOB
STRINGGSChar*string
Input data-typeint3   
BOOLGSBoolbool
string"yamada"        
BYTEint8_tint
$contents = fread($handle, filesize($filename))
SHORTint16_tint
float0.1        
INTEGERint32_tint
booleantrue         
LONGint64_tint
datetimenew DateTime()         
FLOATfloatfloat
DOUBLEdoublefloat
TIMESTAMPGSTimestampGSTimestamp
BLOBGSBlobstring
   
 size_tint
`
diff --git a/docs/PHPAPIReference.files/stylesheet.css b/docs/PHPAPIReference.files/stylesheet.css index fd882f7..8f55a50 100644 --- a/docs/PHPAPIReference.files/stylesheet.css +++ b/docs/PHPAPIReference.files/stylesheet.css @@ -8,7 +8,7 @@ br {mso-data-placement:same-cell;} ruby {ruby-align:left;} -.style0 +.style17 {mso-number-format:General; text-align:general; vertical-align:middle; @@ -25,8 +25,50 @@ ruby mso-font-charset:128; border:none; mso-protection:locked visible; + mso-style-name:"Normal 3";} +.style0 + {mso-number-format:General; + text-align:general; + vertical-align:middle; + white-space:nowrap; + mso-rotate:0; + mso-background-source:auto; + mso-pattern:auto; + color:black; + font-size:11.0pt; + font-weight:400; + font-style:normal; + text-decoration:none; + font-family:Calibri, sans-serif; + mso-font-charset:0; + border:none; + mso-protection:locked visible; mso-style-name:標準; mso-style-id:0;} +.font7 + {color:windowtext; + font-size:8.0pt; + font-weight:400; + font-style:normal; + text-decoration:none; + font-family:Calibri, sans-serif; + mso-font-charset:0;} +.font8 + {color:windowtext; + font-size:8.0pt; + font-weight:400; + font-style:normal; + text-decoration:none; + font-family:Arial, sans-serif; + mso-font-charset:0;} +.font17 + {color:windowtext; + font-size:8.0pt; + font-weight:400; + font-style:normal; + text-decoration:none; + font-family:Calibri, sans-serif; + mso-font-charset:0;} td {mso-style-parent:style0; padding-top:1px; @@ -38,8 +80,8 @@ td font-weight:400; font-style:normal; text-decoration:none; - font-family:"MS Pゴシック", monospace; - mso-font-charset:128; + font-family:Calibri, sans-serif; + mso-font-charset:0; mso-number-format:General; text-align:general; vertical-align:middle; @@ -49,101 +91,383 @@ td mso-protection:locked visible; white-space:nowrap; mso-rotate:0;} -.xl65 +.xl69 + {mso-style-parent:style0; + color:windowtext; + border:.5pt solid windowtext;} +.xl70 + {mso-style-parent:style0; + color:windowtext; + border:.5pt solid windowtext;} +.xl71 + {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; + white-space:normal;} +.xl72 + {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; + vertical-align:top; + white-space:normal;} +.xl73 + {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; + vertical-align:top; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + white-space:normal;} +.xl74 + {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + white-space:normal;} +.xl75 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; + text-align:left; + white-space:normal;} +.xl76 + {mso-style-parent:style0; + color:windowtext;} +.xl77 + {mso-style-parent:style0; + color:windowtext; border:.5pt solid windowtext; white-space:normal;} -.xl66 +.xl78 {mso-style-parent:style0; + text-align:right;} +.xl79 + {mso-style-parent:style0; + text-align:center; border:.5pt solid windowtext;} -.xl67 +.xl80 {mso-style-parent:style0; - border:.5pt solid windowtext; - background:#DDEBF7; - mso-pattern:black none;} -.xl68 + text-align:right; + border:.5pt solid windowtext;} +.xl81 + {mso-style-parent:style0; + border:.5pt solid windowtext;} +.xl82 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; border:.5pt solid windowtext; - background:#BDD7EE; - mso-pattern:black none; white-space:normal;} -.xl69 +.xl83 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; + vertical-align:top; + border:.5pt solid windowtext; white-space:normal;} -.xl70 - {mso-style-parent:style0; - color:windowtext;} -.xl71 +.xl84 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; - border-top:none; - border-right:.5pt solid windowtext; - border-bottom:none; - border-left:.5pt solid windowtext; + vertical-align:top; + border:.5pt solid windowtext; + background:white; + mso-pattern:black none; white-space:normal;} -.xl72 +.xl85 {mso-style-parent:style0; color:windowtext; border:.5pt solid windowtext; + background:white; + mso-pattern:black none;} +.xl86 + {mso-style-parent:style0; + border:.5pt solid windowtext; background:#DDEBF7; + mso-pattern:black none; + white-space:normal;} +.xl87 + {mso-style-parent:style0; + font-size:9.0pt; + border:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none; + white-space:normal;} +.xl88 + {mso-style-parent:style0; + color:windowtext; + border:.5pt solid windowtext; + background:#FCE4D6; mso-pattern:black none;} -.xl73 +.xl89 + {mso-style-parent:style0; + border:.5pt solid windowtext; + background:#FCE4D6; + mso-pattern:black none;} +.xl90 {mso-style-parent:style0; color:windowtext; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128;} +.xl91 + {mso-style-parent:style0; + color:black; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; border:.5pt solid windowtext;} -.xl74 +.xl92 + {mso-style-parent:style0; + color:black; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; + border:.5pt solid windowtext; + white-space:normal;} +.xl93 + {mso-style-parent:style0; + color:black; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; + vertical-align:top; + border:.5pt solid windowtext; + white-space:normal;} +.xl94 {mso-style-parent:style0; color:windowtext; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; border:.5pt solid windowtext; white-space:normal;} -.xl75 +.xl95 + {mso-style-parent:style0; + border:.5pt solid windowtext; + white-space:normal;} +.xl96 + {mso-style-parent:style0; + font-weight:700; + text-align:center; + border:.5pt solid windowtext; + background:#DEEBF7; + mso-pattern:#CCFFFF none;} +.xl97 {mso-style-parent:style0; color:windowtext; - border:.5pt solid windowtext;} -.xl76 + font-size:8.0pt; + font-weight:700; + text-align:center; + vertical-align:top; + border:.5pt solid windowtext; + background:#BDD7EE; + mso-pattern:#99CCFF none; + white-space:normal;} +.xl98 + {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; + font-weight:700; + text-align:center; + vertical-align:top; + white-space:normal;} +.xl99 + {mso-style-parent:style0; + color:windowtext; + font-weight:700; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128;} +.xl100 {mso-style-parent:style0; + color:windowtext; + font-size:8.0pt; border:.5pt solid windowtext; - background:#DDEBF7; + background:white; mso-pattern:black none; white-space:normal;} -.xl77 +.xl101 {mso-style-parent:style0; + color:windowtext; + text-align:right; + border:.5pt solid windowtext;} +.xl102 + {mso-style-parent:style0; + color:windowtext; + font-size:10.0pt; + font-family:", sans-serif; + mso-font-charset:0; + text-align:right; border:.5pt solid windowtext; white-space:normal;} -.xl78 +.xl103 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; text-align:left; - border-top:.5pt solid windowtext; - border-right:.5pt solid windowtext; - border-bottom:none; - border-left:.5pt solid windowtext; + border:.5pt solid windowtext; white-space:normal;} -.xl79 +.xl104 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; text-align:left; border-top:none; border-right:.5pt solid windowtext; - border-bottom:none; + border-bottom:.5pt solid windowtext; border-left:.5pt solid windowtext; white-space:normal;} -.xl80 +.xl105 {mso-style-parent:style0; color:windowtext; font-size:8.0pt; text-align:left; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + white-space:normal;} +.xl106 + {mso-style-parent:style0; + color:windowtext; + font-weight:700; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; + text-align:center; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none;} +.xl107 + {mso-style-parent:style0; + color:windowtext; + font-weight:700; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; + text-align:center; border-top:none; border-right:.5pt solid windowtext; border-bottom:.5pt solid windowtext; border-left:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none;} +.xl108 + {mso-style-parent:style0; + color:windowtext; + font-weight:700; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128; + text-align:center; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none; white-space:normal;} +.xl109 + {mso-style-parent:style0; + font-weight:700; + text-align:center; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:.5pt solid windowtext; + border-left:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none;} +.xl110 + {mso-style-parent:style0; + text-align:center; + border:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none;} +.xl111 + {mso-style-parent:style0; + font-weight:700; + text-align:center; + border:.5pt solid windowtext; + background:#DDEBF7; + mso-pattern:black none; + white-space:normal;} +.xl112 + {mso-style-parent:style0; + font-weight:700; + text-align:center; + border:.5pt solid windowtext; + background:#FCE4D6; + mso-pattern:black none; + white-space:normal;} +.xl113 + {mso-style-parent:style0; + text-align:center; + vertical-align:bottom; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext;} +.xl114 + {mso-style-parent:style0; + text-align:center; + vertical-align:bottom; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:.5pt solid windowtext; + border-left:.5pt solid windowtext;} +.xl115 + {mso-style-parent:style0; + text-align:center; + vertical-align:top; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext;} +.xl116 + {mso-style-parent:style0; + text-align:center; + vertical-align:top; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:.5pt solid windowtext; + border-left:.5pt solid windowtext;} +.xl117 + {mso-style-parent:style0; + text-align:center; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext;} +.xl118 + {mso-style-parent:style0; + text-align:center; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:.5pt solid windowtext; + border-left:.5pt solid windowtext;} +.xl119 + {mso-style-parent:style0; + text-align:left; + border-top:.5pt solid windowtext; + border-right:.5pt solid windowtext; + border-bottom:none; + border-left:.5pt solid windowtext; + background:#FCE4D6; + mso-pattern:black none;} +.xl120 + {mso-style-parent:style0; + text-align:left; + border-top:none; + border-right:.5pt solid windowtext; + border-bottom:.5pt solid windowtext; + border-left:.5pt solid windowtext; + background:#FCE4D6; + mso-pattern:black none;} +.xl121 + {mso-style-parent:style0; + color:windowtext;} +.xl122 + {mso-style-parent:style17; + color:windowtext; + font-family:"MS Pゴシック", monospace; + mso-font-charset:128;} diff --git a/docs/PHPAPIReference.files/tabstrip.htm b/docs/PHPAPIReference.files/tabstrip.htm index e572c46..444f141 100644 --- a/docs/PHPAPIReference.files/tabstrip.htm +++ b/docs/PHPAPIReference.files/tabstrip.htm @@ -24,10 +24,10 @@ - + - - + +
 class list  Class List   PHP Client API  data type list  table(data type)  Data Type List  Data -Type Mapping 
diff --git a/docs/PHPAPIReference.htm b/docs/PHPAPIReference.htm index 8151b6f..e449ba1 100644 --- a/docs/PHPAPIReference.htm +++ b/docs/PHPAPIReference.htm @@ -22,10 +22,10 @@ var c_lTabs=4; var c_rgszSh=new Array(c_lTabs); - c_rgszSh[0] = "class list"; + c_rgszSh[0] = "Class List"; c_rgszSh[1] = "PHP Client API"; - c_rgszSh[2] = "data type list"; - c_rgszSh[3] = "table(data type)"; + c_rgszSh[2] = "Data Type List"; + c_rgszSh[3] = "Data -Type Mapping"; @@ -303,7 +303,7 @@ - class list + Class List @@ -311,19 +311,20 @@ - data type list + Data Type List - table(data type) + Data -Type Mapping - 2655 - 19170 - 0 - 15 + 15840 + 29040 + -120 + -120 + 790 False False From 43b5fce7cfe13301dfc1eb936b0c6ce00f3376e1 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:52:42 +0900 Subject: [PATCH 16/22] update samples for 0.8 --- sample/BlobData.php | 63 ++++++-------- sample/Connect.php | 43 ++++----- sample/ContainerNames.php | 38 ++++---- sample/CreateCollection.php | 40 ++++----- sample/CreateIndex.php | 44 +++++----- sample/CreateTimeSeries.php | 37 ++++---- sample/GetRow.php | 81 ++++++----------- sample/PutRow.php | 54 +++++------- sample/RemoveRowByRowkey.php | 68 +++++++-------- sample/RemoveRowByTQL.php | 82 +++++++++--------- sample/TQLAggregation.php | 86 ++++++++---------- sample/TQLSelect.php | 77 +++++++---------- sample/TQLTimeseries.php | 134 +++++++++++------------------ sample/TimeSeriesRowExpiration.php | 64 ++++++++------ sample/UpdateRowByTQL.php | 98 ++++++++------------- sample/sample1.php | 106 +++++++++++------------ sample/sample1_web.php | 121 +++++++++++++------------- sample/sample2.php | 76 ++++++++-------- sample/sample3.php | 74 ++++++++-------- 19 files changed, 629 insertions(+), 757 deletions(-) diff --git a/sample/BlobData.php b/sample/BlobData.php index 376b70c..8e31ef7 100644 --- a/sample/BlobData.php +++ b/sample/BlobData.php @@ -1,56 +1,49 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + "username" => $argv[4], + "password" => $argv[5]]); // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("blob" => GS_TYPE_BLOB)), - GS_CONTAINER_COLLECTION - ); + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["blob", Type::BLOB]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $col = $gridstore->putContainer($conInfo); echo("Create Collection name=$containerName\n"); // Register string data - // (1)Read string data file - $blobString = file_get_contents('BlobData.php'); - - // (2)Create and set row data - $row = $col->create_row(); //Create row for refer - $row->set_field_by_integer(0, 0); - $row->set_field_by_blob(1, $blobString); - - // (3)Put row - $col->put_row($row); + // (1)Get contents of a file into a string + $filename = "sample/BlobData.php"; + $handle = fopen($filename, "rb"); + $blobString = fread($handle, filesize($filename)); + fclose($handle); + + //(2)Register a row + $col->put([0, $blobString]); echo("Put Row (Blob)\n"); // Get string data file from row - // (1)Create an empty Row object - $row1 = $col->create_row(); - - // (2)Specify row key and get row - $col->get_row_by_integer(0, false, $row1); - $blob = $row1->get_field_as_blob(1); - echo("Get Row (Blob string data=$blob"); + $row = $col->get(0); + echo("Get Row (Blob content: \n$row[1]\nBlob size = ".strlen($row[1]).")\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/Connect.php b/sample/Connect.php index fb3a236..059ee5f 100644 --- a/sample/Connect.php +++ b/sample/Connect.php @@ -1,38 +1,41 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); // Fixed list method - //$gridstore = $factory->get_store(array("notificationMember" => $argv[1], - // "clusterName" => $argv[2], - // "user" => $argv[3], - // "password" => $argv[4] - // )); +// $gridstore = $factory->getStore(array("notificationMember" => $argv[1], +// "clusterName" => $argv[2], +// "username" => $argv[3], +// "password" => $argv[4] +// )); // Provider method - //$gridstore = $factory->get_store(array("notificationProvider" => $argv[1], - // "clusterName" => $argv[2], - // "user" => $argv[3], - // "password" => $argv[4] - // )); +// $gridstore = $factory->getStore(array("notificationProvider" => $argv[1], +// "clusterName" => $argv[2], +// "username" => $argv[3], +// "password" => $argv[4] +// )); // (2)When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); + $gridstore->getContainer("containerName"); echo("Connect to Cluster\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } -?> +?> \ No newline at end of file diff --git a/sample/ContainerNames.php b/sample/ContainerNames.php index b7eabe4..74b4b63 100644 --- a/sample/ContainerNames.php +++ b/sample/ContainerNames.php @@ -1,36 +1,36 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); - - // Get a list of container names + // Get an array of container names // (1)Get partition controller and number of partitions - $pc = $gridstore->get_partition_controller(); - $pcCount = $pc->get_partition_count(); + $pc = $gridstore->partitionController; + $pcCount = $pc->partitionCount; - // (2)Loop by the number of partitions to get a list of container names + //(2)Loop by the number of partitions to get an array of container names for ($i = 0; $i < $pcCount; $i++) { - $nameList = $pc->get_partition_container_names($i, 0); - $nameCount = sizeof($nameList); + $arrayContainerNames = $pc->getContainerNames($i, 0); + $nameCount = sizeof($arrayContainerNames); for ($j = 0; $j < $nameCount; $j++) { - echo("$nameList[$j]\n"); + echo("$arrayContainerNames[$j]\n"); } } + echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/CreateCollection.php b/sample/CreateCollection.php index 17a02a5..7df2bda 100644 --- a/sample/CreateCollection.php +++ b/sample/CreateCollection.php @@ -1,35 +1,35 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + "username" => $argv[4], + "password" => $argv[5]]); // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); - echo("Create Collection name=$containerName\n"); + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $col = $gridstore->putContainer($conInfo); + echo("Create Collection name = $containerName\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/CreateIndex.php b/sample/CreateIndex.php index 909a282..e413b24 100644 --- a/sample/CreateIndex.php +++ b/sample/CreateIndex.php @@ -1,45 +1,45 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + "username" => $argv[4], + "password" => $argv[5]]); // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $gridstore->putContainer($conInfo); echo("Create Collection name=$containerName\n"); // Get the container - $container = $gridstore->get_container($containerName); - if ($container == null) { + $col = $gridstore->getContainer($containerName); + if ($col == null) { echo("ERROR Container not found. name=$containerName\n"); } // Create an index - $container->create_index("count", GS_INDEX_FLAG_HASH); + $col->createIndex("count", IndexType::HASH, "hash_index"); echo("Create Index\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/CreateTimeSeries.php b/sample/CreateTimeSeries.php index fd79f0c..0d357dc 100644 --- a/sample/CreateTimeSeries.php +++ b/sample/CreateTimeSeries.php @@ -1,34 +1,33 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a time series container + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["date", Type::TIMESTAMP], + ["value", Type::DOUBLE]], + "type" => ContainerType::TIME_SERIES]); - // Create a timeseries container - $col = $gridstore->put_container( - $containerName, - array(array("date" => GS_TYPE_TIMESTAMP), - array("value" => GS_TYPE_DOUBLE)), - GS_CONTAINER_TIME_SERIES - ); - echo("Create Timeseries name=$containerName\n"); + $ts = $gridstore->putContainer($conInfo); + echo("Create Collection name = $containerName\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/GetRow.php b/sample/GetRow.php index 1e5b3f4..a15506f 100644 --- a/sample/GetRow.php +++ b/sample/GetRow.php @@ -1,78 +1,49 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + "username" => $argv[4], + "password" => $argv[5]]); // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); - echo("Sample data generation: Create Collection name=$containerName\n"); + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); - // Create and set row data - for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); + $col = $gridstore->putContainer($conInfo); + echo("Create Collection name=$containerName\n"); - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - $col->put_row($rowList[$i]); - } - echo("Sample data generation: Put Rows count=$rowCount\n"); + //Register the row + $col->put([0, "notebook PC", 108]); // Get a row // (1)Get the container - $col1 = $gridstore->get_container($containerName); - if ($col1 == null) { + $col1 = $gridstore->getContainer($containerName); + if ($col == null) { echo("ERROR Container not found. name=$containerName\n"); } - for ($i = 0; $i < $rowCount; $i++) { - // (2)Create an empty Row object - $rowList1[$i] = $col1->create_row(); - - // (3)Specify row key and get row - $col1->get_row_by_integer($i, false, $rowList1[$i]); - - //(4)Get value from Row - $id[$i] = $rowList1[$i]->get_field_as_integer(0); - $productName[$i] = $rowList1[$i]->get_field_as_string(1); - $count[$i] = $rowList1[$i]->get_field_as_integer(2); - } - - echo("Get Row (id=$id[0], productName=$productName[0], count=$count[0])\n"); + // (2)Get the value from row + $row = $col1->get(0); + echo("Get Row (id = $row[0], productName = $row[1], count = $row[2])\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/PutRow.php b/sample/PutRow.php index bb6ee4f..99845ea 100644 --- a/sample/PutRow.php +++ b/sample/PutRow.php @@ -1,54 +1,46 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + "username" => $argv[4], + "password" => $argv[5]]); // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $gridstore->putContainer($conInfo); echo("Create Collection name=$containerName\n"); // Register a row // (1)Get the container - $col1 = $gridstore->get_container($containerName); - if ($col1 == null) { + $col = $gridstore->getContainer($containerName); + if ($col == null) { echo("ERROR Container not found. name=$containerName\n"); } - // (2)Create an empty Row object - $row = $col1->create_row(); - - // (3)Set column value - $row->set_field_by_integer(0, 0); - $row->set_field_by_string(1, "display"); - $row->set_field_by_integer(2, 150); - - // (4)Register the row - $col1->put_row($row); +// (2)Register the row + $col->put([0, "display", 150]); echo("Put Row\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/RemoveRowByRowkey.php b/sample/RemoveRowByRowkey.php index 026fb73..4338eb0 100644 --- a/sample/RemoveRowByRowkey.php +++ b/sample/RemoveRowByRowkey.php @@ -1,63 +1,55 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); - - // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); - echo("Sample data generation: Create Collection name=$containerName\n"); - - // Create and set row data + "username" => $argv[4], + "password" => $argv[5]]); + + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $col = $gridstore->putContainer($conInfo); + echo("Create Collection name=$containerName\n"); + + //Register rows with multiple times for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); - - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - $col->put_row($rowList[$i]); + $col->put([$i, $nameList[$i], $numberList[$i]]); } echo("Sample data generation: Put Rows count=$rowCount\n"); - // Delete a row + // Get a row // (1)Get the container - $col1 = $gridstore->get_container($containerName); + $col1 = $gridstore->getContainer($containerName); if ($col1 == null) { echo("ERROR Container not found. name=$containerName\n"); } // (2)Delete row by specifying Row key - $col1->delete_row_by_integer(3); + $col1->remove(3); echo("Delete Row rowkey=3\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/RemoveRowByTQL.php b/sample/RemoveRowByTQL.php index f814015..5c1c3a2 100644 --- a/sample/RemoveRowByTQL.php +++ b/sample/RemoveRowByTQL.php @@ -1,83 +1,81 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); - // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); + $col = $gridstore->putContainer($conInfo); echo("Sample data generation: Create Collection name=$containerName\n"); - // Create and set row data + //Register rows with multiple times for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); - - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - $col->put_row($rowList[$i]); + $col->put([$i, $nameList[$i], $numberList[$i]]); } echo("Sample data generation: Put Rows count=$rowCount\n"); // Delete a row + // Get a row // (1)Get the container - $col1 = $gridstore->get_container($containerName); + $col1 = $gridstore->getContainer($containerName); if ($col1 == null) { echo("ERROR Container not found. name=$containerName\n"); } // (2)Change auto commit mode to false - $col1->set_auto_commit(false); + $col1->setAutoCommit(false); // (3)Execute search with TQL - echo("Delete query : $queryString\n"); + echo("Delete query: $queryString\n"); $query = $col1->query($queryString); $rs = $query->fetch($update); // (4)Delete a row that was found in the search - while ($rs->has_next()) { - // Create an empty row object - $rrow = $col1->create_row(); - // Get a row - $rs->get_next($rrow); - // Delete the row - $rs->delete_current(); + while ($rs->hasNext()) { + $rs->next(); + $rs->remove(); } // (5)Commit $col1->commit(); - echo("Delete Row\n"); + echo("Finish to delete Row\n"); + + // Check data after deleting + echo("Get row after deleting:\n"); + for($i = 0; $i < $rowCount; $i++){ + $row = $col1->get($i); + if ($row) { + echo("Get row with rowkey = $i : (".$row[0]. ", ".$row[1].", ".$row[2].")\n"); + } + } echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/TQLAggregation.php b/sample/TQLAggregation.php index e61fffb..a6081c8 100644 --- a/sample/TQLAggregation.php +++ b/sample/TQLAggregation.php @@ -1,74 +1,64 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); - // Create a collection container - $col = $gridstore->put_container($containerName, array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION); + $col = $gridstore->putContainer($conInfo); echo("Sample data generation: Create Collection name=$containerName\n"); - // Create and set row data - for($i = 0; $i < $rowCount; $i++){ - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); - - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - echo("Sample data generation: row=($i, $nameList[$i], $numberList[$i])\n"); - $col->put_row($rowList[$i]); + //Register rows with multiple times + for ($i = 0; $i < $rowCount; $i++) { + $col->put([$i, $nameList[$i], $numberList[$i]]); + echo("Sample data generation: row = ($i, $nameList[$i], $numberList[$i])\n"); } - echo("Sample data generation: Put Rows count=$rowCount\n"); // Search by TQL // (1)Get the container - $col1 = $gridstore->get_container($containerName); - if($col1 == NULL){ + $col1 = $gridstore->getContainer($containerName); + if ($col1 == null) { echo("ERROR Container not found. name=$containerName\n"); } - // (2)Executing aggregation operation with TQL - echo("TQL query : $queryStr\n"); - $query = $col1->query($queryStr); - $rs = $query->fetch($update); + // (2)Execute aggregation operation with TQL + echo("TQL query: $queryString\n"); + $query = $col1->query($queryString); + $rs = $query->fetch(); // (3)Get the result - while ($rs->has_next()){ - // (4)Get the result of the aggregation operation - $aggregationResult = $rs->get_next_aggregation(); - $max = $aggregationResult->get_long(); - echo("TQL result: max=$max\n"); + while ($rs->hasNext()) { + $aggregationResult = $rs->next(); + $max = $aggregationResult->get(TYPE::LONG); + echo("TQL result: max = $max\n"); } echo("success!\n"); - - } catch(GSException $e){ - echo($e->what()."\n"); - echo($e->get_code()."\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/TQLSelect.php b/sample/TQLSelect.php index bb6e570..e1de55f 100644 --- a/sample/TQLSelect.php +++ b/sample/TQLSelect.php @@ -1,79 +1,64 @@ = 50 ORDER BY id"; - $update = false; try { // Get GridStore object - $gridstore = $factory->get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); - // Create a collection container - $col = $gridstore->put_container( - $containerName, - array(array("id" => GS_TYPE_INTEGER), - array("productName" => GS_TYPE_STRING), - array("count" => GS_TYPE_INTEGER)), - GS_CONTAINER_COLLECTION - ); + $col = $gridstore->putContainer($conInfo); echo("Sample data generation: Create Collection name=$containerName\n"); - // Create and set row data + //Register rows with multiple times for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); - - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - $col->put_row($rowList[$i]); + $col->put([$i, $nameList[$i], $numberList[$i]]); } echo("Sample data generation: Put Rows count=$rowCount\n"); // Search by TQL // (1)Get the container - $col1 = $gridstore->get_container($containerName); + $col1 = $gridstore->getContainer($containerName); if ($col1 == null) { echo("ERROR Container not found. name=$containerName\n"); } // (2)Execute search with TQL - echo("TQL query : $queryString\n"); + echo("TQL query: $queryString\n"); $query = $col1->query($queryString); - $rs = $query->fetch($update); - - // (3)Create an empty row object - $rrow = $col1->create_row(); + $rs = $query->fetch(); - // (4)Get the result - while ($rs->has_next()) { - // (5)Get row - $rs->get_next($rrow); - $id = $rrow->get_field_as_integer(0); - $productName = $rrow->get_field_as_string(1); - $count = $rrow->get_field_as_integer(2); - echo sprintf("TQL result: id=%d, productName=%s, count=%d\n", $id, $productName, $count); + // (3)Get results + while ($rs->hasNext()) { + // (4)Get row + $row = $rs->next(); + echo("TQL result: id=$row[0], productName=$row[1], count=$row[2]\n"); } echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/TQLTimeseries.php b/sample/TQLTimeseries.php index a4592ff..f6bc0dc 100644 --- a/sample/TQLTimeseries.php +++ b/sample/TQLTimeseries.php @@ -1,76 +1,58 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a timeseries + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["date", Type::TIMESTAMP], + ["value1", Type::INTEGER], + ["value2", Type::DOUBLE]], + "type" => ContainerType::TIME_SERIES]); - // Create a timeseries container - $columnDate = array("date" => GS_TYPE_TIMESTAMP); - $columnValue1 = array("value1" => GS_TYPE_INTEGER); - $columnValue2 = array("value2" => GS_TYPE_DOUBLE); - $columnInfolist = array($columnDate, $columnValue1, $columnValue2); - $ts = $gridstore->put_container($containerName, $columnInfolist, GS_CONTAINER_TIME_SERIES); + $ts = $gridstore->putContainer($conInfo); echo("Sample data generation: Create Collection name=$containerName\n"); + $col1Name = $conInfo->columnInfoArray[0][0]; + $col2Name = $conInfo->columnInfoArray[1][0]; + $col3Name = $conInfo->columnInfoArray[2][0]; + echo("Sample data generation: column=($col1Name, $col2Name, $col3Name)\n"); - // Get names for all columns - foreach ($columnDate as $key => $value) { - $column0 = $key; - }; - foreach ($columnValue1 as $key => $value) { - $column1 = $key; - }; - foreach ($columnValue2 as $key => $value) { - $column2 = $key; - }; - echo("Sample data generation: column=($column0, $column1, $column2)\n"); - - // Create and set row data + // Convert Datetime string to DateTime object + $UTCTime = new DateTimeZone("UTC"); for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $ts->create_row(); - - // (2)Parse time string to timestamp - $timestamp[$i] = TimestampUtils::parse($dateList[$i]); + $dateTimeObjList[$i] = new DateTime($dateTimeStrList[$i], $UTCTime); + } - // (3)Set column value - $rowList[$i]->set_field_by_timestamp(0, $timestamp[$i]); - $rowList[$i]->set_field_by_integer(1, $value1List[$i]); - $rowList[$i]->set_field_by_double(2, $value2List[$i]); - echo sprintf("Sample data generation: row=(%s, %d, %lf)\n", $dateList[$i], $value1List[$i], $value2List[$i]); - $ts->put_row($rowList[$i]); + // Register rows with multiple times + for ($i = 0; $i < $rowCount; $i++) { + $ts->put([$dateTimeObjList[$i], $value1List[$i], $value2List[$i]]); + echo sprintf("Sample data generation: row $i = (%s, %d, %lf)\n", $dateTimeObjList[$i]->format('Y-m-d H:i:s.u'), $value1List[$i], $value2List[$i]); } echo("Sample data generation: Put Rows count=$rowCount\n"); // Aggregation operations specific to time series // Get the container - $ts1 = $gridstore->get_container($containerName); + // (1)Get the container + $ts1 = $gridstore->getContainer($containerName); if ($ts1 == null) { echo("ERROR Container not found. name=$containerName\n"); } @@ -78,14 +60,14 @@ // weighted average TIME_AVG // (1)Execute aggregation operation in TQL echo("TQL query : $queryStr1\n"); - $query = $ts1->query($queryStr1); - $rs = $query->fetch($update); + $query1 = $ts1->query($queryStr1); + $rs1 = $query1->fetch(); // (2)Get the result - while ($rs->has_next()) { + while ($rs1->hasNext()) { // (3)Get the result of the aggregation operation - $aggregationResult = $rs->get_next_aggregation(); - $value = $aggregationResult->get_double(); + $aggregationResult = $rs1->next(); + $value = $aggregationResult->get(TYPE::DOUBLE); echo sprintf("TQL result: %lf\n", $value); } @@ -93,46 +75,34 @@ // TIME_NEXT //(1)Execute aggregation operation in TQL echo("TQL query : $queryStr2\n"); - $query = $ts1->query($queryStr2); - $rs = $query->fetch($update); + $query2 = $ts1->query($queryStr2); + $rs2 = $query2->fetch(); // (2)Get the result - while ($rs->has_next()) { - // Create empty row - $rrow = $ts1->create_row(); - // Get a row - $rs->get_next($rrow); - // Get value - $date = $rrow->get_field_as_timestamp(0); - $value1 = $rrow->get_field_as_integer(1); - $value2 = $rrow->get_field_as_double(2); - $buf = TimestampUtils::format_time($date, $GS_TIME_STRING_SIZE_MAX); - echo sprintf("TQL result: row=(%s, %d, %lf)\n", $buf, $value1, $value2); + while ($rs2->hasNext()) { + $row2 = $rs2->next(); + echo sprintf("TQL result: row=(%s, %d, %lf)\n", $row2[0]->format('Y-m-d H:i:s.u'), $row2[1], $row2[2]); } // Time series specific interpolation operation // TIME_INTERPOLATED // (1)Execute aggregation operation in TQL echo("TQL query : $queryStr3\n"); - $query = $ts1->query($queryStr3); - $rs = $query->fetch($update); + $query3 = $ts1->query($queryStr3); + $rs3 = $query3->fetch(); // (2)Get the result - while ($rs->has_next()) { - // Create empty row - $rrow = $ts1->create_row(); - // Get a row - $rs->get_next($rrow); - // Get value - $date = $rrow->get_field_as_timestamp(0); - $value1 = $rrow->get_field_as_integer(1); - $value2 = $rrow->get_field_as_double(2); - $buf = TimestampUtils::format_time($date, $GS_TIME_STRING_SIZE_MAX); - echo sprintf("TQL result: row=(%s, %d, %lf)\n", $buf, $value1, $value2); + while ($rs3->hasNext()) { + $row3 = $rs3->next(); + echo sprintf("TQL result: row=(%s, %d, %lf)\n", $row3[0]->format('Y-m-d H:i:s.u'), $row3[1], $row3[2]); } echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } -?> +?> \ No newline at end of file diff --git a/sample/TimeSeriesRowExpiration.php b/sample/TimeSeriesRowExpiration.php index ebc8f57..75d83d2 100644 --- a/sample/TimeSeriesRowExpiration.php +++ b/sample/TimeSeriesRowExpiration.php @@ -1,40 +1,50 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); - - // Create a timeseries container - $ts = $gridstore->put_container( - $containerName, - array(array("date" => GS_TYPE_TIMESTAMP), - array("value" => GS_TYPE_DOUBLE)), - GS_CONTAINER_TIME_SERIES, - false, // modifiable = false - true, // rowKeyAssigned = true - false, // columnOrderIgnorable = false - 100, // rowExpirationTime - GS_TIME_UNIT_DAY, // rowExpirationTimeUnit - 5 // expirationDivisionCount - ); - echo("Create TimeSeries & Set Row Expiration name=$containerName\n"); + "username" => $argv[4], + "password" => $argv[5]]); + + // Set row expiration release + $timeProp = new ExpirationInfo(100, TimeUnit::DAY, 5); + + // Create a time series container + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["date", Type::TIMESTAMP], + ["value", Type::DOUBLE]], + "type" => ContainerType::TIME_SERIES, + "rowKey" => true, + "expiration" => $timeProp]); + $ts = $gridstore->putContainer($conInfo); + + // Display attribute name, type and rowKey for ContainerInfo + $conInformation = $gridstore->getContainerInfo($containerName); + echo("ContainerInfo: name = ".$conInformation->name. + ", type = ".(($conInformation->type) ? "TIME_SERIES" : "COLLECTION"). + ", rowKey = ".(($conInformation->rowKey) ? "true" : "false")."\n"); + + // Display atribute time, unit, divisionCount for ExpirationInfo + $expirationInfo = $conInformation->expiration; + echo("ExpirationInfo: time = ".$expirationInfo->time. + " , unit = ".$expirationInfo->unit. + ", divisionCount = ".$expirationInfo->divisionCount."\n"); + + echo("Create TimeSeries & Set Row Expiration name = $containerName\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/UpdateRowByTQL.php b/sample/UpdateRowByTQL.php index 9e2c7e3..9fdaa11 100644 --- a/sample/UpdateRowByTQL.php +++ b/sample/UpdateRowByTQL.php @@ -1,97 +1,75 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - // When operations such as container creation and acquisition are performed, it is connected to the cluster. - $gridstore->get_container("containerName"); - echo("Connect to Cluster\n"); + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); - // Create a collection container - $column0 = array("id" => GS_TYPE_INTEGER); - $column1 = array("productName" => GS_TYPE_STRING); - $column2 = array("count" => GS_TYPE_INTEGER); - $columnInfolist = array($column0, $column1, $column2); - $col = $gridstore->put_container($containerName, $columnInfolist, GS_CONTAINER_COLLECTION); + $col = $gridstore->putContainer($conInfo); echo("Sample data generation: Create Collection name=$containerName\n"); - // Get names for all columns - foreach ($column0 as $key => $value) { - $column0 = $key; - }; - foreach ($column1 as $key => $value) { - $column1 = $key; - }; - foreach ($column2 as $key => $value) { - $column2 = $key; - }; - echo("Sample data generation: column=($column0, $column1, $column2)\n"); - - // Create and set row data + //Register rows with multiple times for ($i = 0; $i < $rowCount; $i++) { - // (1)Create an empty Row object - $rowList[$i] = $col->create_row(); - - // (2)Set the value in the Row object - $rowList[$i]->set_field_by_integer(0, $i); - $rowList[$i]->set_field_by_string(1, $nameList[$i]); - $rowList[$i]->set_field_by_integer(2, $numberList[$i]); - echo("Sample data generation: row=($i, $nameList[$i], $numberList[$i])\n"); - $col->put_row($rowList[$i]); + $col->put([$i, $nameList[$i], $numberList[$i]]); + echo("Sample data generation: row = ($i, $nameList[$i], $numberList[$i])\n"); } echo("Sample data generation: Put Rows count=$rowCount\n"); - // Update a row // (1)Get the container - $col1 = $gridstore->get_container($containerName); + $col1 = $gridstore->getContainer($containerName); if ($col1 == null) { echo("ERROR Container not found. name=$containerName\n"); } // (2)Change auto commit mode to false - $col1->set_auto_commit(false); + $col1->setAutoCommit(false); - // (3)Execute search with TQL - $query = $col1->query($queryStr); - $rs = $query->fetch($update); + //(3)Execute search with TQL + echo("TQL query: $queryString\n"); + $query = $col1->query($queryString); + $rs = $query->fetch(true); // (4)Get the result - while ($rs->has_next()) { - // Create an empty Row object - $rrow = $col1->create_row(); - // Get the row - $rs->get_next($rrow); + while ($rs->hasNext()) { + $row = $rs->next(); // Change the value - $rrow->set_field_by_integer(2, 325); - // Update the row - $rs->update_current($rrow); + $row[2] = 325; + // Update a row + $rs->update($row); } // (5)Commit $col1->commit(); - echo("Update row id=4\n"); + echo("Update row id=$id\n"); echo("success!\n"); } catch (GSException $e) { - echo($e->what()."\n"); - echo($e->get_code()."\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/sample1.php b/sample/sample1.php index bc57a98..8fef0c4 100644 --- a/sample/sample1.php +++ b/sample/sample1.php @@ -1,78 +1,74 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + try { + // Get GridStore object + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); + "username" => $argv[4], + "password" => $argv[5]]); - //Create Collection - $col = $gridstore->put_container("col01", array(array("name" => GS_TYPE_STRING), - array("status" => GS_TYPE_BOOL), - array("count" => GS_TYPE_LONG), - array("lob" => GS_TYPE_BLOB)), - GS_CONTAINER_COLLECTION); + // Create a collection container + $conInfo = new ContainerInfo(["name" => "col01", + "columnInfoArray" => [["name", Type::STRING], + ["status", Type::BOOL], + ["count", Type::LONG], + ["lob", Type::BLOB]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + $gridstore->dropContainer("col01"); + $col = $gridstore->putContainer($conInfo); - //Change auto commit mode to false - $col->set_auto_commit(false); + // Change auto commit mode to false + $col->setAutoCommit(false); - //Set an index on the Row-key Column - $col->create_index("name", GS_INDEX_FLAG_DEFAULT); + // Set an index on the Row-key Column + $col->createIndex("name"); - //Set an index on the Column - $col->create_index("count", GS_INDEX_FLAG_DEFAULT); + // Set an index on the Column + $col->createIndex("count"); - //Create and set row data - $row = $col->create_row(); //Create row for refer - $row->set_field_by_string(0, "name01"); - $row->set_field_by_bool(1, False); - $row->set_field_by_long(2, 1); - $row->set_field_by_blob(3, "ABCDEFGHIJ"); + // Put row: RowKey is "name01" + $ret = $col->put(["name01", false, 1, $blob]); + // Remove row with RowKey "name01" + $col->remove("name01"); - //Put row: RowKey is "name01" - $col->put_row($row); - $col->commit(); - $row2 = $col->create_row(); //Create row for refer - $col->get_row_by_string("name01", True, $row2); //Get row with RowKey "name01" - $col->delete_row_by_string("name01"); //Remove row with RowKey "name01" + // Put row: RowKey is "name02" + $col->put(["name02", false, 1, $blob]); + $col-> commit(); - //Put row: RowKey is "name02" - $col->put_row_by_string("name02", $row); - $col->commit(); + $mArray = $col->get("name02"); - //Create normal query + // Create normal query $query = $col->query("select * where name = 'name02'"); - //Execute query - $rrow = $col->create_row(); + // Execute query $rs = $query->fetch($update); - while ($rs->has_next()){ - $rs->get_next($rrow); - - $name = $rrow->get_field_as_string(0); - $status = $rrow->get_field_as_bool(1); - $count = $rrow->get_field_as_long(2) + 1; - $lob = $rrow->get_field_as_blob(3); - echo("Person: name=$name status="); - echo $status ? 'true' : 'false'; - echo(" count=$count lob=$lob\n"); + while ($rs->hasNext()) { + $data = $rs->next(); + $data[2] = $data[2] + 1; + echo("Person: name=$data[0] status=".($data[1] ? "true" : "false") + ." count=$data[2] lob=$data[3]\n"); - //Update row - $rrow->set_field_by_long(2, $count); - $rs->update_current($rrow); + // Update row + $rs->update($data); } - //End transaction + + // End transction $col->commit(); - } catch(GSException $e){ - echo($e->what()."\n"); - echo($e->get_code()."\n"); + echo("success!\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } } ?> diff --git a/sample/sample1_web.php b/sample/sample1_web.php index 392e56a..659d7e6 100644 --- a/sample/sample1_web.php +++ b/sample/sample1_web.php @@ -1,84 +1,83 @@ get_store(array("notificationAddress" => $address, - "notificationPort" => $port, + try { + // Get GridStore object + $gridstore = $factory->getStore(["host" => $address, + "port" => (int)$port, "clusterName" => $cluster, - "user" => $user, - "password" => $password - )); - - //Create Collection - $col = $gridstore->put_container("col01", array(array("name" => GS_TYPE_STRING), - array("status" => GS_TYPE_BOOL), - array("count" => GS_TYPE_LONG), - array("lob" => GS_TYPE_BLOB)), - GS_CONTAINER_COLLECTION); - - //Change auto commit mode to false - $col->set_auto_commit(false); - - //Set an index on the Row-key Column - $col->create_index("name", GS_INDEX_FLAG_DEFAULT); - - //Set an index on the Column - $col->create_index("count", GS_INDEX_FLAG_DEFAULT); - - //Create and set row data - $row = $col->create_row(); //Create row for refer - $row->set_field_by_string(0, "name01"); - $row->set_field_by_bool(1, False); - $row->set_field_by_long(2, 1); - $row->set_field_by_blob(3, "ABCDEFGHIJ"); - - //Put row: RowKey is "name01" - $col->put_row($row); - $col->commit(); - $row2 = $col->create_row(); //Create row for refer - $col->get_row_by_string("name01", True, $row2); //Get row with RowKey "name01" - $col->delete_row_by_string("name01"); //Remove row with RowKey "name01" + "username" => $user, + "password" => $password]); - //Put row: RowKey is "name02" - $col->put_row_by_string("name02", $row); - $col->commit(); + // Create a collection container + $conInfo = new ContainerInfo(["name" => "col01", + "columnInfoArray" => [["name", Type::STRING], + ["status", Type::BOOL], + ["count", Type::LONG], + ["lob", Type::BLOB]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + $gridstore->dropContainer("col01"); + $col = $gridstore->putContainer($conInfo); + + // Change auto commit mode to false + $col->setAutoCommit(false); + + // Set an index on the Row-key Column + $col->createIndex("name"); + + // Set an index on the Column + $col->createIndex("count"); - //Create normal query + // Put row: RowKey is "name01" + $ret = $col->put(["name01", false, 1, $blob]); + // Remove row with RowKey "name01" + $col->remove("name01"); + + // Put row: RowKey is "name02" + $col->put(["name02", false, 1, $blob]); + $col-> commit(); + + $mArray = $col->get("name02"); + + // Create normal query $query = $col->query("select * where name = 'name02'"); - //Execute query - $rrow = $col->create_row(); + // Execute query $rs = $query->fetch($update); - while ($rs->has_next()){ - $rs->get_next($rrow); - - $name = $rrow->get_field_as_string(0); - $status = $rrow->get_field_as_bool(1); - $count = $rrow->get_field_as_long(2) + 1; - $lob = $rrow->get_field_as_blob(3); - $data .= "Person: name=" . $name . " status=" . ($status ? 'true' : 'false') . " count=" . $count . " lob=" . $lob . "\n"; - - //Update row - $rrow->set_field_by_long(2, $count); - $rs->update_current($rrow); + while ($rs->hasNext()) { + $row = $rs->next(); + $row[2] = $row[2] + 1; + $data .= "Person: name=$row[0] status=".($row[1] ? "true" : "false") + ." count=$row[2] lob=$row[3]\n"; + + // Update row + $rs->update($row); } - //End transaction + + // End transction $col->commit(); - } catch(GSException $e){ - $data = $e->what(). "\n" . $e->get_code() . "\n"; + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + $data = "\n[$i]\n"; + $data = $e->getErrorCode($i)."\n"; + $data = $e->getLocation($i)."\n"; + $data = $e->getErrorMessage($i)."\n"; + } } } ?> diff --git a/sample/sample2.php b/sample/sample2.php index 7f167b4..442a611 100644 --- a/sample/sample2.php +++ b/sample/sample2.php @@ -1,53 +1,49 @@ get_store(array("notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + try { + // Get GridStore object + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5] - )); - - #Create ContainerInfo - $conInfo = + "username" => $argv[4], + "password" => $argv[5]]); - #Create TimeSeries - $ts = $gridstore->put_container("point01", array(array("timestamp" => GS_TYPE_TIMESTAMP), - array("active" => GS_TYPE_BOOL), - array("voltage" => GS_TYPE_DOUBLE)), - GS_CONTAINER_TIME_SERIES); + // Create a time series container + $conInfo = new ContainerInfo(["name" => "point01", + "columnInfoArray" => [["timestamp", Type::TIMESTAMP], + ["active", Type::BOOL], + ["voltage", Type::DOUBLE]], + "type" => ContainerType::TIME_SERIES, + "rowKey" => true]); - #Create and set row data - $row = $ts->create_row(); - $row->set_field_by_timestamp(0, TimestampUtils::current()); - $row->set_field_by_bool(1, false); - $row->set_field_by_double(2, 100); + $ts = $gridstore->putContainer($conInfo); - #Put row to timeseries with current timestamp - $ts->put_row($row); + // Put row to timeseries with current timestamp + $now = new DateTime("now", new DateTimeZone("UTC")); + $ts->put([$now, false, 100]); - #Create normal query for range of timestamp from 6 hours ago to now + // Create normal query for range of timestamp from 6 hours ago to now $query = $ts->query("select * where timestamp > TIMESTAMPADD(HOUR, NOW(), -6)"); - $rs = $query->fetch($update); - - #Get result - $rrow = $ts->create_row(); - while ($rs->has_next()){ - $rs->get_next($rrow); - $timestamp = $rrow->get_field_as_timestamp(0); - $active = $rrow->get_field_as_bool(1); - $voltage = $rrow->get_field_as_double(2); - echo 'Time='.$timestamp.' Active='; - echo $active ? 'true' : 'false'; - echo ' Voltage='.$voltage, PHP_EOL; + $rs = $query->fetch(); + + while ($rs->hasNext()) { + $data = $rs->next(); + $dateTime = $data[0]->format("Y-m-d H:i:s.u"); + $active = $data[1] ? "true" : "false"; + $voltage = $data[2]; + echo("Time=$dateTime Active=$active Voltage =$voltage\n"); + } + + echo("success!\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); } - } catch(Exception $e){ - echo $e->getMessage(), PHP_EOL; } ?> diff --git a/sample/sample3.php b/sample/sample3.php index be916de..d55aed7 100644 --- a/sample/sample3.php +++ b/sample/sample3.php @@ -1,49 +1,49 @@ get_store(array( - "notificationAddress" => $argv[1], - "notificationPort" => $argv[2], + try { + // Get GridStore object + $gridstore = $factory->getStore(["host" => $argv[1], + "port" => (int)$argv[2], "clusterName" => $argv[3], - "user" => $argv[4], - "password" => $argv[5], - "consistency" => "EVENTUAL" - )); + "username" => $argv[4], + "password" => $argv[5]]); - #Get TimeSeries - #Reuse TimeSeries and data from sample 2 - $ts = $gridstore->get_container("point01"); + // Get Timeseries + // Reuse TimeSeries and data from sample 2 + $ts = $gridstore->getContainer("point01"); - #Create normal query to get all row where active = FAlSE and voltage > 50 + // Create normal query to get all row where active = FAlSE and voltage > 50 $query = $ts->query("select * from point01 where not active and voltage > 50"); - $rs = $query->fetch($update); + $rs = $query->fetch(); - #Get result - $rrow = $ts->create_row(); - while ($rs->has_next()){ - $rs->get_next($rrow); - $timestamp = $rrow->get_field_as_timestamp(0); - - #Perform aggregation query to get average value - #during 10 minutes later and 10 minutes earlier from this point - $aggCommand = "select AVG(voltage) from point01 where timestamp > TIMESTAMPADD(MINUTE, TO_TIMESTAMP_MS($timestamp), -10) AND timestamp < TIMESTAMPADD(MINUTE, TO_TIMESTAMP_MS($timestamp), 10)"; - $aggQuery = $ts->query($aggCommand); - $aggRs = $aggQuery->fetch($update); - while ($aggRs->has_next()){ - #Get aggregation result - $aggResult = $aggRs->get_next_aggregation(); - #Convert result to double and print out - $voltage = $aggResult->get_double(); - echo("[Timestamp=$timestamp] Average voltage = $voltage\n"); - } + // Get result + while ($rs->hasNext()) { + $data = $rs->next(); + $dateTime= $data[0]; + $gsTS = TimestampUtils::getTimeMillis($dateTime); + // Perform aggregation query to get average value + // during 10 minutes later and 10 minutes earlier from this point + $aggCommand = "select AVG(voltage) from point01 where timestamp > TIMESTAMPADD(MINUTE, TO_TIMESTAMP_MS($gsTS), -10) AND timestamp < TIMESTAMPADD(MINUTE, TO_TIMESTAMP_MS($gsTS), 10)"; + $aggQuery = $ts->query($aggCommand); + $aggRs = $aggQuery->fetch(); + while ($aggRs->hasNext()) { + // Get aggregation result + $aggResult = $aggRs->next(); + // Convert result to double and print out + $voltage = $aggResult->get(TYPE::DOUBLE); + echo sprintf("[Alert] DateTime=%s, Average voltage=%.1lf\n", $data[0]->format('Y-m-d H:i:s.u'), $voltage); + } + } + echo("success!\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); } - } catch(Exception $e){ - echo $e->getMessage(), "\n"; } ?> From 54ca07596e809afc4a20fe8e9f0664541ce766bc Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:53:38 +0900 Subject: [PATCH 17/22] add new samples for 0.8 --- sample/ContainerInformation.php | 57 +++++++++++++++++++++++++++++++++ sample/PutRows.php | 54 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 sample/ContainerInformation.php create mode 100644 sample/PutRows.php diff --git a/sample/ContainerInformation.php b/sample/ContainerInformation.php new file mode 100644 index 0000000..b489bbc --- /dev/null +++ b/sample/ContainerInformation.php @@ -0,0 +1,57 @@ +getStore(["host" => $argv[1], + "port" => (int)$argv[2], + "clusterName" => $argv[3], + "username" => $argv[4], + "password" => $argv[5]]); + + // Create a collection container + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $col = $gridstore->putContainer($conInfo); + echo("Sample data generation: Create Collection name=$containerName\n"); + + // Get container information + // (1)Get container information + $containerInfo = $gridstore->getContainerInfo($containerName); + + // (2)Display container information + echo("Get containerInfo:\n name =".$containerInfo->name."\n"); + + if ($containerInfo->type == ContainerType::COLLECTION) { + echo(" type=Collection\n"); + } else { + echo(" type=Timeseries\n"); + } + + echo(" rowKeyAssigned=". (($containerInfo->rowKey) ? "true" : "false")."\n"); + + $count = sizeof($containerInfo->columnInfoArray); + echo(" columnCount=$count\n"); + + for ($i = 0; $i < $count; $i++) { + echo(" column (".$containerInfo->columnInfoArray[$i][0].", ".$containerInfo->columnInfoArray[$i][1].")\n"); + } + echo("success!\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } +?> diff --git a/sample/PutRows.php b/sample/PutRows.php new file mode 100644 index 0000000..85248bb --- /dev/null +++ b/sample/PutRows.php @@ -0,0 +1,54 @@ +getStore(["host" => $argv[1], + "port" => (int)$argv[2], + "clusterName" => $argv[3], + "username" => $argv[4], + "password" => $argv[5]]); + + // Create a collection + $conInfo = new ContainerInfo(["name" => $containerName, + "columnInfoArray" => [["id", Type::INTEGER], + ["productName", Type::STRING], + ["count", Type::INTEGER]], + "type" => ContainerType::COLLECTION, + "rowKey" => true]); + + $col = $gridstore->putContainer($conInfo); + echo("Create Collection name=$containerName\n"); + + // Register multiple rows + // (1)Get the container + $col1 = $gridstore->getContainer($containerName); + if ($col1 == null) { + echo("ERROR Container not found. name=$containerName\n"); + } + + // Register multiple rows + for ($i = 0; $i < $rowCount; $i++) { + $row = []; + array_push($row, $i, "dvd", 10*$i); + array_push($rowArray, $row); + $col1->multiPut($rowArray); + } + + echo("Put rows\n"); + echo("success!\n"); + } catch (GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } +?> From 2899305472449ed02906fa8cb5d78e8da62c8182 Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:54:58 +0900 Subject: [PATCH 18/22] update for 0.8 --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f3de6b7..686ad18 100644 --- a/Makefile +++ b/Makefile @@ -20,20 +20,20 @@ CPPFLAGS_PHP = $(CPPFLAGS) $(INCLUDES_PHP) PROGRAM = griddb_php_client.so -SOURCES = src/Resource.cpp \ - src/TimeSeriesProperties.cpp \ - src/AggregationResult.cpp \ +SOURCES = src/TimeSeriesProperties.cpp \ src/ContainerInfo.cpp \ + src/AggregationResult.cpp \ src/Container.cpp \ src/Store.cpp \ src/StoreFactory.cpp \ src/PartitionController.cpp \ src/Query.cpp \ - src/Row.cpp \ + src/QueryAnalysisEntry.cpp \ src/RowKeyPredicate.cpp \ src/RowSet.cpp \ src/TimestampUtils.cpp \ - + src/Field.cpp \ + src/Util.cpp all: $(PROGRAM) From 7db1822c76efbf507cc4cc08c01505fac008c45e Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 13:56:34 +0900 Subject: [PATCH 19/22] update for 0.8 --- README.md | 55 ++++++++++++++++++------------------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f7df552..1ee0a1b 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,19 @@ GridDB PHP Client ## Overview -GridDB PHP Client is developed using GridDB C Client and [SWIG](http://www.swig.org/) (Simplified Wrapper and Interface Generator). +GridDB PHP Client is developed using GridDB C Client and [SWIG](http://www.swig.org/) (Simplified Wrapper and Interface Generator). -(Additional information) -There is [PHP Client package on Packagist repository](https://packagist.org/packages/griddb/php-client) . ## Operating environment Building of the library and execution of the sample programs have been checked in the following environment. - OS: CentOS 7.4(x64) + OS: CentOS 7.8(x64) SWIG: 4.0.0 GCC: 4.8.5 - PHP: 7 - GridDB Server: 4.2 (CE) - GridDB C Client: 4.2 (CE) + PHP: 7.4.7 + GridDB Server: 4.5 (CE) + GridDB C Client: 4.5 (CE) ## QuickStart ### Preparations @@ -29,17 +27,17 @@ Install SWIG as below. $ ./configure $ make $ sudo make install - + Note: If CentOS, you might need to install pcre in advance. $ sudo yum install pcre2-devel.x86_64 -Install PHP7 and GridDB C Client. +Install PHP7.4.7 and GridDB C Client. -Set LIBRARY_PATH. +Set LIBRARY_PATH. export LIBRARY_PATH=$LIBRARY_PATH: -### Build and Run +### Build and Run 1. Execute the command on project directory. @@ -69,14 +67,13 @@ GridDB Server need to be started in advance. GridDB Server need to be started in advance. -In the case of Web Server: Apache/2.2.15, please use the following steps. - +In the case of Web Server: Apache/2.4.6, please use the following steps. + 1. Store griddb_php_client.php and sample/sample1_web.php in /var/www/html. 2. Store griddb_php_client.so in /usr/lib64/php/modules. - 3. Add extension for griddb_php_client.so in /etc/php.ini.rpmsave or /etc/php/7.2/apache2/php.ini. - extension=griddb_php_client.so + 3. Add extension for griddb_php_client.so in /etc/php.ini 4. Set LD_LIBRARY_PATH. @@ -84,7 +81,7 @@ In the case of Web Server: Apache/2.2.15, please use the following steps. 5. Restart httpd/apache. - 6. In web browser, run : http://localhost:8000/sample1_web.php. + 6. In web browser, run : http://localhost/sample1_web.php. 7. Click submit button after entering address, port, cluster, user and password. @@ -102,37 +99,21 @@ In the case of Web Server: Apache/2.2.15, please use the following steps. - timeseries-specific function like gsAggregateTimeSeries, gsQueryByTimeSeriesSampling in C client - trigger, affinity -Please refer to the following files for more detailed information. +Please refer to the following files for more detailed information. - [PHP Client API Reference](https://griddb.github.io/php_client/PHPAPIReference.htm) About API: - When an error occurs, an exception GSException is thrown. -- Based on C Client API. Please refer to C Client API Reference for the detailed information. - * [API Reference](https://griddb.github.io/griddb_nosql/manual/GridDB_API_Reference.html) - * [API Reference(Japanese)](https://griddb.github.io/griddb_nosql/manual/GridDB_API_Reference_ja.html) - -Note: -1. The current API might be changed in the next version. e.g. ContainerInfo() -2. References to objects obtained using the get method described below must be referenced prior to executing the methods. When referencing after the execution of the get methods, please copy the basic data type such as string from the object and reference it to the copied data. - - get_row_xxx - - get_partition_xxx - - get_container_info - - Please refer to the following note from C Client API Reference document for detailed information of the reason behind the implementation: - - "In order to store the variable-length data such as string or array, it uses a temporary memory area. - This area is valid until this function or similar functions which use a temporary memory area. - The behavior is undefined when the area which has been invalidated is accessed." ## Community - * Issues - Use the GitHub issue function if you have any requests, questions, or bug reports. - * PullRequest + * Issues + Use the GitHub issue function if you have any requests, questions, or bug reports. + * PullRequest Use the GitHub pull request function if you want to contribute code. You'll need to agree GridDB Contributor License Agreement(CLA_rev1.1.pdf). By using the GitHub pull request function, you shall be deemed to have agreed to GridDB Contributor License Agreement. ## License - + GridDB PHP Client source license is Apache License, version 2.0. From 2a19617becf66c4e3c1a6263f0f0df941c79a7ad Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 14:21:04 +0900 Subject: [PATCH 20/22] add test code --- .../BS-001-Container_basic_scenario.csv | 10 + test/resource/BS-004-Container_put_get.csv | 12 + test/resource/BS-005-Container_index.csv | 3 + ...-007-Aggregation_with_double_timestamp.csv | 9 + .../BS-008-Container_put_get_remove.csv | 5 + test/resource/BS-009-RowSet_manual_commit.csv | 6 + test/resource/BS-010-Query-with-limit.csv | 7 + test/resource/BS-012-Error_utility.csv | 33 ++ .../resource/BS-015-ContainerInfo_set_get.csv | 5 + .../BS-016-ExpirationInfo_set_get.csv | 5 + test/resource/UC-017-Attribute.csv | 91 +++++ test/resource/exceedSizeColName.txt | 1 + test/resource/exceedSizeString.txt | 1 + test/resource/longSizeString.txt | 1 + test/testCode/BS001ContainerBasicScenario.php | 121 +++++++ test/testCode/BS004ContainerPutGet.php | 135 ++++++++ .../testCode/BS004ContainerPutGetNullSpec.php | 149 +++++++++ test/testCode/BS005ContainerIndex.php | 123 +++++++ .../BS007AggregationWithDoubleTimestamp.php | 175 ++++++++++ .../BS008ContainerPutGetRemoveSpec.php | 196 +++++++++++ test/testCode/BS009RowSetManualCommitSpec.php | 204 ++++++++++++ test/testCode/BS010QueryWithLimitSpec.php | 134 ++++++++ test/testCode/BS012ErrorUtilitySpec.php | 63 ++++ .../testCode/BS015ContainerInfoSetGetSpec.php | 132 ++++++++ .../BS016ExpirationInfoSetGetSpec.php | 91 +++++ test/testCode/BS018EnumSpec.php | 60 ++++ test/testCode/BS019AttributeSpec.php | 314 ++++++++++++++++++ test/testCode/BS021KeywordParametersSpec.php | 96 ++++++ test/testCode/config.php | 7 + test/testCode/utility.php | 242 ++++++++++++++ 30 files changed, 2431 insertions(+) create mode 100644 test/resource/BS-001-Container_basic_scenario.csv create mode 100644 test/resource/BS-004-Container_put_get.csv create mode 100644 test/resource/BS-005-Container_index.csv create mode 100644 test/resource/BS-007-Aggregation_with_double_timestamp.csv create mode 100644 test/resource/BS-008-Container_put_get_remove.csv create mode 100644 test/resource/BS-009-RowSet_manual_commit.csv create mode 100644 test/resource/BS-010-Query-with-limit.csv create mode 100644 test/resource/BS-012-Error_utility.csv create mode 100644 test/resource/BS-015-ContainerInfo_set_get.csv create mode 100644 test/resource/BS-016-ExpirationInfo_set_get.csv create mode 100644 test/resource/UC-017-Attribute.csv create mode 100644 test/resource/exceedSizeColName.txt create mode 100644 test/resource/exceedSizeString.txt create mode 100644 test/resource/longSizeString.txt create mode 100644 test/testCode/BS001ContainerBasicScenario.php create mode 100644 test/testCode/BS004ContainerPutGet.php create mode 100644 test/testCode/BS004ContainerPutGetNullSpec.php create mode 100644 test/testCode/BS005ContainerIndex.php create mode 100644 test/testCode/BS007AggregationWithDoubleTimestamp.php create mode 100644 test/testCode/BS008ContainerPutGetRemoveSpec.php create mode 100644 test/testCode/BS009RowSetManualCommitSpec.php create mode 100644 test/testCode/BS010QueryWithLimitSpec.php create mode 100644 test/testCode/BS012ErrorUtilitySpec.php create mode 100644 test/testCode/BS015ContainerInfoSetGetSpec.php create mode 100644 test/testCode/BS016ExpirationInfoSetGetSpec.php create mode 100644 test/testCode/BS018EnumSpec.php create mode 100644 test/testCode/BS019AttributeSpec.php create mode 100644 test/testCode/BS021KeywordParametersSpec.php create mode 100644 test/testCode/config.php create mode 100644 test/testCode/utility.php diff --git a/test/resource/BS-001-Container_basic_scenario.csv b/test/resource/BS-001-Container_basic_scenario.csv new file mode 100644 index 0000000..9df46b0 --- /dev/null +++ b/test/resource/BS-001-Container_basic_scenario.csv @@ -0,0 +1,10 @@ +testId,containerType,containerName,rowKeyList,GS_TYPE_STRING,GS_TYPE_BOOL,GS_TYPE_DOUBLe,queryCommand,expectedOutput +BS-001-Container_basic_scenario-001,GS_CONTAINER_COLLECTION,Abc_123,[10;20;30],abc,True,1.1,select MIN(a_9),0 +BS-001-Container_basic_scenario-002,GS_CONTAINER_COLLECTION,Abc_124,[10;20;3.3],abc,True,1.1,select MAX(za),1 +BS-001-Container_basic_scenario-003,GS_CONTAINER_COLLECTION,Abc_125,[10;20;30],abc,False,False,select MIN(a_9),1 +BS-001-Container_basic_scenario-004,GS_CONTAINER_TIME_SERIES,Abc_126,[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;2018-12-01T10:20:00.000Z],abc,True,1.1,select MAX(za),0 +BS-001-Container_basic_scenario-005,GS_CONTAINER_TIME_SERIES,Abc_127,[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;3.3],abc,True,1.1,select MIN(a_91),1 +BS-001-Container_basic_scenario-006,GS_CONTAINER_TIME_SERIES,Abc_128,[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;2018-12-01T10:20:00.000Z],abc,False,1,select MAX(za1),1 +BS-001-Container_basic_scenario-007,GS_CONTAINER_TIME_SERIES,Abc_128<.>/?;:[]{}~`!@#$%^&*(),[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;2018-12-01T10:20:00.000Z],abc,False,1,select MAX(za),1 +BS-001-Container_basic_scenario-008,GS_CONTAINER_TIME_SERIES,Abc_128'リング,[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;2018-12-01T10:20:00.000Z],abc,False,1,select MAX(za),1 +BS-001-Container_basic_scenario-009,GS_CONTAINER_TIME_SERIES,Abc_128リング,[2018-12-01T10:00:00.000Z;2018-12-01T10:10:00.000Z;2018-12-01T10:20:00.000Z],abc,False,1,select MAX(za),1 diff --git a/test/resource/BS-004-Container_put_get.csv b/test/resource/BS-004-Container_put_get.csv new file mode 100644 index 0000000..dfdf2e1 --- /dev/null +++ b/test/resource/BS-004-Container_put_get.csv @@ -0,0 +1,12 @@ +testId, containerType,GS_TYPE_STRING, GS_TYPE_TIMESTAMP, GS_TYPE_BYTE, GS_TYPE_SHORT, GS_TYPE_INTEGER, GS_TYPE_BOOL, GS_TYPE_FLOAT, GS_TYPE_DOUBLE, GS_TYPE_BLOB, expectedOutput +BS-004-Container_put_get-001,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,abc,0 +BS-004-Container_put_get-002,GS_CONTAINER_TIME_SERIES,abc,2018-12-01T10:20:00.000Z,127,32767,2147483647,False,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-003,GS_CONTAINER_TIME_SERIES,abc,9999-12-31T23:59:59.999Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-004,GS_CONTAINER_TIME_SERIES,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-005,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,ABC,0 +BS-004-Container_put_get-006,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-007,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-008,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-009,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,99,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-010,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,9.9,[1;2;3],0 +BS-004-Container_put_get-011,GS_CONTAINER_COLLECTION,abc,1970-01-01T00:00:00.000Z,127,32767,2147483647,True,1.1,100,[1;2;3],0 diff --git a/test/resource/BS-005-Container_index.csv b/test/resource/BS-005-Container_index.csv new file mode 100644 index 0000000..3da532c --- /dev/null +++ b/test/resource/BS-005-Container_index.csv @@ -0,0 +1,3 @@ +testId, containerType, columnInfo, indexType, expectedOutput +BS-005-Container_index_create_drop-001,GS_CONTAINER_COLLECTION,1_a:GS_TYPE_INTEGER,GS_INDEX_FLAG_HASH,0 +BS-005-Container_index_create_drop-002,GS_CONTAINER_TIME_SERIES,Z0:GS_TYPE_BYTE,,0 diff --git a/test/resource/BS-007-Aggregation_with_double_timestamp.csv b/test/resource/BS-007-Aggregation_with_double_timestamp.csv new file mode 100644 index 0000000..b186aa5 --- /dev/null +++ b/test/resource/BS-007-Aggregation_with_double_timestamp.csv @@ -0,0 +1,9 @@ +testId, containerType, query, expectedOutput +BS-007-Aggregation_with_double_timestamp-001,GS_CONTAINER_COLLECTION,select MIN(a_9),0 +BS-007-Aggregation_with_double_timestamp-002,GS_CONTAINER_COLLECTION,select MAX(za),0 +BS-007-Aggregation_with_double_timestamp-003,GS_CONTAINER_COLLECTION,select MIN(A00) from not_exist,1 +BS-007-Aggregation_with_double_timestamp-004,GS_CONTAINER_COLLECTION,select MAX(A00) from not_exist,1 +BS-007-Aggregation_with_double_timestamp-005,GS_CONTAINER_TIME_SERIES,select MIN(a_9),0 +BS-007-Aggregation_with_double_timestamp-006,GS_CONTAINER_TIME_SERIES,select MAX(za),0 +BS-007-Aggregation_with_double_timestamp-007,GS_CONTAINER_TIME_SERIES,select MIN(A00) from not_exist,1 +BS-007-Aggregation_with_double_timestamp-008,GS_CONTAINER_TIME_SERIES,select MAX(A00) from not_exist,1 diff --git a/test/resource/BS-008-Container_put_get_remove.csv b/test/resource/BS-008-Container_put_get_remove.csv new file mode 100644 index 0000000..1ee2c2a --- /dev/null +++ b/test/resource/BS-008-Container_put_get_remove.csv @@ -0,0 +1,5 @@ +testId, containerType, rowKey, rowKeyType, GS_TYPE_BYTE, GS_TYPE_SHORT, GS_TYPE_BOOL, GS_TYPE_FLOAT , GS_TYPE_DOUBLE, GS_TYPE_BLOB, expectedOutput +BS-008-Container_put_get_remove-001,GS_CONTAINER_COLLECTION,abc,string,127,32767,True,1.1,9.9,ABC,0 +BS-008-Container_put_get_remove-002,GS_CONTAINER_COLLECTION,2147483647,integer,32,767,False,1.1,9.9,[1;2;3],0 +BS-008-Container_put_get_remove-003,GS_CONTAINER_COLLECTION,9223372036854775807,long,32,767,True,1.1,9.9,[1;2;3],0 +BS-008-Container_put_get_remove-004,GS_CONTAINER_TIME_SERIES,9999-12-31T23:59:59.999Z,timestamp,32,767,True,1.1,9.9,[1;2;3],0 diff --git a/test/resource/BS-009-RowSet_manual_commit.csv b/test/resource/BS-009-RowSet_manual_commit.csv new file mode 100644 index 0000000..8beb42f --- /dev/null +++ b/test/resource/BS-009-RowSet_manual_commit.csv @@ -0,0 +1,6 @@ +testId,ContainerType,RowKeyType,RowKey,GS_TYPE_STRING,GS_TYPE_BOOL,GS_TYPE_BYTE,GS_TYPE_SHORT,GS_TYPE_INTEGER,GS_TYPE_LONG,GS_TYPE_FLOAT,GS_TYPE_DOUBLE,GS_TYPE_BLOB,expectedOutput +BS-009-RowSet_manual_commit-001,GS_CONTAINER_COLLECTION,string,abc,abc,True,127,32767,2147483647,3000000000,1.1,9.9,[1;2;3],0 +BS-009-RowSet_manual_commit-002,GS_CONTAINER_COLLECTION,integer,99,abc,True,127,32767,2147483647,3000000000,1.2,9.10,[1;2;3],0 +BS-009-RowSet_manual_commit-003,GS_CONTAINER_COLLECTION,long,2147483647,abc,True,127,32767,2147483647,3000000000,1.3,9.11,[1;2;3],0 +BS-009-RowSet_manual_commit-004,GS_CONTAINER_TIME_SERIES,timestamp,1970-01-01T00:00:00.000Z,abc,True,127,32767,2147483647,3000000000,1.4,9.12,[1;2;3],0 +BS-009-RowSet_manual_commit-005,GS_CONTAINER_COLLECTION,string,1.1,abc,True,127,32767,2147483647,3000000000,1.5,9.13,[1;2;3],1 diff --git a/test/resource/BS-010-Query-with-limit.csv b/test/resource/BS-010-Query-with-limit.csv new file mode 100644 index 0000000..95c4b00 --- /dev/null +++ b/test/resource/BS-010-Query-with-limit.csv @@ -0,0 +1,7 @@ +testId, containerType, query, expectedOutput +BS-010-Query-with-limit-001,GS_CONTAINER_COLLECTION,select * limit 1,0 +BS-010-Query-with-limit-002,GS_CONTAINER_COLLECTION,select * limit a,1 +BS-010-Query-with-limit-003,GS_CONTAINER_TIME_SERIES,select * limit 1,0 +BS-010-Query-with-limit-004,GS_CONTAINER_TIME_SERIES,select * limit a,1 +BS-010-Query-with-limit-005,GS_CONTAINER_COLLECTION,select * limit -1,1 +BS-010-Query-with-limit-006,GS_CONTAINER_TIME_SERIES,select * limit -1,1 diff --git a/test/resource/BS-012-Error_utility.csv b/test/resource/BS-012-Error_utility.csv new file mode 100644 index 0000000..aca9dde --- /dev/null +++ b/test/resource/BS-012-Error_utility.csv @@ -0,0 +1,33 @@ +testID,Stack index,Buffer size,Expected Output +Test get_error_stack_size(),,, +UC-014-Error_utility-001,NA,NA,0 +UC-014-Error_utility-002,NA,NA,0 +Test get_error_code(),,, +UC-014-Error_utility-003,0,NA,A number different to 0 +UC-014-Error_utility-004,2147483647,NA,0 +UC-014-Error_utility-005,-1,NA,A number different to 0 +UC-014-Error_utility-006,-2147483649,NA,A number different to 0 +UC-014-Error_utility-007,2147483648,NA,0 +UC-014-Error_utility-008,1.1,NA,A number different to 0 +UC-014-Error_utility-009,a,NA,A number different to 0 +Test format_error_message(),,, +UC-014-Error_utility-010,0,100,"Error message contains ""cluster name invalid""" +UC-014-Error_utility-011,2147483647,30,Empty string +UC-014-Error_utility-012,-1,30,Non-empty string +UC-014-Error_utility-013,-2147483649,30,Non-empty string +UC-014-Error_utility-014,2147483648,30,Empty string +UC-014-Error_utility-015,1.1,30,Non-empty string +UC-014-Error_utility-016,a,30,Non-empty string +UC-014-Error_utility-018,0,-1,Non-empty string +UC-014-Error_utility-019,0,-2147483649,Non-empty string +UC-014-Error_utility-020,0,2147483648,Empty string +UC-014-Error_utility-021,0,1.1,Empty string +UC-014-Error_utility-022,0,a,Empty string +Test format_error_location(),,, +UC-014-Error_utility-023,0,100,Non-empty string +UC-014-Error_utility-024,2147483647,30,Empty string +UC-014-Error_utility-025,-1,30,Non-empty string +UC-014-Error_utility-026,-2147483649,30,Non-empty string +UC-014-Error_utility-027,2147483648,30,Empty string +UC-014-Error_utility-028,1.1,30,Non-empty string +UC-014-Error_utility-029,a,30,Non-empty string diff --git a/test/resource/BS-015-ContainerInfo_set_get.csv b/test/resource/BS-015-ContainerInfo_set_get.csv new file mode 100644 index 0000000..55d40bf --- /dev/null +++ b/test/resource/BS-015-ContainerInfo_set_get.csv @@ -0,0 +1,5 @@ +testId,ContainerType, containerName, containerType, rowKeyAssigned, columnInfoList, expirationInfo, expectedOutput +BS-015-ContainerInfo_set_get-001,GS_CONTAINER_COLLECTION,Abc_123,GS_CONTAINER_COLLECTION,True,[[A_0:GS_TYPE_STRING];[A9:GS_TYPE_BOOL];[za:GS_TYPE_DOUBLE]],[10;20;30],0 +BS-015-ContainerInfo_set_get-002,GS_CONTAINER_TIME_SERIES,Abc_123,GS_CONTAINER_TIME_SERIES,False,[[A_0:GS_TYPE_STRING];[A9:GS_TYPE_BOOL];[za:GS_TYPE_DOUBLE]],[10;20;30],0 +BS-015-ContainerInfo_set_get-003,GS_CONTAINER_COLLECTION,Abc_123,GS_CONTAINER_COLLECTION,1.1,[[A_0:GS_TYPE_STRING];[A9:GS_TYPE_BOOL];[za:GS_TYPE_DOUBLE]],[10;20;30],1 +BS-015-ContainerInfo_set_get-004,GS_CONTAINER_TIME_SERIES,Abc_123,GS_CONTAINER_TIME_SERIES,abc,[[A_0:GS_TYPE_STRING];[A9:GS_TYPE_BOOL];[za:GS_TYPE_DOUBLE]],[10;20;30],1 diff --git a/test/resource/BS-016-ExpirationInfo_set_get.csv b/test/resource/BS-016-ExpirationInfo_set_get.csv new file mode 100644 index 0000000..a300959 --- /dev/null +++ b/test/resource/BS-016-ExpirationInfo_set_get.csv @@ -0,0 +1,5 @@ +testId, containerType, rowExpirationTime, rowExpirationTimeUnit, expirationDivisionCount, expectedOutput +BS-016-ExpirationInfo_set_get-001,string,1,0,10,0 +BS-016-ExpirationInfo_set_get-002,integer,9,10,10,0 +BS-016-ExpirationInfo_set_get-003,long,99,100,10,0 +BS-016-ExpirationInfo_set_get-004,timestamp,999,1000,10,0 \ No newline at end of file diff --git a/test/resource/UC-017-Attribute.csv b/test/resource/UC-017-Attribute.csv new file mode 100644 index 0000000..efb7e1b --- /dev/null +++ b/test/resource/UC-017-Attribute.csv @@ -0,0 +1,91 @@ +testID,query,containerName,columnInfoList,rowKeyAssigned,rowExpirationTime,rowExpirationTimeUnit,divisionCount,containerType,attribute,expectedOutput +UC-017-Attribute-001,,,,,,,,collection,container_type,0 +UC-017-Attribute-002,,,,,,,,timeseries,container_type,0 +UC-017-Attribute-003,,,,,,,,timeseries,container_type(set),1 +UC-017-Attribute-004,,,,,,,,,PartitionInfo:partition_count,0 +UC-017-Attribute-005,,,,,,,,,PartitionInfo:partition_count(set),1 +UC-017-Attribute-006,select * ,,,,,,,,RowSet:type;RowSet:size,0 +UC-017-Attribute-007,select MIN(Z_9),,,,,,,,RowSet:type;RowSet:size,0 +UC-017-Attribute-008,EXPLAIN select *,,,,,,,,RowSet:type;RowSet:size,0 +UC-017-Attribute-009,select * ,,,,,,,,RowSet:type;RowSet:size(set),1 +UC-017-Attribute-010,,a,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-011,,_,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-012,,a1,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-013,,a_,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-014,,_1,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-015,,abcde_____12345,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-016,,Z,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-017,,Z0,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-018,,Z_9,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-019,,A,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-020,,A_0,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-021,,A9,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-022,,z,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-023,,z0_,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-024,,z9,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-025,,16KB_string,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-026,,1a_,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-027,,/,,,,,,,ContainerInfo:name(set/get),0 +UC-017-Attribute-028,,NULL,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-029,,,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-030,,EEEEEEEEEE,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-031,,?,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-032,,exceed_16KB_string,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-033,,a 09 z,,,,,,,ContainerInfo:name(set/get),1 +UC-017-Attribute-034,,,0,,,,,,ContainerInfo:column_info_list(set/get),0 +UC-017-Attribute-035,,,1,,,,,,ContainerInfo:column_info_list(set/get),0 +UC-017-Attribute-036,,,2,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-037,,,3,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-038,,,4,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-039,,,5,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-040,,,6,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-041,,,7,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-042,,,8,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-043,,,9,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-044,,,10,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-045,,,11,,,,,,ContainerInfo:column_info_list(set/get),0 +UC-017-Attribute-046,,,12,,,,,,ContainerInfo:column_info_list(set/get),1 +UC-017-Attribute-047,,,13,,,,,,ContainerInfo:column_info_list(set/get),0 +UC-017-Attribute-048,,,,TRUE,,,,,ContainerInfo:row_key(set/get),0 +UC-017-Attribute-049,,,,FALSE,,,,,ContainerInfo:row_key(set/get),0 +UC-017-Attribute-050,,,,0,,,,,ContainerInfo:row_key(set/get),0 +UC-017-Attribute-051,,,,1,,,,,ContainerInfo:row_key(set/get),0 +UC-017-Attribute-052,,,,0.1,,,,,ContainerInfo:row_key(set/get),1 +UC-017-Attribute-053,,,,1.1,,,,,ContainerInfo:row_key(set/get),1 +UC-017-Attribute-054,,,,a,,,,,ContainerInfo:row_key(set/get),1 +UC-017-Attribute-055,,,,,10,,,,ExpirationInfo:time(set/get),0 +UC-017-Attribute-056,,,,,-1,,,,ExpirationInfo:time(set/get),0 +UC-017-Attribute-057,,,,,-2147483648,,,,ExpirationInfo:time(set/get),0 +UC-017-Attribute-058,,,,,2147483647,,,,ExpirationInfo:time(set/get),0 +UC-017-Attribute-059,,,,,NULL,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-060,,,,,1.1,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-061,,,,,a,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-062,,,,,-2147483649,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-063,,,,,2147483648,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-064,,,,,0,,,,ExpirationInfo:time(set/get),1 +UC-017-Attribute-065,,,,,,GS_TIME_UNIT_DAY,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-066,,,,,,GS_TIME_UNIT_HOUR,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-067,,,,,,GS_TIME_UNIT_MINUTE,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-068,,,,,,GS_TIME_UNIT_SECOND,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-069,,,,,,GS_TIME_UNIT_MILLISECOND,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-070,,,,,,NULL,,,ExpirationInfo:unit(set/get),1 +UC-017-Attribute-071,,,,,,ABC,,,ExpirationInfo:unit(set/get),1 +UC-017-Attribute-072,,,,,,GS_TIME_UNIT_YEAR ,,,ExpirationInfo:unit(set/get),1 +UC-017-Attribute-073,,,,,,8,,,ExpirationInfo:unit(set/get),1 +UC-017-Attribute-074,,,,,,-1,,,ExpirationInfo:unit(set/get),0 +UC-017-Attribute-075,,,,,,GS_TIME_UNIT_MONTH,,,ExpirationInfo:unit(set/get),1 +UC-017-Attribute-076,,,,,,,10,,ExpirationInfo:division_count(set/get),0 +UC-017-Attribute-077,,,,,,,-1,,ExpirationInfo:division_count(set/get),0 +UC-017-Attribute-078,,,,,,,160,,ExpirationInfo:division_count(set/get),0 +UC-017-Attribute-079,,,,,,,1.1,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-080,,,,,,,a,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-081,,,,,,,0,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-082,,,,,,,161,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-083,,,,,,,-2147483649,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-084,,,,,,,2147483648,,ExpirationInfo:division_count(set/get),1 +UC-017-Attribute-085,,,,,,,,GS_CONTAINER_COLLECTION,ContainerInfo:type(set/get),0 +UC-017-Attribute-086,,,,,,,,GS_CONTAINER_TIME_SERIES,ContainerInfo:type(set/get),0 +UC-017-Attribute-087,,,,,,,,-1,ContainerInfo:type(set/get),1 +UC-017-Attribute-088,,,,,,,,3,ContainerInfo:type(set/get),1 +UC-017-Attribute-089,,,,,,,,1.1,ContainerInfo:type(set/get),1 +UC-017-Attribute-090,,,,,,,,a,ContainerInfo:type(set/get),1 diff --git a/test/resource/exceedSizeColName.txt b/test/resource/exceedSizeColName.txt new file mode 100644 index 0000000..949359c --- /dev/null +++ b/test/resource/exceedSizeColName.txt @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/test/resource/exceedSizeString.txt b/test/resource/exceedSizeString.txt new file mode 100644 index 0000000..5154345 --- /dev/null +++ b/test/resource/exceedSizeString.txt @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/test/resource/longSizeString.txt b/test/resource/longSizeString.txt new file mode 100644 index 0000000..563050d --- /dev/null +++ b/test/resource/longSizeString.txt @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/test/testCode/BS001ContainerBasicScenario.php b/test/testCode/BS001ContainerBasicScenario.php new file mode 100644 index 0000000..660f16f --- /dev/null +++ b/test/testCode/BS001ContainerBasicScenario.php @@ -0,0 +1,121 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-001-Container_basic_scenario.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testContainerBasicScenario($testId, $containerType, + $containerName, $rowKeyList, + $stringVal, $boolVal, $doubleVal, + $queryCommand, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + $modifiable = true; + $rowKeyAssigned = true; + + // Convert data test from string type in CSV to other data type + $stringVal = convertData($stringVal); + $boolVal = convertData($boolVal); + $doubleVal = convertData($doubleVal); + $containerName = convertData($containerName); + $containerName = convertExtraData($containerName); + + // Convert $rowKeyList string in CSV to array + // For example: "[10;20;30]" => [10, 20, 30] + if (!is_null($rowKeyList)) { + $rowKeyListRep = str_replace(["[", "]"], ["", ""], $rowKeyList); + $rowKeyList = explode(";", $rowKeyListRep); + } else { + $rowKeyList = []; + } + $hasException = "0"; + + // Test putRow + try { + /** + * Container schema + */ + $propList = [["A_0", \Type::STRING], + ["A9", \Type::BOOL], + ["za", \Type::DOUBLE]]; + if ($containerType == "GS_CONTAINER_COLLECTION") { + $containerType = \ContainerType::COLLECTION; + $rowKey = ["a_9", \Type::INTEGER]; + } else { + $containerType = \ContainerType::TIME_SERIES; + $rowKey = ["a_9", \Type::TIMESTAMP]; + } + + // Insert row key property to the first element of columnInfoList property + $columnInfoList = $propList; + array_unshift($columnInfoList, $rowKey); + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $columnInfoList, + "type" => $containerType, + "rowKey" => $rowKeyAssigned]); + self::$gridstore->dropContainer($containerName); + $container = self::$gridstore->putContainer($containerInfo, + $modifiable); + for ($i = 0; $i < sizeof($rowKeyList); $i++) { + $container->put([convertData($rowKeyList[$i]), + $stringVal, $boolVal, $doubleVal]); + } + $query = $container->query($queryCommand); + $query->fetch(false); + self::$gridstore->dropContainer($containerName); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS004ContainerPutGet.php b/test/testCode/BS004ContainerPutGet.php new file mode 100644 index 0000000..230cf0a --- /dev/null +++ b/test/testCode/BS004ContainerPutGet.php @@ -0,0 +1,135 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-004-Container_put_get.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testContainerPutGet($testId, $containerType, + $stringVal, $timestampVal, $byteVal, + $shortVal, $integerVal, $boolVal, + $floatVal, $doubleVal, $blobVal, + $expectedOutput) + { + echo sprintf("Test case: %s put: %s:\n", $testId, $containerType); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + + $modifiable = true; + $rowKeyAssigned = true; + + // Convert data test from string type in CSV to other data type + $stringVal = convertData($stringVal); + $timestampVal = convertData($timestampVal); + $byteVal = convertData($byteVal); + $shortVal = convertData($shortVal); + $integerVal = convertData($integerVal); + $boolVal = convertData($boolVal); + $floatVal = convertData($floatVal); + $doubleVal = convertData($doubleVal); + $blobVal = convertData($blobVal); + $hasException = "0"; + + // Test putRow + try { + if ($containerType == "GS_CONTAINER_COLLECTION") { + $containerName = "col01Collection"; + $columnInfoList = [["A", \Type::STRING], + ["B", \Type::TIMESTAMP], + ["C", \Type::BYTE], + ["D", \Type::SHORT], + ["E", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + $containerType = \ContainerType::COLLECTION; + } else { + $containerName = "col01Timeseries"; + $columnInfoList = [["A", \Type::TIMESTAMP], + ["B", \Type::STRING], + ["C", \Type::BYTE], + ["D", \Type::SHORT], + ["E", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + $containerType = \ContainerType::TIME_SERIES; + } + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $columnInfoList, + "type" => $containerType, + "rowKey" => $rowKeyAssigned]); + self::$gridstore->dropContainer($containerName); + $container = self::$gridstore->putContainer($containerInfo, + $modifiable); + if ($containerType == "GS_CONTAINER_COLLECTION") { + $rowData = [$stringVal, $timestampVal, $byteVal, + $shortVal, $integerVal, $boolVal, + $floatVal, $doubleVal, $blobVal]; + } else { + $rowData = [$timestampVal, $stringVal, $byteVal, + $shortVal, $integerVal, $boolVal, + $floatVal, $doubleVal, $blobVal]; + } + $existed = $container->put($rowData); + if ($containerType == "GS_CONTAINER_COLLECTION") { + $rowDataGet = $container->get($stringVal); + } else { + $rowDataGet = $container->get($timestampVal); + } + self::$gridstore->dropContainer($containerName); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS004ContainerPutGetNullSpec.php b/test/testCode/BS004ContainerPutGetNullSpec.php new file mode 100644 index 0000000..4cd84b0 --- /dev/null +++ b/test/testCode/BS004ContainerPutGetNullSpec.php @@ -0,0 +1,149 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + self::$gridstore->dropContainer("col"); + self::$gridstore->dropContainer("ts"); + + // Create a collection container + $containerInfoCol = new \ContainerInfo(["name" => "col", + "columnInfoArray" => $propListCol, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + // Create a timeseries container + $containerInfoTS = new \ContainerInfo(["name" => "ts", + "columnInfoArray" => $propListTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + self::$containerCol = self::$gridstore->putContainer($containerInfoCol, true); + self::$containerTS = self::$gridstore->putContainer($containerInfoTS, true); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + // Test put null for all fields of row (except rowKey) + // Collection container and timeseries container + public function testPutRowNullExceptRowKey() { + echo("Testcase: BS-004-Container_put_get_null-001:\n"); + echo(" Put null for all fields of row (except rowKey)\n"); + echo sprintf(" Expected has exception = 0\n"); + $hasException = "0"; + + try { + self::$containerCol->put(["name01", null, null]); + + $dateTimeStr = "9999-12-31T23:59:59.999Z"; + $dateTimeObj = convertData($dateTimeStr); + self::$containerTS->put([$dateTimeObj, null, null]); + + $row = self::$containerCol->get("name01"); + $row = self::$containerTS->get($dateTimeObj); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + //Assert result + $this->assertEquals($hasException, "0"); + } + + // Test put null for all fields of row (include rowKey) + // Collection container + public function testPutRowNullContainerCol() { + echo("Test case: BS-004-Container_put_get_null-002: Collection container:\n"); + echo(" Put null for all fields of row (include rowKey)\n"); + echo(" Expected has exception = 1\n"); + $hasException = "0"; + + try { + self::$containerCol->put([null, null, null]); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($hasException, "1"); + } + + // Test put null for all fields of row (include rowKey) + // Timeseries container + public function testPutRowNullContainerTS() { + echo("Testcase: BS-004-Container_put_get_null-002: Timeseries container:\n"); + echo(" Put null for all fields of row (include rowKey)\n"); + echo (" Expected has exception = 1\n"); + $hasException = "0"; + + try { + self::$containerTS->put([null, null, null]); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($hasException, "1"); + } +} +?> + diff --git a/test/testCode/BS005ContainerIndex.php b/test/testCode/BS005ContainerIndex.php new file mode 100644 index 0000000..de130f8 --- /dev/null +++ b/test/testCode/BS005ContainerIndex.php @@ -0,0 +1,123 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-005-Container_index.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testContainerIndex($testId, $containerType, $columnInfo, + $indexType, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + + $modifiable = true; + $rowKeyAssigned = true; + + // Convert data test from string type in CSV to other data type + $indexType = convertData($indexType); + if (strpos($columnInfo, ":") !== false) { + $columnInfo = convertStrToRow($columnInfo); + } else { + $columnInfo = [$columnInfo]; + } + $hasException = "0"; + + try { + if ($containerType == "GS_CONTAINER_COLLECTION") { + $containerName = "col01Collection"; + $columnInfoList = [["A", \Type::STRING], + ["B", \Type::TIMESTAMP], + ["Z0", \Type::BYTE], + ["D", \Type::SHORT], + ["1_a", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + $containerType = \ContainerType::COLLECTION; + } else { + $containerName = "col01Timeseries"; + $columnInfoList = [["A", \Type::TIMESTAMP], + ["B", \Type::STRING], + ["Z0", \Type::BYTE], + ["D", \Type::SHORT], + ["1_a", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + $containerType = \ContainerType::TIME_SERIES; + } + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $columnInfoList, + "type" => $containerType, + "rowKey" => $rowKeyAssigned]); + self::$gridstore->dropContainer($containerName); + $container = self::$gridstore->putContainer($containerInfo, + $modifiable); + + // If index type = "" -> it means not set value for index type + //-> default type will be set for index type + if ($indexType == "") { + $container->createIndex($columnInfo[0]); + $container->dropIndex($columnInfo[0]); + } else { + $container->createIndex($columnInfo[0], $indexType); + $container->dropIndex($columnInfo[0], $indexType); + } + self::$gridstore->dropContainer($containerName); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS007AggregationWithDoubleTimestamp.php b/test/testCode/BS007AggregationWithDoubleTimestamp.php new file mode 100644 index 0000000..f88a5db --- /dev/null +++ b/test/testCode/BS007AggregationWithDoubleTimestamp.php @@ -0,0 +1,175 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + self::$gridstore->dropContainer(self::$containerNameCol); + self::$gridstore->dropContainer(self::$containerNameTS); + + // Create a collection container + $containerInfoCol = new \ContainerInfo(["name" => self::$containerNameCol, + "columnInfoArray" => $columnInfoListCol, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + // Create a timeseries container + $containerInfoTS = new \ContainerInfo(["name" => self::$containerNameTS, + "columnInfoArray" => $columnInfoListTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + $containerCol = self::$gridstore->putContainer($containerInfoCol, true); + $containerTS = self::$gridstore->putContainer($containerInfoTS, true); + + // Convert Datetime string to DateTime object + $dateTimeObjList = []; + for ($i = 0; $i < $rowCount; $i++) { + $dateTimeObjList[$i] = convertStrToDateTime($dateTimeStrList[$i]); + } + // Put row with multiple times + for ($i = 0; $i < $rowCount; $i++) { + // For row key is string + $containerCol->put([$strList[$i], $dateTimeObjList[$i], + 127, 32767, 2147483647, true, + 1.1, $doubleList[$i] , "abc"]); + // For row key is timestamp + $containerTS->put([$dateTimeObjList[$i], $strList[$i], + 127, 32767, 2147483647, true, + 1.1, $doubleList[$i], "abc"]); + } + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + public static function tearDownAfterClass(): void + { + // Delete container + try { + self::$gridstore->dropContainer(self::$containerNameCol); + self::$gridstore->dropContainer(self::$containerNameTS); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-007-Aggregation_with_double_timestamp.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testAggregation($testId, $containerType, + $queryStr, $expectedOutput) + { + + echo sprintf("Test case: %s:\n", $testId); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + if ($containerType == "GS_CONTAINER_COLLECTION") { + $containerName = self::$containerNameCol; + } else { + $containerName = self::$containerNameTS; + } + $hasException = "0"; + + try { + $container = self::$gridstore->getContainer($containerName); + $query = $container->query($queryStr); + // Query fetch + $rs = $query->fetch(); + // Get the result + while ($rs->hasNext()) { + // Get the result of the aggregation operation + $aggregationResult = $rs->next(); + if (strpos($queryStr, "a_9") !== false) { + $value = $aggregationResult->get(\TYPE::DOUBLE); + echo sprintf(" TQL result: %lf\n", $value); + } + if (strpos($queryStr, "za") !== false){ + $value = $aggregationResult->get(\TYPE::TIMESTAMP); + echo sprintf(" TQL result: %s\n", $value->format('Y-m-d H:i:s.u')); + } + } + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS008ContainerPutGetRemoveSpec.php b/test/testCode/BS008ContainerPutGetRemoveSpec.php new file mode 100644 index 0000000..befb4e1 --- /dev/null +++ b/test/testCode/BS008ContainerPutGetRemoveSpec.php @@ -0,0 +1,196 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + + // Create a collection container with rowkey is string + $containerInfoString = new \ContainerInfo(["name" => self::$containerNameString, + "columnInfoArray" => $columnInfoListString, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a a collection container with rowkey is integer + $containerInfoInteger = new \ContainerInfo(["name" => self::$containerNameInteger, + "columnInfoArray" => $columnInfoListInteger, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a collection container with rowkey is long + $containerInfoLong = new \ContainerInfo(["name" => self::$containerNameLong, + "columnInfoArray" => $columnInfoListLong, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a a collection container with rowkey is timestamp + $containerInfoTimestampTS = new \ContainerInfo(["name" => self::$containerNameTimestampTS, + "columnInfoArray" => $columnInfoListTimestampTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + self::$gridstore->dropContainer(self::$containerNameString); + self::$gridstore->dropContainer(self::$containerNameInteger); + self::$gridstore->dropContainer(self::$containerNameLong); + self::$gridstore->dropContainer(self::$containerNameTimestampTS); + + self::$gridstore->putContainer($containerInfoString, true); + self::$gridstore->putContainer($containerInfoInteger, true); + self::$gridstore->putContainer($containerInfoLong, true); + self::$gridstore->putContainer($containerInfoTimestampTS, true); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + } + + public static function tearDownAfterClass(): void + { + // Delete container + try { + self::$gridstore->dropContainer(self::$containerNameString); + self::$gridstore->dropContainer(self::$containerNameInteger); + self::$gridstore->dropContainer(self::$containerNameLong); + self::$gridstore->dropContainer(self::$containerNameTimestampTS); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-008-Container_put_get_remove.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testContainerPutGetRemove($testId, $containerType, $rowKey, + $rowKeyType, $mTypeByte, + $mTypeShort, $mTypeBool, + $mTypeFloat, $mTypeDouble, + $mTypeBlob, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Put container with row key type %s, value %s\n", $rowKeyType, $rowKey); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + + $rowKey = convertData($rowKey); + $mTypeByte = convertData($mTypeByte); + $mTypeShort = convertData($mTypeShort); + $mTypeBool = convertData($mTypeBool); + $mTypeFloat = convertData($mTypeFloat); + $mTypeDouble = convertData($mTypeDouble); + $mTypeBlob = convertData($mTypeBlob); + + $hasException = "0"; + + switch ($rowKeyType) { + case "string": + $containerName = self::$containerNameString; + break; + case "integer": + $containerName = self::$containerNameInteger; + break; + case "long": + $containerName = self::$containerNameLong; + break; + case "timestamp": + $containerName = self::$containerNameTimestampTS; + break; + default: + $containerName = self::$containerNameString; + } + try { + $container = self::$gridstore->getContainer($containerName); + $row = [$rowKey, $mTypeByte, $mTypeShort, $mTypeBool, + $mTypeFloat, $mTypeDouble, $mTypeBlob]; + $container->put($row); + $rowBeforeDelte = $container->get($rowKey); + $container->remove($rowKey); + $rowAfterDelete = $container->get($rowKey); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS009RowSetManualCommitSpec.php b/test/testCode/BS009RowSetManualCommitSpec.php new file mode 100644 index 0000000..cab531a --- /dev/null +++ b/test/testCode/BS009RowSetManualCommitSpec.php @@ -0,0 +1,204 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + + // Create a collection container with rowkey is string + $containerInfoString = new \ContainerInfo(["name" => self::$containerNameString, + "columnInfoArray" => $columnInfoListString, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a a collection container with rowkey is integer + $containerInfoInteger = new \ContainerInfo(["name" => self::$containerNameInteger, + "columnInfoArray" => $columnInfoListInteger, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a collection container with rowkey is long + $containerInfoLong = new \ContainerInfo(["name" => self::$containerNameLong, + "columnInfoArray" => $columnInfoListLong, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + // Create a a collection container with rowkey is timestamp + $containerInfoTimestampTS = new \ContainerInfo(["name" => self::$containerNameTimestampTS, + "columnInfoArray" => $columnInfoListTimestampTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + self::$gridstore->dropContainer(self::$containerNameString); + self::$gridstore->dropContainer(self::$containerNameInteger); + self::$gridstore->dropContainer(self::$containerNameLong); + self::$gridstore->dropContainer(self::$containerNameTimestampTS); + + self::$gridstore->putContainer($containerInfoString, true); + self::$gridstore->putContainer($containerInfoInteger, true); + self::$gridstore->putContainer($containerInfoLong, true); + self::$gridstore->putContainer($containerInfoTimestampTS, true); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + } + + public static function tearDownAfterClass(): void + { + // Delete container + try { + self::$gridstore->dropContainer(self::$containerNameString); + self::$gridstore->dropContainer(self::$containerNameInteger); + self::$gridstore->dropContainer(self::$containerNameLong); + self::$gridstore->dropContainer(self::$containerNameTimestampTS); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-009-RowSet_manual_commit.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testRowSetManualCommit($testId, $containerType, + $rowKeyType, $rowKey, + $mType_STRING, $mType_BOOL, + $mType_BYTE, $mType_SHORT, + $mType_INTEGER, $mType_LONG, + $mType_FLOAT, $mType_DOUBLE, + $mType_BLOB, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Put container with row key type %s, value %s\n", $rowKeyType, $rowKey); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + + $queryStr = "Select *"; + $rowKey = convertData($rowKey); + $mType_BOOL = convertData($mType_BOOL); + $mType_BYTE = convertData($mType_BYTE); + $mType_SHORT = convertData($mType_SHORT); + $mType_FLOAT = convertData($mType_FLOAT); + $mType_DOUBLE = convertData($mType_DOUBLE); + $mType_BLOB = convertData($mType_BLOB); + + $hasException = "0"; + + switch ($rowKeyType) { + case "string": + $containerName = self::$containerNameString; + break; + case "integer": + $containerName = self::$containerNameInteger; + break; + case "long": + $containerName = self::$containerNameLong; + break; + case "timestamp": + $containerName = self::$containerNameTimestampTS; + break; + default: + $containerName = self::$containerNameString; + } + try { + $container = self::$gridstore->getContainer($containerName); + $container->setAutoCommit(false); + $row = [$rowKey, $mType_BYTE, $mType_SHORT, $mType_BOOL, + $mType_FLOAT, $mType_DOUBLE, $mType_BLOB]; + $container->put($row); + $container->commit(); + $rowAfterPut = $container->get($rowKey); + $query = $container->query($queryStr); + $rowSet = $query->fetch(false); + while ($rowSet->hasNext()) { + $rowSet->next(); + } + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS010QueryWithLimitSpec.php b/test/testCode/BS010QueryWithLimitSpec.php new file mode 100644 index 0000000..ec4e371 --- /dev/null +++ b/test/testCode/BS010QueryWithLimitSpec.php @@ -0,0 +1,134 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + self::$gridstore->dropContainer(self::$containerNameCol); + self::$gridstore->dropContainer(self::$containerNameTS); + + // Create a collection container + $containerInfoCol = new \ContainerInfo(["name" => self::$containerNameCol, + "columnInfoArray" => $columnInfoListCol, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + // Create a timeseries container + $containerInfoTS = new \ContainerInfo(["name" => self::$containerNameTS, + "columnInfoArray" => $columnInfoListTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + self::$gridstore->putContainer($containerInfoCol, true); + self::$gridstore->putContainer($containerInfoTS, true); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + public static function tearDownAfterClass(): void + { + // Delete container + try { + self::$gridstore->dropContainer(self::$containerNameCol); + self::$gridstore->dropContainer(self::$containerNameTS); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-010-Query-with-limit.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testQueryWithLimitSpec($testId, $containerType, + $queryStr, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + if ($containerType == "GS_CONTAINER_COLLECTION") { + $containerName = self::$containerNameCol; + } else { + $containerName = self::$containerNameTS; + } + $hasException = "0"; + + try { + $container = self::$gridstore->getContainer($containerName); + $query = $container->query($queryStr); + // Query fetch + $query->fetch(false); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS012ErrorUtilitySpec.php b/test/testCode/BS012ErrorUtilitySpec.php new file mode 100644 index 0000000..a04b764 --- /dev/null +++ b/test/testCode/BS012ErrorUtilitySpec.php @@ -0,0 +1,63 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + self::$gridstore->dropContainer("ER_col"); + + /** + * Container schema + */ + $columnInfoList = [["A", \Type::DOUBLE], + ["B", \Type::STRING], + ["a_9", \Type::BYTE], + ["za", \Type::SHORT], + ["1_a", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::TIMESTAMP], + ["I", \Type::BLOB]]; + // Create a collection container + $containerInfo = new \ContainerInfo(["name" => "ER_col", + "columnInfoArray" => $columnInfoList, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + self::$gridstore->putContainer($containerInfo, true); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals("1", $hasException); + } +} +?> + diff --git a/test/testCode/BS015ContainerInfoSetGetSpec.php b/test/testCode/BS015ContainerInfoSetGetSpec.php new file mode 100644 index 0000000..16a0294 --- /dev/null +++ b/test/testCode/BS015ContainerInfoSetGetSpec.php @@ -0,0 +1,132 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-015-ContainerInfo_set_get.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testContainerInfoSetGet($testId, $containerType, + $containerName, $containerType1, + $rowKeyAssigned, $columnInfoList, + $expirationInfo, $expectedOutput) + { + echo sprintf("Test case: %s put %s:\n", $testId, $containerType); + echo sprintf(" Put container name: %s\n", $containerName); + echo sprintf(" Expect has exception = %s\n", $expectedOutput); + + // Convert data test from string type in CSV to other data type + $containerType = convertData($containerType); + $rowKeyAssigned = convertData($rowKeyAssigned); + + // Convert $expirationInfo string in CSV to array + // For example: "[10;20;30]" => [10, 20, 30] + $expirationInfo = str_replace(["[", "]"], ["", ""], $expirationInfo); + $expirationInfo = explode(";", $expirationInfo); + $hasException = "0"; + + // Convert $columnInfoList string in CSV to array + // For example: [[A_0:GS_TYPE_STRING];[A9:GS_TYPE_BOOL];[za:GS_TYPE_DOUBLE]] + // => [[A_0,GS_TYPE_STRING],[A9,GS_TYPE_BOOL],[za,GS_TYPE_DOUBLE]] + $columnInfoList = str_replace(["[", "]"], ["", ""], $columnInfoList); + $columnInfoList = explode(";", $columnInfoList); + $columnInfoArray = []; + for ($i = 0; $i < sizeof($columnInfoList); $i++) { + $columnInfoArray[$i] = convertStrToRow($columnInfoList[$i]); + } + try { + /** + * Container schema + */ + $propList = [["A_0", \Type::STRING], + ["A9", \Type::BOOL], + ["za", \Type::DOUBLE]]; + $expirationInfoObj = new \ExpirationInfo(convertData($expirationInfo[0]), + convertData($expirationInfo[1]), + convertData($expirationInfo[2])); + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $propList, + "type" => $containerType, + "rowKey" => true]); + // Check ContainerInfo.name + $containerInfo->name = $containerName; + $name = $containerInfo->name; + $this->assertEquals($name, $containerName); + + // Check ContainerInfo.type + $containerInfo->type = $containerType; + $type = $containerInfo->type; + $this->assertEquals($type, $containerType); + + // Check ContainerInfo.rowKey + $containerInfo->rowKey = $rowKeyAssigned; + $rowKeyAssign = $containerInfo->rowKey; + $this->assertEquals($rowKeyAssign, $rowKeyAssigned); + + // Check ContainerInfo.expiration + $containerInfo->expiration = $expirationInfoObj; + $expirationInfoTmp = $containerInfo->expiration; + $this->assertEquals($expirationInfoObj->divisionCount, + $expirationInfoTmp->divisionCount); + $this->assertEquals($expirationInfoObj->unit, + $expirationInfoTmp->unit); + $this->assertEquals($expirationInfoObj->time, + $expirationInfoTmp->time); + + // Check ContainerInfo.columnInfoArray + $containerInfo->columnInfoArray = $columnInfoArray; + $columnInfoArrayTmp = $containerInfo->columnInfoArray; + $this->assertEquals($columnInfoArray, $columnInfoArrayTmp); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS016ExpirationInfoSetGetSpec.php b/test/testCode/BS016ExpirationInfoSetGetSpec.php new file mode 100644 index 0000000..d6213a4 --- /dev/null +++ b/test/testCode/BS016ExpirationInfoSetGetSpec.php @@ -0,0 +1,91 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/BS-016-ExpirationInfo_set_get.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testExpirationInfoSetGet($testId, $containerType, + $rowExpirationTime, + $rowExpirationTimeUnit, + $expirationDivisionCount, + $expectedOutput) + { + echo sprintf("Test case: %s:\n", $testId); + echo sprintf(" Expect has exception = %s\n", $expectedOutput); + + // Convert data test from string type in CSV to other data type + $containerType = convertData($containerType); + $rowExpirationTime = convertData($rowExpirationTime); + $rowExpirationTimeUnit = convertData($rowExpirationTimeUnit); + $expirationDivisionCount = convertData($expirationDivisionCount); + $hasException = "0"; + + try { + $expirationInfoObj = new \ExpirationInfo(0, 0, 0); + // Check ExpirationInfo.time + $expirationInfoObj->time = $rowExpirationTime; + $exTime = $expirationInfoObj->time; + $this->assertEquals($exTime, $rowExpirationTime); + + // Check ExpirationInfo.unit + $expirationInfoObj->unit = $rowExpirationTimeUnit; + $exTimeUnit = $expirationInfoObj->unit; + $this->assertEquals($exTimeUnit, $rowExpirationTimeUnit); + + // Check ExpirationInfo.divisionCount + $expirationInfoObj->divisionCount = $expirationDivisionCount; + $exDivisionCount = $expirationInfoObj->divisionCount; + $this->assertEquals($exDivisionCount, $expirationDivisionCount); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS018EnumSpec.php b/test/testCode/BS018EnumSpec.php new file mode 100644 index 0000000..e1861db --- /dev/null +++ b/test/testCode/BS018EnumSpec.php @@ -0,0 +1,60 @@ +getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($hasException, "0"); + } +} +?> + diff --git a/test/testCode/BS019AttributeSpec.php b/test/testCode/BS019AttributeSpec.php new file mode 100644 index 0000000..c7b9465 --- /dev/null +++ b/test/testCode/BS019AttributeSpec.php @@ -0,0 +1,314 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + + preSetupContainer(self::$gridstore, $containerNameList, $containerTypeList); + $timeSeries = self::$gridstore->getContainer("NQR_TS"); + $timeSeries->setAutoCommit(false); + $timeSeries->put([convertData("2018-12-01T10:10:00.000Z"), + "name01", true, 8, 90, 10, 0, + convertData("9999-12-31T23:59:59.999Z"), + 23.98, 1211.9232, pack('C*', 65, 66)]); + $timeSeries->put([convertData("2018-12-01T10:20:00.000Z"), + "name01", true, 8, 90, 10, 0, + convertData("9999-12-31T23:59:59.999Z"), + 23.98, 1211.9232, pack('C*', 65, 66)]); + $timeSeries->put([convertData("2018-12-01T10:30:00.000Z"), + "name01", true, 8, 90, 10, 0, + convertData("9999-12-31T23:59:59.999Z"), + 23.98, 1211.9232, pack('C*', 65, 66)]); + $timeSeries->put([convertData("2018-12-01T10:40:00.000Z"), + "name01", true, 8, 90, 10, 0, + convertData("9999-12-31T23:59:59.999Z"), + 23.98, 1211.9232, pack('C*', 65, 66)]); + $timeSeries->commit(); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + } + + public function createDropContainer($containerName, $containerInfo) { + $hasException = "0"; + try { + self::$gridstore->dropContainer($containerName); + self::$gridstore->putContainer($containerInfo); + self::$gridstore->dropContainer($containerName); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + $hasException = "1"; + } + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + return $hasException; + } + + /** + * Provider Data + */ + public function providerDataTest() { + return getTestData("test/resource/UC-017-Attribute.csv"); + } + + /** + * @dataProvider providerDataTest + */ + public function testAttribute($testId, $queryStr, $containerName, + $columnInfoList, $rowKeyAssigned, + $rowExpirationTime, $rowExpirationTimeUnit, + $divisionCount, $containerType, + $attribute, $expectedOutput) + { + echo sprintf("Test case: %s\n", $testId); + echo sprintf(" Expected has exception = %s\n", $expectedOutput); + $exceedString = file_get_contents('test/resource/exceedSizeColName.txt'); + + try { + // Container schema: + $propList = [["A_0", \Type::STRING], ["A9", \Type::BOOL], ["za", \Type::DOUBLE]]; + + $propList0 = [["bnfb", \Type::TIMESTAMP], ["ccvb", \Type::INTEGER]]; + + $propList1 = [["aaaaaaaaaaaaaa", \Type::STRING]]; + + $propList2 = [["a1", \Type::STRING], ["a2", -1]]; + + $propList3 = [["a1", \Type::STRING], ["a1", 20]]; + + $propList4 = [["a1", \Type::STRING], ["a1", \Type::BOOL]]; + + $propList5 = [["", \Type::STRING]]; + + $propList6 = [["a1", \Type::STRING], ["a1", 1.1]]; + + $propList7 = [["a1", \Type::STRING], [$exceedString, \Type::STRING]]; + + $propList8 = [["a1", \Type::STRING], ["a 0", \Type::INTEGER]]; + + $propList9 = [["a1", \Type::STRING], ["a_0", "GS_TYPE_STRING"]]; + + $propList10 = [["a1", \Type::STRING], ["!", \Type::BOOL]]; + + $propList11 = [["a1", \Type::STRING], ["/", \Type::BYTE]]; + + $propList12 = [["a1", \Type::STRING], ["⇿", \Type::SHORT]]; + + $propList13 = [["a1", \Type::STRING], ["1_a", \Type::INTEGER]]; + + $propList14 = [["A_0", \Type::STRING]]; + + $hasException = "0"; + $partitionController = self::$gridstore->partitionController; + if ($containerName == "" || $containerName == NULL) { + if ($containerType == "collection") { + $container = self::$gridstore->getContainer("NQR_Col"); + } else { + $container = self::$gridstore->getContainer("NQR_TS"); + } + } else { + $container = self::$gridstore->getContainer($containerName); + } + + switch ($attribute) { + case "container_type": + $type = $container->type; + break; + case "container_type(set)": + $container->type = \ContainerType::COLLECTION; + break; + case "PartitionInfo:partition_count": + $count = $partitionController->partitionCount; + break; + case "PartitionInfo:partition_count(set)": + $partitionController->partitionCount = 2; + break; + case "RowSet:type;RowSet:size": + $container = self::$gridstore->getContainer("NQR_Col"); + $query = $container->query($queryStr); + $rowSet = $query->fetch(); + $type = $rowSet->type; + $size = $rowSet->size; + break; + case "RowSet:type;RowSet:size(set)": + $container = self::$gridstore->getContainer("NQR_Col"); + $query = $container->query($queryStr); + $rowSet = $query->fetch(); + $rowSet->type = 10; // dummy data + $rowSet->size = 2; // dummy data + break; + case "ContainerInfo:name(set/get)": + if ($containerName == "16KB_string" || + $containerName == "exceed_16KB_string") { + $containerNameTmp = convertExtraData($containerName); + } else { + $containerNameTmp = convertData($containerName); + } + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["name", \Type::STRING], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + $name = $conInfo->name; + $conInfo->name = $containerNameTmp; + // Create/drop container + $hasException = $this->createDropContainer($containerNameTmp, $conInfo); + break; + case "ContainerInfo:column_info_list(set/get)": + $propListStr = "\$propList = \$propList"; + $propListStr.=$columnInfoList; + $propListStr.=";"; + eval($propListStr); + $conInfo = new \ContainerInfo(["name" => "Con_collection", + "columnInfoArray" => [["name", \Type::STRING], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + $infoList = $conInfo->columnInfoArray; + $conInfo->columnInfoArray = $propList; + // Create/drop Con_collection container + $hasException = $this->createDropContainer("Con_collection", $conInfo); + break; + case "ContainerInfo:row_key(set/get)": + $rowKeyAssigned = convertData($rowKeyAssigned); + if ($rowKeyAssigned === 0) { + $rowKeyAssigned = false; + } else if ($rowKeyAssigned == 1) { + $rowKeyAssigned = true; + } + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["name", \Type::STRING], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + $rowKey = $conInfo->rowKey; + $conInfo->rowKey = $rowKeyAssigned; + break; + case "ExpirationInfo:time(set/get)": + $rowExpirationTime = convertData($rowExpirationTime); + $expirationInfo = new \ExpirationInfo(100, \TimeUnit::MINUTE, 10); //dummy data + $time = $expirationInfo->time; + $expirationInfo->time = $rowExpirationTime; + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["bnfb", \Type::TIMESTAMP], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true, + "expiration" => $expirationInfo]); + $tmp = $conInfo->expiration; + $conInfo->expiration = $expirationInfo; + // Create/drop dummy container + $hasException = $this->createDropContainer("dummy", $conInfo); + break; + case "ExpirationInfo:unit(set/get)": + $rowExpirationTimeUnit = convertData($rowExpirationTimeUnit); + $expirationInfo = new \ExpirationInfo(100, \TimeUnit::MINUTE, 10); //dummy data + $time = $expirationInfo->unit; + $expirationInfo->unit = $rowExpirationTimeUnit; + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["bnfb", \Type::TIMESTAMP], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true, + "expiration" => $expirationInfo]); + // Create/drop dummy container + $hasException = $this->createDropContainer("dummy", $conInfo); + break; + case "ExpirationInfo:division_count(set/get)": + $divisionCount = convertData($divisionCount); + $expirationInfo = new \ExpirationInfo(100, \TimeUnit::MINUTE, 10); //dummy data + $tmp = $expirationInfo->divisionCount; + $expirationInfo->divisionCount = $divisionCount; + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["bnfb", \Type::TIMESTAMP], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true, + "expiration" => $expirationInfo]); + // Create/drop dummy container + $hasException = $this->createDropContainer("dummy", $conInfo); + break; + case "ContainerInfo:type(set/get)": + $containerType = convertData($containerType); + $conInfo = new \ContainerInfo(["name" => "dummy", + "columnInfoArray" => [["bnfb", \Type::TIMESTAMP], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + $tmp = $conInfo->type; + $conInfo->type = $containerType; + // Create/drop dummy container + $hasException = $this->createDropContainer("dummy", $conInfo); + break; + default: + $hasException ="1"; + break; + } + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals($expectedOutput, $hasException); + } +} +?> + diff --git a/test/testCode/BS021KeywordParametersSpec.php b/test/testCode/BS021KeywordParametersSpec.php new file mode 100644 index 0000000..e0b9b98 --- /dev/null +++ b/test/testCode/BS021KeywordParametersSpec.php @@ -0,0 +1,96 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + $gridstore = $factory->getStore($storeInfo); + + // Create a collection container with rowkey is string + $containerInfo = new \ContainerInfo(["name" => "col01", + "columnInfoArray" => [["name", \Type::STRING], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + + $gridstore->dropContainer("col01"); + $col = $gridstore->putContainer($containerInfo, true); + $col->setAutoCommit(false); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals("0", $hasException); + } + + // Test keyword parameter with invalid input + public function testKeywordParametersWithInvalidInput() + { + echo("Test case for hash parameters with invalid input\n"); + echo(" Expected has exception = 1\n"); + $hasException = "0"; + try { + $factory = \StoreFactory::getInstance(); + $storeInfo = ["host" => GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + $gridstore = $factory->getStore($storeInfo); + + // Create a collection container with invalid input + $containerInfo = new \ContainerInfo(["col02", + [["name", \Type::STRING], + ["status", \Type::BOOL], + ["count", \Type::LONG], + ["lob", \Type::BLOB]], + \ContainerType::COLLECTION, + true]); + } catch (\GSException $e) { + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $hasException = "1"; + } catch (\Exception $e1) { + echo($e1."\n"); + $hasException = "1"; + } + + //Assert result + $this->assertEquals("1", $hasException); + } +} +?> + diff --git a/test/testCode/config.php b/test/testCode/config.php new file mode 100644 index 0000000..7a2ca4f --- /dev/null +++ b/test/testCode/config.php @@ -0,0 +1,7 @@ + diff --git a/test/testCode/utility.php b/test/testCode/utility.php new file mode 100644 index 0000000..34c8e35 --- /dev/null +++ b/test/testCode/utility.php @@ -0,0 +1,242 @@ + $containerName[$i], + "columnInfoArray" => $rowKey, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + } else { + array_unshift($rowKey, ["A00", \Type::TIMESTAMP]); + $containerInfo = new \ContainerInfo(["name" => $containerName[$i], + "columnInfoArray" => $rowKey, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + } + $gridstore->putContainer($containerInfo); + } + } else { + $rowKey = $propList; + if ($containerType != "timestamp_timeseries") { + $containerTypeTmp = "\$containerTypeConvert = \Type::"; + $containerTypeTmp.= strtoupper($containerType); + $containerTypeTmp.= ";"; + eval($containerTypeTmp); + array_unshift($rowKey, ["A00", $containerTypeConvert]); + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $rowKey, + "type" => \Type::COLLECTION, + "rowKey" => true]); + } else { + array_unshif($rowKey, ["A00", \Type::TIMESTAMP]); + $containerInfo = new \ContainerInfo(["name" => $containerName, + "columnInfoArray" => $rowKey, + "type" => \Type::TIMSE_SERIES, + "rowKey" => true]); + } + $gridstore->putContainer($containerInfo); + } +} + +function tearDown($gridstore, $containerName) { + if (is_array($containerName)) { + for ($i = 0; $i < sizeof($containerName); $i ++) { + $gridstore->dropContainer($containerName[$i]); + } + } else { + $gridstore->dropContainer($containerName); + } +} +?> From db28a9094a0d9ae0b144e75732504045bf31319a Mon Sep 17 00:00:00 2001 From: knonomura Date: Wed, 19 Aug 2020 18:51:28 +0900 Subject: [PATCH 21/22] delete a sample using multiPut() --- sample/PutRows.php | 54 ---------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 sample/PutRows.php diff --git a/sample/PutRows.php b/sample/PutRows.php deleted file mode 100644 index 85248bb..0000000 --- a/sample/PutRows.php +++ /dev/null @@ -1,54 +0,0 @@ -getStore(["host" => $argv[1], - "port" => (int)$argv[2], - "clusterName" => $argv[3], - "username" => $argv[4], - "password" => $argv[5]]); - - // Create a collection - $conInfo = new ContainerInfo(["name" => $containerName, - "columnInfoArray" => [["id", Type::INTEGER], - ["productName", Type::STRING], - ["count", Type::INTEGER]], - "type" => ContainerType::COLLECTION, - "rowKey" => true]); - - $col = $gridstore->putContainer($conInfo); - echo("Create Collection name=$containerName\n"); - - // Register multiple rows - // (1)Get the container - $col1 = $gridstore->getContainer($containerName); - if ($col1 == null) { - echo("ERROR Container not found. name=$containerName\n"); - } - - // Register multiple rows - for ($i = 0; $i < $rowCount; $i++) { - $row = []; - array_push($row, $i, "dvd", 10*$i); - array_push($rowArray, $row); - $col1->multiPut($rowArray); - } - - echo("Put rows\n"); - echo("success!\n"); - } catch (GSException $e) { - for ($i= 0; $i < $e->getErrorStackSize(); $i++) { - echo("\n[$i]\n"); - echo($e->getErrorCode($i)."\n"); - echo($e->getLocation($i)."\n"); - echo($e->getErrorMessage($i)."\n"); - } - } -?> From 9e605a11dbe18aacb255a4ed649e3fa7d500585c Mon Sep 17 00:00:00 2001 From: knonomura Date: Thu, 20 Aug 2020 09:23:15 +0900 Subject: [PATCH 22/22] add test code for PartitionConrtoller API and update src --- sample/ContainerNames.php | 2 +- src/PartitionController.h | 2 +- src/gstype_php.i | 10 + test/resource/BS-013-PartitionController.csv | 15 ++ test/testCode/BS013PartitionController.php | 199 +++++++++++++++++++ test/testCode/utility.php | 18 ++ 6 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 test/resource/BS-013-PartitionController.csv create mode 100644 test/testCode/BS013PartitionController.php diff --git a/sample/ContainerNames.php b/sample/ContainerNames.php index 74b4b63..a655342 100644 --- a/sample/ContainerNames.php +++ b/sample/ContainerNames.php @@ -18,7 +18,7 @@ //(2)Loop by the number of partitions to get an array of container names for ($i = 0; $i < $pcCount; $i++) { - $arrayContainerNames = $pc->getContainerNames($i, 0); + $arrayContainerNames = $pc->getContainerNames($i, 0, -1); $nameCount = sizeof($arrayContainerNames); for ($j = 0; $j < $nameCount; $j++) { echo("$arrayContainerNames[$j]\n"); diff --git a/src/PartitionController.h b/src/PartitionController.h index 3adb3b0..b0faf8f 100644 --- a/src/PartitionController.h +++ b/src/PartitionController.h @@ -36,7 +36,7 @@ class PartitionController { 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); + int64_t limit); int32_t get_partition_index_of_container(const GSChar *container_name); private: diff --git a/src/gstype_php.i b/src/gstype_php.i index 724304d..ef26642 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -1276,3 +1276,13 @@ static bool checkTypeIsLongBool(zval* value) { } $1 = longVal; } + +/** +* Support to get long value +*/ +%typemap(in, fragment = "checkTypeIsLongBool") int64_t { + if (!checkTypeIsLongBool(&$input)) { + SWIG_exception(E_ERROR, "Expected long value as input"); + } + $1 = Z_LVAL_P(&$input); +} \ No newline at end of file diff --git a/test/resource/BS-013-PartitionController.csv b/test/resource/BS-013-PartitionController.csv new file mode 100644 index 0000000..2f18d08 --- /dev/null +++ b/test/resource/BS-013-PartitionController.csv @@ -0,0 +1,15 @@ +testID,partitionIndex,start,limit,containerName,hostname,expectedOutput +BS-013-PartitionController-001,0,,,,,0 +BS-013-PartitionController-002,127,,,,,0 +BS-013-PartitionController-003,-1,,,,,-1 +BS-013-PartitionController-004,0,1,2147483647,,,0 +BS-013-PartitionController-005,-1,2147483647,1,,,-1 +BS-013-PartitionController-006,-2147483649,0,2147483647,,,-1 +BS-013-PartitionController-007,2147483648,0,NULL,,,-1 +BS-013-PartitionController-008,1.1,1,2147483647,,,-1 +BS-013-PartitionController-009,a,1,NULL,,,-1 +BS-013-PartitionController-010,127,-1,1,,,-1 +BS-013-PartitionController-011,127,a,1,,,-1 +BS-013-PartitionController-012,127,-2147483649,1,,,-1 +BS-013-PartitionController-013,,,,PC_1,,0 +BS-013-PartitionController-014,,,,1a_,,-1 diff --git a/test/testCode/BS013PartitionController.php b/test/testCode/BS013PartitionController.php new file mode 100644 index 0000000..6b06539 --- /dev/null +++ b/test/testCode/BS013PartitionController.php @@ -0,0 +1,199 @@ + GRIDDB_NOTIFICATION_ADDRESS, + "port" => (int)GRIDDB_NOTIFICATION_PORT, + "clusterName" => GRIDDB_CLUSTER_NAME, + "username" => GRIDDB_USERNAME, + "password" => GRIDDB_PASSWORD]; + + self::$gridstore = $factory->getStore($storeInfo); + /** + * Container schema + */ + $columnInfoListCol = [["A", \Type::STRING], + ["B", \Type::TIMESTAMP], + ["a_9", \Type::BYTE], + ["za", \Type::SHORT], + ["1_a", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + + $columnInfoListTS = [["A", \Type::TIMESTAMP], + ["B", \Type::STRING], + ["a_9", \Type::BYTE], + ["za", \Type::SHORT], + ["1_a", \Type::INTEGER], + ["F", \Type::BOOL], + ["G", \Type::FLOAT], + ["H", \Type::DOUBLE], + ["I", \Type::BLOB]]; + + // Create a collection container + $containerInfoCol = new \ContainerInfo(["name" => self::$containerNameCol, + "columnInfoArray" => $columnInfoListCol, + "type" => \ContainerType::COLLECTION, + "rowKey" => true]); + // Create a timeseries container + $containerInfoTS = new \ContainerInfo(["name" => self::$containerNameTS, + "columnInfoArray" => $columnInfoListTS, + "type" => \ContainerType::TIME_SERIES, + "rowKey" => true]); + + self::$gridstore->dropContainer(self::$containerNameCol); + self::$gridstore->dropContainer(self::$containerNameTS); + self::$gridstore->putContainer($containerInfoCol, $modifiable); + self::$gridstore->putContainer($containerInfoTS, $modifiable); + } catch (\GSException $e){ + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + } catch (\Exception $e1) { + echo($e1."\n"); + } + } + + /** + * Provider Data + */ + public function providerDataTestGetContainerCount() { + return getTestDataFilter("test/resource/BS-013-PartitionController.csv", 0, 3); + } + + /** + * @dataProvider providerDataTestGetContainerCount + */ + public function testGetContainerCount($testId, $partitionIndex, $start, + $limit,$containerName, + $hostname, $expectedOutput) + { + echo sprintf("Test case: %s \n", $testId); + echo (" PartitionController::getContainerCount\n"); + $expectedOutputConvert = convertData($expectedOutput); + + try { + $partitionController = self::$gridstore->partitionController; + $retCount = $partitionController->getContainerCount(convertData($partitionIndex)); + + } catch (\GSException $e) { + echo("Throw $e\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $retCount = -1; + $this->assertLessThanOrEqual($retCount, $expectedOutputConvert); + } catch (\Exception $e1) { + echo($e1."\n"); + $retCount = -1; + $this->assertLessThanOrEqual($retCount, $expectedOutputConvert); + } + //Assert result + $this->assertLessThanOrEqual($retCount, $expectedOutputConvert); + } + + /** + * Provider Data + */ + public function providerDataTestGetContainerNames() { + return getTestDataFilter("test/resource/BS-013-PartitionController.csv", 3, 12); + } + + /** + * @dataProvider providerDataTestGetContainerNames + */ + public function testGetContainerNames($testId, $partitionIndex, $start, + $limit,$containerName, + $hostname, $expectedOutput) + { + echo sprintf("Test case: %s \n", $testId); + echo (" PartitionController::getContainerNames\n"); + $expectedOutputConvert = convertData($expectedOutput); + + try { + $partitionController = self::$gridstore->partitionController; + $containerNames = $partitionController->getContainerNames(convertData($partitionIndex), + convertData($start), + convertData($limit)); + $length = sizeof($containerNames); + } catch (\GSException $e) { + echo("Throw $e\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $length = -1; + $this->assertLessThanOrEqual($length, $expectedOutputConvert); + } catch (\Exception $e1) { + echo($e1."\n"); + $length = -1; + $this->assertLessThanOrEqual($length, $expectedOutputConvert); + } + //Assert result + $this->assertLessThanOrEqual($length, $expectedOutputConvert); + } + + /** + * Provider Data + */ + public function providerDataTestGetPartitionIndexOfContainer() { + return getTestDataFilter("test/resource/BS-013-PartitionController.csv", 13, 14); + } + + /** + * @dataProvider providerDataTestGetPartitionIndexOfContainer + */ + public function testGetPartitionIndexOfContainer($testId, $partitionIndex, + $start, $limit,$containerName, + $hostname, $expectedOutput) + { + echo sprintf("Test case: %s \n", $testId); + echo (" PartitionController::getPartitionIndexOfContainer\n"); + $expectedOutputConvert = convertData($expectedOutput); + + try { + $partitionController = self::$gridstore->partitionController; + $index = $partitionController->getPartitionIndexOfContainer(convertData($containerName)); + } catch (\GSException $e) { + echo("Throw $e\n"); + for ($i= 0; $i < $e->getErrorStackSize(); $i++) { + echo("\n[$i]\n"); + echo($e->getErrorCode($i)."\n"); + echo($e->getLocation($i)."\n"); + echo($e->getErrorMessage($i)."\n"); + } + $index = -1; + $this->assertLessThanOrEqual($index, $expectedOutputConvert); + } catch (\Exception $e1) { + echo($e1."\n"); + $index = -1; + $this->assertLessThanOrEqual($index, $expectedOutputConvert); + } + //Assert result + $this->assertLessThanOrEqual($index, $expectedOutputConvert); + } +} +?> + diff --git a/test/testCode/utility.php b/test/testCode/utility.php index 34c8e35..9a4a527 100644 --- a/test/testCode/utility.php +++ b/test/testCode/utility.php @@ -12,6 +12,24 @@ function getTestData($filePath) { return $data; } +function getTestDataFilter($filePath, $start, $finish) { + $file = file_get_contents($filePath, "r"); + $index = 0; + $numberLine = 0; + $dataFilter = []; + foreach (explode("\n", $file, -1) as $line) { + if ($index != 0) { + $numberLine++; + if ($start <= $numberLine && $finish >= $numberLine) { + $data[] = str_getcsv($line, ","); + } + } else { + $index = 1; + } + } + return $data; +} + // Convert string to bool function convertStrToBool($str) { if ($str == 'True' || $str == 'TRUE' || $str == 'true'):