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) 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. 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 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/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/ContainerNames.php b/sample/ContainerNames.php index b7eabe4..a655342 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, -1); + $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"; } ?> diff --git a/src/AggregationResult.cpp b/src/AggregationResult.cpp index 24ae7ca..32918ce 100644 --- a/src/AggregationResult.cpp +++ b/src/AggregationResult.cpp @@ -1,77 +1,76 @@ /* - 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..202e946 100644 --- a/src/AggregationResult.h +++ b/src/AggregationResult.h @@ -1,43 +1,42 @@ /* - 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 "GSException.h" -#include +#include -using namespace std; +#include "GSException.h" +#include "Field.h" +#include "gridstore.h" namespace griddb { - class AggregationResult : public Resource { - GSAggregationResult* mAggResult; - public: - AggregationResult(GSAggregationResult* aggResult); - ~AggregationResult(); +class AggregationResult { + GSAggregationResult *mAggResult; - long get_long(); - double get_double(); - GSTimestamp get_timestamp(); - private: - void close(); - }; + friend class RowSet; + 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 f51d2e3..a454900 100644 --- a/src/Container.cpp +++ b/src/Container.cpp @@ -1,338 +1,415 @@ /* - 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" +#include namespace griddb { - 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; - } - } - -} - - + 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(); + // This is for set for normal data (int, float, double..) + (*mContainerInfo) = (*containerInfo); + 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 (std::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 + */ + 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); + } + } + + /** + * @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 + */ + 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); + } + } + + /** + * @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 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. + */ + 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 (std::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; + + 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); + 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 static_cast(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; + } +} /* namespace griddb */ diff --git a/src/Container.h b/src/Container.h index 183ce08..3fe13df 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" -using namespace std; +#include "GSException.h" +#include "Util.h" namespace griddb { - class Container : public Resource { +class Container { + GSContainerInfo *mContainerInfo; + GSContainer *mContainer; + + friend class Store; - GSContainer *mContainer; + GSRow *mRow; + GSType *mTypeList; - public: - Container(GSContainer *container); - ~Container(); + public: + bool timestamp_output_with_float; + ~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 = + 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(); - 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: + Container(GSContainer *container, GSContainerInfo *containerInfo); + void freeMemoryContainer(); +}; - private: - void close(); - }; -} +} /* namespace griddb */ #endif /* _CONTAINER_H_ */ diff --git a/src/ContainerInfo.cpp b/src/ContainerInfo.cpp index f1be8e0..a49b529 100644 --- a/src/ContainerInfo.cpp +++ b/src/ContainerInfo.cpp @@ -1,32 +1,396 @@ /* - 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 (std::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 (std::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 (std::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 (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 + for (int i = 0; i < columnInfoList.size; i++) { + if (columnInfoList.columnInfo[i].name) { + try { + Util::strdup(&(tmpColumnInfoList[i].name), + columnInfoList.columnInfo[i].name); + } catch (std::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 = 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 + */ + 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 (std::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() { + const GSTimeSeriesProperties *timeSeriesProperties = mContainerInfo + .timeSeriesProperties; + if (timeSeriesProperties != NULL) { + if (mExpInfo != NULL) { + mExpInfo->set_time(timeSeriesProperties->rowExpirationTime); + mExpInfo->set_time_unit( + timeSeriesProperties->rowExpirationTimeUnit); + mExpInfo->set_division_count( + timeSeriesProperties->expirationDivisionCount); + } else { + try { + mExpInfo = new ExpirationInfo( + timeSeriesProperties->rowExpirationTime, + timeSeriesProperties->rowExpirationTimeUnit, + timeSeriesProperties->expirationDivisionCount); + } catch (std::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..14996e1 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 -#include "gridstore.h" +#include +#include -using namespace std; +#include "TimeSeriesProperties.h" +#include "ExpirationInfo.h" +#include "GSException.h" +#include "Util.h" + +// Support column_info_list attribute +struct ColumnInfoList { + GSColumnInfo *columnInfo; + size_t size; +}; 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: + 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 */ -#endif /* SRC_CONTAINERINFO_H_ */ +#endif /* Define _CONTAINERINFO_H_ */ diff --git a/src/EnumValue.h b/src/EnumValue.h new file mode 100644 index 0000000..ea0451f --- /dev/null +++ b/src/EnumValue.h @@ -0,0 +1,103 @@ +/* + 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_ + +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; +}; +} /* namespace griddb */ + +#endif diff --git a/src/ExpirationInfo.h b/src/ExpirationInfo.h new file mode 100644 index 0000000..f80b51a --- /dev/null +++ b/src/ExpirationInfo.h @@ -0,0 +1,87 @@ +/* + 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 + +namespace griddb { +class ExpirationInfo { + /* + * Contains information about expiration configuration + */ + GSTimeSeriesProperties 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 */ + +#endif diff --git a/src/Field.cpp b/src/Field.cpp new file mode 100644 index 0000000..3964bfd --- /dev/null +++ b/src/Field.cpp @@ -0,0 +1,107 @@ +/* + 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[] 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; + } + break; + default: + // Not need to free allocation + break; + } + } +} /* namespace griddb */ diff --git a/src/Field.h b/src/Field.h new file mode 100644 index 0000000..1a1660a --- /dev/null +++ b/src/Field.h @@ -0,0 +1,36 @@ +/* + 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" + +namespace griddb { + +class Field { + public: + GSType type; + GSValue value; + Field(); + ~Field(); +}; +} /* namespace griddb */ + +#endif /* _FIELD_H_ */ diff --git a/src/GSException.h b/src/GSException.h index 2621232..b652cc5 100644 --- a/src/GSException.h +++ b/src/GSException.h @@ -1,72 +1,278 @@ /* - 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; +using std::string; +using std::exception; + +#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: + 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; + mInnerMessagesStack = NULL; + mInnerErrorLocationStack = NULL; + mIsTimeout = false; + } + } + 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; + 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() 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..afb473d 100644 --- a/src/PartitionController.cpp +++ b/src/PartitionController.cpp @@ -1,155 +1,129 @@ /* - 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 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 + * @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..b0faf8f 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,28 @@ #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(); + 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, + int64_t limit); + 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 09dda2a..eacbc9a 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -1,93 +1,118 @@ /* - 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 (std::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 (std::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. + */ + 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); + if (!GS_SUCCEEDED(ret)) { + throw GSException(mQuery, ret); + } + } + } +} /* namespace griddb */ diff --git a/src/Query.h b/src/Query.h index c4b6753..e7ba9a1 100644 --- a/src/Query.h +++ b/src/Query.h @@ -1,48 +1,52 @@ /* - 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" -using namespace std; 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); + 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 new file mode 100644 index 0000000..cf3c384 --- /dev/null +++ b/src/QueryAnalysisEntry.cpp @@ -0,0 +1,149 @@ +/* + 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 (std::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 (std::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"); + } + } +} /* namespace griddb */ diff --git a/src/QueryAnalysisEntry.h b/src/QueryAnalysisEntry.h new file mode 100644 index 0000000..d6769d3 --- /dev/null +++ b/src/QueryAnalysisEntry.h @@ -0,0 +1,43 @@ +/* + 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" + +namespace griddb { + +class QueryAnalysisEntry { + 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/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_ */ diff --git a/src/RowKeyPredicate.cpp b/src/RowKeyPredicate.cpp index 917c557..122a4bf 100644 --- a/src/RowKeyPredicate.cpp +++ b/src/RowKeyPredicate.cpp @@ -1,323 +1,310 @@ /* - 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); + // 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; + 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 (std::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 (std::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, + 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 = 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 (std::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..bcae4e9 100644 --- a/src/RowKeyPredicate.h +++ b/src/RowKeyPredicate.h @@ -1,67 +1,55 @@ /* - 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_ #define _ROWKEYPREDICATE_H_ +#include +#include #include #include -#include "Resource.h" -#include "gridstore.h" -using namespace std; +#include "gridstore.h" +#include "Field.h" +#include "GSException.h" +#include "Util.h" 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..6168a33 100644 --- a/src/RowSet.cpp +++ b/src/RowSet.cpp @@ -1,117 +1,288 @@ /* - 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 static_cast(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 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. + */ + 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 (std::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 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. + */ + 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 (std::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 (std::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 (std::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; + } + +} /* namespace griddb */ diff --git a/src/RowSet.h b/src/RowSet.h index 95e11a8..1092d8c 100644 --- a/src/RowSet.h +++ b/src/RowSet.h @@ -1,56 +1,77 @@ /* - 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 -using namespace std; +#include "gridstore.h" +#include "Field.h" +#include "AggregationResult.h" +#include "QueryAnalysisEntry.h" +#include "GSException.h" +#include "Util.h" 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(); + void set_size(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 set_type(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 7829947..b98c781 100644 --- a/src/Store.cpp +++ b/src/Store.cpp @@ -1,180 +1,372 @@ /* - 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 (std::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 (std::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 (std::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 (std::bad_alloc &ba) { + gsClosePartitionController(&partitionController); + throw GSException(mStore, "Memory allocation error"); + } + } + + /** + * @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 + * @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 (std::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 (std::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 = 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 (std::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 (std::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; + } +} /* namespace griddb */ diff --git a/src/Store.h b/src/Store.h index e6ada46..47b445a 100644 --- a/src/Store.h +++ b/src/Store.h @@ -1,64 +1,70 @@ /* - 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 - -using namespace std; +#include "GSException.h" 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(); + void set_partition_info(PartitionController *pattition_controller); + 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 b3f49c4..8f3dde3 100644 --- a/src/StoreFactory.cpp +++ b/src/StoreFactory.cpp @@ -1,88 +1,189 @@ /* - 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 (std::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; + char *savePtr; + try { + Util::strdup((const GSChar**) &tmp, address); + } catch (std::bad_alloc &ba) { + throw GSException("Memory allocation error"); + } + + char *octets = strtok_r(tmp, ".", &savePtr); + 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(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 (std::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; + } +} /* namespace griddb */ diff --git a/src/StoreFactory.h b/src/StoreFactory.h index f7680f3..43b9760 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 -using namespace std; +#include "gridstore.h" +#include "Store.h" +#include "GSException.h" +#include "Util.h" 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, 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 c355d43..98105c6 100644 --- a/src/TimeSeriesProperties.cpp +++ b/src/TimeSeriesProperties.cpp @@ -1,58 +1,97 @@ /* - 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..da2c1e9 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,26 @@ 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: + 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 88823d3..66371f0 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 PHP DateTime to GridDB timestamp + */ + int64_t TimestampUtils::get_time_millis(int64_t timestamp) { + return timestamp; + } } /* namespace griddb */ diff --git a/src/TimestampUtils.h b/src/TimestampUtils.h index a193e1a..0a30806 100644 --- a/src/TimestampUtils.h +++ b/src/TimestampUtils.h @@ -1,39 +1,33 @@ /* - 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_ -#include "gridstore.h" +#ifndef _TIMESTAMPUTILS_H_ +#define _TIMESTAMPUTILS_H_ #include +#include "gridstore.h" #include "GSException.h" -using namespace std; - namespace griddb { - 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); - }; +class TimestampUtils { + public: + TimestampUtils(); + ~TimestampUtils(); + static int64_t get_time_millis(int64_t timestamp); +}; } /* namespace griddb */ diff --git a/src/Util.cpp b/src/Util.cpp new file mode 100644 index 0000000..c002897 --- /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](); + strncpy(temp, from, strlen(from)); + *to = temp; + } +} /* namespace griddb */ diff --git a/src/Util.h b/src/Util.h new file mode 100644 index 0000000..e57651e --- /dev/null +++ b/src/Util.h @@ -0,0 +1,32 @@ +/* + 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" + +namespace griddb { + +class Util { + public: + static void strdup(const GSChar **const to, const GSChar *from); +}; + +} + +#endif diff --git a/src/griddb.i b/src/griddb.i index c0de9f3..8e05896 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..c3ab4bd 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,65 @@ enum GSIndexTypeFlagTag { GS_INDEX_FLAG_HASH, GS_INDEX_FLAG_SPATIAL }; - -typedef int32_t GSTypeOption; - -typedef int32_t GSIndexTypeFlags; - -typedef int64_t GSTimestamp; - -typedef int32_t GSEnum; - -typedef GSEnum GSRowSetType; - -typedef GSEnum GSContainerType; - -typedef GSEnum GSType; - -typedef int32_t GSResult; - -typedef char GSChar; - -typedef char GSBool; - -typedef GSEnum GSTimeUnit; +#endif enum GSFetchOptionTag { - GS_FETCH_LIMIT, -#if GS_COMPATIBILITY_SUPPORT_1_5 - #if GS_INTERNAL_DEFINITION_VISIBLE #if !GS_COMPATIBILITY_DEPRECATE_FETCH_OPTION_SIZE GS_FETCH_SIZE = (GS_FETCH_LIMIT + 1) #endif -#endif - #endif }; +#if !defined(SWIGGO) enum GSTimeUnitTag { + GS_TIME_UNIT_YEAR, + + GS_TIME_UNIT_MONTH, - GS_TIME_UNIT_YEAR, + GS_TIME_UNIT_DAY, + GS_TIME_UNIT_HOUR, - GS_TIME_UNIT_MONTH, + GS_TIME_UNIT_MINUTE, + GS_TIME_UNIT_SECOND, - GS_TIME_UNIT_DAY, + GS_TIME_UNIT_MILLISECOND +}; +#endif +enum GSTypeOptionTag { + GS_TYPE_OPTION_KEY = 1 << 0, - GS_TIME_UNIT_HOUR, + GS_TYPE_OPTION_NULLABLE = 1 << 1, + GS_TYPE_OPTION_NOT_NULL = 1 << 2, +}; - GS_TIME_UNIT_MINUTE, +typedef int32_t GSTypeOption; +typedef int32_t GSIndexTypeFlags; - GS_TIME_UNIT_SECOND, +typedef int64_t GSTimestamp; +typedef int32_t GSEnum; - GS_TIME_UNIT_MILLISECOND -}; +typedef GSEnum GSRowSetType; + +typedef GSEnum GSContainerType; + +typedef GSEnum GSType; + +typedef int32_t GSResult; + +typedef char GSChar; + +typedef char GSBool; + +typedef GSEnum GSTimeUnit; typedef struct GSQueryAnalysisEntryTag GSQueryAnalysisEntry; diff --git a/src/gstype_php.i b/src/gstype_php.i index 835a8ed..ef26642 100644 --- a/src/gstype_php.i +++ b/src/gstype_php.i @@ -1,522 +1,1288 @@ /* - 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. +*/ +#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("%(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; + +/* + * Use attribute in PHP language + */ +%include + +// Read only attribute Container::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, set_size); +// Read only attribute RowSet::type +%attribute(griddb::RowSet, GSRowSetType, type, type, set_type); +// Read and write attribute ContainerInfo::name +%attribute(griddb::ContainerInfo, GSChar*, name, get_name, set_name); +// Read and write attribute ContainerInfo::type +%attribute(griddb::ContainerInfo, GSContainerType, type, get_type, set_type); +// Read and write attribute ContainerInfo::rowKey +%attribute(griddb::ContainerInfo, bool, rowKey, + get_row_key_assigned, set_row_key_assigned); +// Read and write attribute ContainerInfo::columnInfoArray +%attributeval(griddb::ContainerInfo, ColumnInfoList, columnInfoArray, + get_column_info_list, set_column_info_list); +// Read and write attribute ContainerInfo::expiration +%attribute(griddb::ContainerInfo, griddb::ExpirationInfo*, expiration, + get_expiration_info, set_expiration_info); +// Read and write attribute ExpirationInfo::time +%attribute(griddb::ExpirationInfo, int, time, get_time, set_time); +// Read and write attribute ExpirationInfo::unit +%attribute(griddb::ExpirationInfo, GSTimeUnit, unit, + get_time_unit, set_time_unit); +// 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, set_partition_info); +// Read only attribute PartitionController::partitionCount +%attribute(griddb::PartitionController, int, partitionCount, + get_partition_count, set_partition_count); + +/* + * 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* obj_typename = "GSException"; - size_t obj_typename_len = strlen(obj_typename); - // 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 ctor_rv; + SWIG_SetPointerZval(&resource, reinterpret_cast(exception), + $descriptor(griddb::GSException *), 1); + zval ex; + 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); - 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, &ctor_rv, 1, &resource, NULL TSRMLS_CC); - if (Z_TYPE(ctor_rv) != IS_UNDEF) { - zval_ptr_dtor(&ctor_rv); - } + // 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); + + // Check if no references remaining to ctorRv variable, then destroy it + 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.get_code(), $1.what()); + +%typemap(throws, fragment = "throwGSException") griddb::GSException %{ + griddb::GSException* tmpException = new griddb::GSException(&$1); throwGSException(tmpException); return; %} /** - * Typemaps for put_container() function + * 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) (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(); +%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) { + SWIG_exception(E_ERROR, "Expected associative array as input"); } + arr = Z_ARRVAL_P(&$input); - $2 = (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 $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++; - } + $2 = 0; + $3 = NULL; + $4 = NULL; + $5 = NULL; + $6 = NULL; + $7 = NULL; + $8 = NULL; + + if (length == 0) { + SWIG_exception(E_ERROR, "Expected not empty array as input"); } -} -%typemap(typecheck) (const GSColumnInfo* props, int propsCount) { - $1 = (Z_TYPE_P(&$input) == IS_ARRAY) ? 1 : 0; -} + 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_exception(E_ERROR, "Expected string as input for key"); + } -%typemap(freearg) (const GSColumnInfo* props, int propsCount) (int i) { - if ($1) { - free((void *) $1); + name = ZSTR_VAL(key); + if (strcmp(name, "host") == 0) { + if (Z_TYPE_P(data) != IS_STRING) { + 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_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_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_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_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_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_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_exception(E_ERROR, "Expected string as" + " input for host notificationProvider property"); + } + $8 = Z_STRVAL_P(data); + } else { + SWIG_exception(E_ERROR, "Invalid Property"); + } } } /** - * Typemaps for get_store() function + * Typemaps for ContainerInfo : support keyword parameter ("name" : str, + * "columnInfoArray" : array, "type" : int, 'rowKey' : boolean, + * "expiration" : expiration object) */ -%typemap(in) (const GSPropertyEntry* props, int propsCount) -(HashTable *arr, HashPosition pos, zval *data) { - if(Z_TYPE_P(&$input) != IS_ARRAY) { - php_printf("Expected associative array as input"); - SWIG_FAIL(); +%typemap(in, numinputs = 1, fragment = "freeArgContainerInfo", + fragment = "checkTypeIsLongBool") + (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) { + if (Z_TYPE_P(&$input) != IS_ARRAY) { + SWIG_exception(E_ERROR, "Expected associative array as input"); } - arr = Z_ARRVAL_P(&$input); - $2 = (int) zend_hash_num_elements(arr); + char* name = 0; + // Create $1, $2, $3, $3, $4, $5, $6 with default value $1 = NULL; - if ($2 > 0) { - $1 = (GSPropertyEntry *) malloc($2*sizeof(GSPropertyEntry)); - 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_STRING) { - $1[i].name = ZSTR_VAL(key); - $1[i].value = Z_STRVAL_P(data); + $2 = NULL; + $3 = 0; + $4 = GS_CONTAINER_COLLECTION; + $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 = zend_hash_num_elements(arrContainerInfo); + + if (sizeOfContainerInfo == 0) { + SWIG_exception(E_ERROR, "Expected 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) { + 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) { + 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) { + freeArgContainerInfo($2); + SWIG_exception(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) { + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected not empty array"); + } + $2 = new GSColumnInfo[$3]; + if ($2 == NULL) { + SWIG_exception(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) { + 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) { + freeArgContainerInfo($2); + 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) { + freeArgContainerInfo($2); + SWIG_exception(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) { + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected an integer as" + " column type"); + } + $2[i].type = Z_LVAL_P(columnType); i++; } + } else if (strcmp(name, "type") == 0) { + if (Z_TYPE_P(dataContainerInfo) != IS_LONG) { + 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 (!checkTypeIsLongBool(dataContainerInfo)) { + freeArgContainerInfo($2); + SWIG_exception(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)) { + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Expected expiration object" + " as input for expiration property"); + } + $6 = (griddb::ExpirationInfo *) expiration; + } else { + freeArgContainerInfo($2); + SWIG_exception(E_ERROR, "Invalid Property"); } } } -%typemap(freearg) (const GSPropertyEntry* props, int propsCount) (int i = 0) { - if ($1) { - free((void *) $1); +/** + * Cleanup argument data for ContainerInfo constructor + */ +%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; } } +} -/** - * 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(); +%fragment("convertToFieldWithType", "header", + fragment = "convertZvalValueToFloat", + fragment = "convertZvalValueToDouble", + fragment = "convertDateTimeObjectToGSTimestamp", + fragment = "checkTypeIsLongBool") { +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)); } - 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++; + + switch (type) { + case GS_TYPE_STRING: { + GSChar* stringVal; + if (Z_TYPE_P(value) != IS_STRING) { + return false; + } + 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; + } + longVal = Z_LVAL_P(value); + returnCode = gsSetRowFieldByLong(row, column, longVal); + break; + } + case GS_TYPE_BOOL: { + if (!checkTypeIsLongBool(value)) { + return false; + } + bool boolVal; + boolVal = static_cast (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; + } + byteVal = Z_LVAL_P(value); + if (byteVal < std::numeric_limits::min() || + byteVal > std::numeric_limits::max()) { + return false; + } + returnCode = gsSetRowFieldByByte(row, column, byteVal); + break; + } + 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; + } + returnCode = gsSetRowFieldByShort(row, column, shortVal); + 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; + } + returnCode = gsSetRowFieldByInteger(row, column, intVal); + break; + } + case GS_TYPE_FLOAT: { + float floatVal; + isSuccess = convertZvalValueToFloat(value, &floatVal); + if (!isSuccess) { + return false; + } + returnCode = gsSetRowFieldByFloat(row, column, floatVal); + break; + } + 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)); +} } -%typemap(freearg) (GSQuery* const* queryList, size_t queryCount) { - if ($1) { - free((void *) $1); +/** + * 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; } } +} /** - * Typemaps for put_multi_row_container() function + * Support convert type from Zval value to Float. + * Input in target language can be : float or integer */ -%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(); +%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; } - 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++; - } +} +} + +/** + * 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) { + // 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); + 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; +} } -%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); - } +/** +* 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) { + const int SIZE = 60; + if (Z_TYPE_P(&$input) != IS_ARRAY) { + SWIG_exception(E_ERROR, "Expected an array as input"); + } + arr = Z_ARRVAL_P(&$input); + int length = zend_hash_num_elements(arr); + GSRow *tmpRow = arg1->getGSRowPtr(); + int colNum = arg1->getColumnCount(); + GSType* typeList = arg1->getGSTypeList(); + + if (length != colNum) { + SWIG_exception(E_ERROR, "Num row is different with container info"); + } + + 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]; + snprintf(gsType, SIZE, "Invalid value for column %d," + " type should be : %d", pos, type); + SWIG_exception(E_ERROR, gsType); } - free((void *) $1); } } /** - * Typemaps for put_multi_row() function + * Support convert row key Field from zval* in target language to + * C Object with specific type */ -%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(); +%fragment("convertToRowKeyFieldWithType", "header") { +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 + return false; } - 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++; + switch (type) { + case (GS_TYPE_STRING): + if (Z_TYPE_P(value) != IS_STRING) { + return false; } - } + griddb::Util::strdup(&field.value.asString, 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): + isSuccess = convertDateTimeObjectToGSTimestamp( + value, &field.value.asTimestamp); + if (!isSuccess) { + return false; + } + break; + default: + // Not support for now + return false; + break; } + return true; +} } -%typemap(freearg) (const void* const * rowObjs, size_t rowCount) { - if ($1) { - free((void *) $1); +/* +* 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_exception(E_ERROR, "Can not convert to row field"); + } } } -// 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) {} +%typemap(in, numinputs = 0) (GSRow *rowdata) { + $1 = NULL; +} /** - * Typemaps for set_field_by_byte_array() function + * Support convert data from GSRow* row to zval array */ -%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++; +%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 + GSBool nullValue; + returnCode = gsGetRowFieldNull(row, (int32_t) i, &nullValue); + if (!GS_SUCCEEDED(returnCode)) { + *columnError = i; + returnValue = false; + *fieldTypeError = GS_TYPE_NULL; + return returnValue; + } + if (nullValue) { + add_index_null(outList, i); + continue; + } + switch (typeList[i]) { + case GS_TYPE_LONG: { + int64_t 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; + 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}; + returnCode = gsGetRowFieldAsBlob(row, (int32_t) i, &blobValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } + add_index_stringl(outList, i, + reinterpret_cast(blobValue.data), + blobValue.size); + break; + } + case GS_TYPE_BOOL: { + GSBool boolValue; + bool boolVal; + returnCode = gsGetRowFieldAsBool(row, (int32_t) i, &boolValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } + if (boolValue == GS_TRUE) { + boolVal = true; + } else { + boolVal = false; + } + add_index_bool(outList, i, boolVal); + break; + } + case GS_TYPE_INTEGER: { + int32_t 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; + 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; + 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; + zval 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; + 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; + returnCode = gsGetRowFieldAsShort(row, (int32_t) i, &shortValue); + if (!GS_SUCCEEDED(returnCode)) { + break; + } + add_index_long(outList, i, shortValue); + break; + } + default: { + // NOT OK + returnCode = -1; + break; + } + } + if (!GS_SUCCEEDED(returnCode)) { + *columnError = i; + *fieldTypeError = typeList[i]; + returnValue = false; + return returnValue; } } + return returnValue; +} } -%typemap(freearg) (const int8_t *fieldValue, size_t size) { - if ($1) { - free((void *) $1); +/** + * Support convert data from timestamp to DateTime object in target language + */ +%fragment("convertTimestampToDateTimeObject", "header") { +static void convertTimestampToDateTimeObject(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; + snprintf(timeStr, SIZE, "%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) { + if (result == GS_FALSE) { + RETVAL_NULL(); + } else { + bool returnValue; + 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()); + 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_exception(E_ERROR, errorMsg); + } } } /** - * Typemaps input for get_multi_container_row() function + * Support convert AggregationResult object from C++ layer to PHP language */ -%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"); +%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(); } - 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; + object_and_properties_init(AggregationResultZvalObject, ce, NULL); - for (i = 0; i < $2; i++) { - if(pList[i].containerName) { - free((void *) pList[i].containerName); - } - } - free((void *) pList); + // 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); } } +} /** - * Typemaps output for get_multi_container_row() function + * Type map for Rowset::next() */ -%typemap(in, numinputs = 0) (const GSContainerRowEntry **entryList, size_t *entryCount) (GSContainerRowEntry *pEntryList, size_t temp) { - $1 = &pEntryList; - $2 = &temp; +%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="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); +%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(); + } + switch (*$1) { + case (GS_ROW_SET_CONTAINER_ROWS): { + bool returnValue; + int errorColumn; + + 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_exception(E_ERROR, errorMsg); } + break; } - add_assoc_zval(&temp_result, entry->containerName, &list); + case (GS_ROW_SET_AGGREGATION_RESULT): + convertToAgrregationResultZvalObj(*$4, return_value); + break; + case (GS_ROW_SET_QUERY_ANALYSIS): + // Not support now + SWIG_exception(E_ERROR, "Function is not supportted now"); + break; + default: + SWIG_exception(E_ERROR, "Invalid Rowset type"); + break; } - 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 for get function in AggregationResult class +*/ +%typemap(in, numinputs = 0) (griddb::Field *agValue) + (griddb::Field tmpAgValue) { + $1 = &tmpAgValue; } -%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(argout) (griddb::Field *agValue) { + 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: + convertTimestampToDateTimeObject(&($1->value.asTimestamp), + return_value); + break; + default: + RETURN_NULL(); } } -%typemap(in, numinputs=0) (const int **intList, size_t *size) (int *intList1, size_t size1) { - $1 = &intList1; - $2 = &size1; +/* +* 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) { + bool isSuccess; + GSTimestamp timestampValue; + isSuccess = convertDateTimeObjectToGSTimestamp(&$input, ×tampValue); + if (!isSuccess) { + SWIG_exception(E_ERROR, "Expected a DateTime object as input"); + } + $1 = timestampValue; } -%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 for set attribute ContainerInfo::column_info_list +*/ +%typemap(in, numinputs = 1, fragment = "freeArgColumnInfoList") (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_exception(E_ERROR, "Expected an array as input"); + } + + arrColumnInfoArray = Z_ARRVAL_P(&$input); + int length = zend_hash_num_elements(arrColumnInfoArray); + + if (length == 0) { + SWIG_exception(E_ERROR, "Expected not empty array as input"); + } + + containerInfo = new GSColumnInfo[length]; + if (containerInfo == NULL) { + SWIG_exception(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) { + 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) { + 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) { + freeArgColumnInfoList($1); + SWIG_exception(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) { + freeArgColumnInfoList($1); + SWIG_exception(E_ERROR, "Expected an integer as column type"); + } + containerInfo[i].type = Z_LVAL_P(columnType); + i++; } } -%typemap(in, numinputs=0) (const long **longList, size_t *size) (long *longList1, size_t size1) { - $1 = &longList1; - $2 = &size1; +/** + * Cleanup argument data for set attribute ContainerInfo::column_info_list + */ +%typemap(freearg, fragment = "freeArgColumnInfoList") (ColumnInfoList*) { + freeArgColumnInfoList($1); } -%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]); +%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); } } +} -// set_field_as_blob -%typemap(in) (const GSBlob *fieldValue) { - if(Z_TYPE_P(&$input) != IS_STRING) { - php_printf("Expected string as input"); - RETURN_NULL(); +/* +* 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); } +} + +/** +* 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; +} - $1 = (GSBlob*) malloc(sizeof(GSBlob)); +%typemap(argout, numinputs = 0) (const GSChar * const ** stringList, + size_t *size) { + GSChar** nameList = *$1; + size_t size = *$2; - convert_to_string(&$input); - $1->size = Z_STRLEN_P(&$input); - $1->data = (char*) Z_STRVAL($input); + array_init_size(return_value, size); + for (int i = 0; i < size; i++) { + add_next_index_string(return_value, nameList[i]); + } } -%typemap(freearg) (const GSBlob *fieldValue) { - if ($1) { - free((void *) $1); +/** +* 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; +} } -%typemap(in, numinputs = 0) (GSBlob *value) (GSBlob pValue) { - $1 = &pValue; +/** +* 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); } -// 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); +/** +* 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; } -// Type check for GSBool type -%php_typecheck2(GSBool, SWIG_TYPECHECK_BOOL, IS_TRUE, IS_FALSE) +/** +* 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-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-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/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/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/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..9a4a527 --- /dev/null +++ b/test/testCode/utility.php @@ -0,0 +1,260 @@ += $numberLine) { + $data[] = str_getcsv($line, ","); + } + } else { + $index = 1; + } + } + return $data; +} + +// Convert string to bool +function convertStrToBool($str) { + if ($str == 'True' || $str == 'TRUE' || $str == 'true'): + $ret = True; + elseif ($str == 'False'|| $str == 'FALSE' || $str == 'false'): + $ret = False; + elseif ($str == 'NULL' || $str == 'Null' || $str == 'null' || $str == 'None'): + $ret = NULL; + else: + $ret = $str; + endif; + return $ret; +} + +// Convert string to interger or float number +function convertStrToNumber($str) { + $pos = strpos($str, "."); + // The !== operator can also be used. Using != would not work as expected + // because if the position of '.' is 0. The statement (0 != false) evaluates + // to false. + if ($pos !== false) { + $number = (float) $str; + } else { + $number = (int) $str; + } + return $number; +} + +// Check if a string is DateTime +function isDateTime($str) { + if (DateTime::createFromFormat('Y-m-d H:i:s', $str) !== FALSE || + DateTime::createFromFormat('Y-m-d H:i:s.u', $str) !== FALSE || + DateTime::createFromFormat('Y-m-d\TH:i:s.u', $str) !== FALSE || + DateTime::createFromFormat('Y-m-d\TH:i:s.uZ', $str) !== FALSE) { + return true; + } else { + return false; + } +} + +// Convert Datetime string to DateTime object +function convertStrToDateTime($str) { + $UTCTime = new DateTimeZone("UTC"); + $dateTimeObj = new DateTime($str, $UTCTime); + return $dateTimeObj; +} + +// Convert string to blob data +function convertStrToBlob($str) { + $blobData = ""; + if (!is_null($str)) { + $strRep = str_replace(["[", "]"], ["", ""], $str); + $byteDataArray = explode(";", $strRep); + foreach ($byteDataArray as $value) { + $mBlob = pack('C*', $value); + $blobData.= $mBlob; + } + return $blobData; +} +} +// Convert data test from string type in CSV to other data type +function convertData($str) { + if ($str == 'NULL'): + $ret = NULL; + elseif ($str == ""): + $ret = ""; + elseif (is_numeric($str)): + $ret = convertStrToNumber($str); + elseif (isDateTime($str)): + $ret = convertStrToDateTime($str); + elseif ($str == "True" || $str == "False" || $str == "TRUE" || + $str == "FALSE" ||$str == "true" || $str == "false"): + $ret = convertStrToBool($str); + elseif (strpos($str, "[") !== false && strpos($str, "]") !== false): + $ret = convertStrToBlob($str); + elseif ($str == "GS_TIME_UNIT_YEAR"): + $ret = \TimeUnit::YEAR; + elseif ($str == "GS_TIME_UNIT_MONTH"): + $ret = \TimeUnit::MONTH; + elseif ($str == "GS_TIME_UNIT_DAY"): + $ret = \TimeUnit::DAY; + elseif ($str == "GS_TIME_UNIT_HOUR"): + $ret = \TimeUnit::HOUR; + elseif ($str == "GS_TIME_UNIT_MINUTE"): + $ret = \TimeUnit::MINUTE; + elseif ($str == "GS_TIME_UNIT_SECOND"): + $ret = \TimeUnit::SECOND; + elseif ($str == "GS_TIME_UNIT_MILLISECOND"): + $ret = \TimeUnit::MILLISECOND; + elseif ($str == "GS_CONTAINER_COLLECTION"): + $ret = \ContainerType::COLLECTION; + elseif ($str =="GS_CONTAINER_TIME_SERIES"): + $ret = \ContainerType::TIME_SERIES; + elseif ($str == "GS_INDEX_DEFAULT"): + $ret = \IndexType::DEFAULT_TYPE; + elseif ($str == "GS_INDEX_TREE"): + $ret = \IndexType::TREE; + elseif ($str == "GS_INDEX_FLAG_HASH"): + $ret = \IndexType::HASH; + else: + $ret = $str; + endif; + return $ret; +} + +function convertExtraData($str) { + if ($str == '16KB_string'): + $ret = file_get_contents('test/resource/longSizeString.txt'); + elseif ($str == '31KB_string'): + $ret = file_get_contents('test/resource/31k.txt'); + elseif ($str == '128KB_string'): + $ret = file_get_contents('test/resource/31k.txt'); + elseif ($str == 'exceed_16KB_string' || $str == 'exceed_31KB_string'): + $ret = file_get_contents('test/resource/exceedSizeString.txt'); + elseif ($str == 'exceed_128KB_string'): + $ret = file_get_contents('test/resource/exceed128KB.txt'); + else: + $ret = $str; + endif; + return $ret; +} + +function convertStrToRow($str) { + $mArray = explode(":", $str); + $rowName = $mArray[0]; + switch ($mArray[1]) { + case "GS_TYPE_STRING": + $rowType = \Type::STRING; + break; + case "GS_TYPE_BOOL": + $rowType = \Type::BOOL; + break; + case "GS_TYPE_BYTE": + $rowType = \Type::BYTE; + break; + case "GS_TYPE_SHORT": + $rowType = \Type::SHORT; + break; + case "GS_TYPE_INTEGER": + $rowType = \Type::INTEGER; + break; + case "GS_TYPE_LONG": + $rowType = \Type::LONG; + break; + case "GS_TYPE_FLOAT": + $rowType = \Type::FLOAT; + break; + case "GS_TYPE_DOUBLE": + $rowType = \Type::DOUBLE; + break; + case "GS_TYPE_TIMESTAMP": + $rowType = \Type::TIMESTAMP; + break; + case "GS_TYPE_BLOB": + $rowType = \Type::BLOB; + break; + } + return [$rowName, $rowType]; +} + +function preSetupContainer($gridstore, $containerName, $containerType) { + $propList = [["A_0", \Type::STRING], + ["A9", \Type::BOOL], + ["Z0", \Type::BYTE], + ["A0Z", \Type::SHORT], + ["Z_9", \Type::INTEGER], + ["A0", \Type::LONG], + ["a_9", \Type::TIMESTAMP], + ["Z", \Type::FLOAT], + ["za", \Type::DOUBLE], + ["az", \Type::BLOB]]; + tearDown($gridstore, $containerName); + if (is_array($containerName)) { + $containerCount = sizeof($containerName) - 1; + for ($i = 0; $i < $containerCount; $i++) { + $rowKey = $propList; + if ($containerType[$i] != "timestamp_timeseries") { + $containerTypeTmp[$i] = "\$containerTypeConvert = \Type::"; + $containerTypeTmp[$i].= strtoupper($containerType[$i]); + $containerTypeTmp[$i].= ";"; + eval($containerTypeTmp[$i]); + array_unshift($rowKey, ["A00", $containerTypeConvert]); + $containerInfo = new \ContainerInfo(["name" => $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); + } +} +?>