<commit_before># EXASockets
Interface to the EXASOL DB via JSON over Websockets protocol.

## Status

Work in progress... 

### Functionality: 

What basically works:

- Connect & Disconnect
- Sending a query
- Fetching a result set

### Performance:

The library is entierly C++ with a custom implemnetation of the websocket protocol and relying on rapidJSON, 
which is pretty fast and works well for huge JSONs. Promising so far...

Tested with EXASOL 6 Beta 1: Measured is sending a query and fetching a 
result set (which needs to be done separately using 'fetch()' if the result set is
 1000 rows or greater). Testing with the flights data set with an EXASolo on the same machine, 
 a simple query (e.g. metadata request) returns within 10-20 ms; an uncompressed fetch of 10k rows / 970 KB
  RAW data took me ~ 900 - 1300 ms. Fetching 100k rows / 9.8 MB RAW data typically took about 8.5 sec.

### Stability:

Regarding the interface, nothing is final.
There is certainly still some error-handling left to do. I appreciate any bug report!

### Memory:

std::shared_pointers were used for some parts, but memory management is probably still messy and will see improvement
 on occasion.

## Example code:

```C++

#include <iostream>
#include "exasockets/exasockets.h"

int main() {
  
    exasockets_connection *exaws;
    
    // connecting to EXASOL (IP, port, client descriptor, username, password, password length, autocommit)
    try {
        exaws = new exasockets_connection("192.168.137.10", 8563, "MBO", "sys", "exasol", 6, false);
    } catch (const char *msg) {
        std::cerr << msg << std::endl;
    }
    
    // returning the EXASOL session ID
    std::cout << exaws->session_id() << std::endl;

    // sending a query to EXASOL
    int h = exaws->exec_sql("select * from pub1092.flights limit 100000");
    
    // if exec_sql() returns a handle, use it to fetch the result set
    // results sets < 1000 rows are immediately fetched by exec_sql()
    // fetch(handle, row offset / first row to fetch, Bytes to fetch - here 30 MB)
    if (h > 0) { // a result set handle received (result set >= 1000 rows))
        std::cout << "rows fetched: " << exaws->fetch(h, 0, (10485760 * 3)) << std::endl;
    }

    // accessing the data 
    // data is a rapidJSON Value object. For details see the rapidJSON documentation (link below).
    std::cout << "First data field: " << exaws->data[0][0].GetInt() << std::endl; // first col, first row

    // a clean disconnect is done on destruction of the connection object.
    delete (exaws);
    
    return 0;
}

```


## Build

These libs are intended to work on Windows and POSIX systems. For building the linker needs:

- the websockets libs, see https://github.com/marcelboldt/websockets/
- RapidJSON 1.10, see https://github.com/miloyip/rapidjson/
- OpenSSL (tested with v1.1.0b 26 Sep 2016), see https://www.openssl.org/

No other non C++ 11 standard libraries (e.g. boost) are needed.


## Documentation

Also in progress...

See https://marcelboldt.github.io/EXASockets/

A tutorial for rapidJSON: http://rapidjson.org/md_doc_tutorial.html

## See also

https://github.com/EXASOL/websocket-api/blob/master/WebsocketAPI.md

https://www.exasol.com/portal<commit_msg>updated readme for exaResultSet<commit_after># EXASockets
Interface to the EXASOL DB via JSON over Websockets protocol.

## Status

Work in progress... but probably already useful.

### Functionality: 

What basically works:

- Connect & Disconnect
- Sending a query
- Fetching a result set

The result set is stored in an exaResultSet that stores data column-wise in C++ std::vectors 
of an appropriate data type, depending on the column data type. However, the data type mapping is not yet perfect and
may be improved in the future.

### Performance:

The library is entierly C++ with a custom implementation of the websocket protocol and relying on rapidJSON, 
which is pretty fast and works well for huge JSONs. Promising so far...

Tested with EXASOL 6 Beta 1: Measured is sending a query and fetching a 
result set (which needs to be done separately using 'fetch()' if the result set is
 1000 rows or greater). Testing with the flights data set with an EXASolo on the same machine, 
 a simple query (e.g. metadata request) returns within 10-20 ms; an uncompressed fetch of 10k rows / 970 KB
  RAW data took me ~ 900 - 1300 ms. Fetching 100k rows / 9.8 MB RAW data typically took about 8.5 sec.

### Stability:

Regarding the interface, nothing is final.
There is certainly still some error-handling left to do. I appreciate any bug report!

### Memory:

std::shared_pointers were used for some parts, but memory management is probably still messy and will see improvement
 on occasion.

## Use:

```C++

#include <iostream>
#include "exasockets/exasockets.h"

int main() {
  
    exasockets_connection *exaws;
    
    // connecting to EXASOL (IP, port, client descriptor, username, password, password length, autocommit)
    try {
        exaws = new exasockets_connection("192.168.137.10", 8563, "MBO", "sys", "exasol", 6, false);
    } catch (const char *msg) {
        std::cerr << msg << std::endl;
    }
    
    // returning the EXASOL session ID
    std::cout << exaws->session_id() << std::endl;

    // sending a query to EXASOL and receiving a result set
    exaResultSetHandler *rs = exaws->exec_sql("select * from test.flights;");
    

    // accessing the data 
    // data is stored in an exaResultSet. Values can be addressed two-dimensionally [column][row];
    // returned is a void pointer that may be casted into the appropriate C datatype (see section "Data type mapping").
    
    int col = 0; int row = 1; // first column, second row
   
    std::cout << "Column name: " << (*rs)[col].getName() << std::endl;
    std::cout << "Column type: " << exasockets_connection::ExaDatatypeToString((*rs)[col].type()) << std::endl;
    std::cout << "Value: " << *static_cast<std::string *>((*rs)[col][row]) << std::endl;

    // a clean disconnect is done on destruction of the connection object.
    delete (exaws);
    
    return 0;
}

```

### Data type mapping

| EXASOL data type 	| client data type (C++ type) 	|
|------------------	|-----------------------------	|
| BOOLEAN          	| bool                        	|
| CHAR             	| std::string                 	|
| DATE             	| std::string                 	|
| DECIMAL          	| std::string                 	|
| DOUBLE           	| double                      	|
| GEOMETRY         	| not yet implemented         	|
| INTERVAL_DS      	| not yet implemented         	|
| INTERVAL_YM      	| not yet implemented         	|
| TIMESTAMP        	| std::string                 	|
| VARCHAR          	| std::string                 	|


## Build

These libs are intended to work on Windows and POSIX systems. For building the linker needs:

- the websockets libs, see https://github.com/marcelboldt/websockets/
- RapidJSON 1.10, see https://github.com/miloyip/rapidjson/
- OpenSSL (tested with v1.1.0b 26 Sep 2016), see https://www.openssl.org/

No other non C++ standard libraries (e.g. boost) are needed.


## Documentation

Also in progress...

See https://marcelboldt.github.io/EXASockets/


## See also

https://github.com/EXASOL/websocket-api/blob/master/WebsocketAPI.md

https://www.exasol.com/portal
{'fraction_non_alphanumeric': 0.1099290780141844, 'fraction_numerical': 0.020867430441898527, 'mean_word_length': 2.877842411422528, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 14, 'https://': 12, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '585087', 'n_tokens_mistral': 2357, 'n_tokens_neox': 2157, 'n_words': 861}