1# Handling Results
2
3The [`CassResult`](http://datastax.github.io/cpp-driver/api/struct.CassResult/) object
4is typically returned for `SELECT` statements. For mutations (`INSERT`, `UPDATE`,
5and `DELETE`) only a status code will be present and can be accessed using
6`cass_future_error_code()`. However, when using lightweight transactions a
7result object will be available to check the status of the transaction. The
8result object is obtained from executed statements' future object.
9
10**Important**: Rows, column values, collections, decimals, strings, and bytes
11objects are all invalidated when the result object is freed. All of these
12objects point to memory held by the result. This allows the driver to avoid
13unnecessarily copying data.
14
15```c
16void process_result(CassFuture* future) {
17  const CassResult* result = cass_future_get_result(future);
18
19  /* Process result */
20
21  cass_result_free(result);
22}
23```
24
25*Note*: The result object is immutable and can be accessed by multiple threads concurrently.
26
27## Rows and Column Values
28
29The result object represents a collection of rows. The first row, if present,
30can be obtained using `cass_result_first_row()`. Multiple rows are accessed
31using a [`CassIterator`](http://datastax.github.io/cpp-driver/api/struct.CassIterator/)
32object. After a row has been retrieved, the column value(s) can be accessed from
33a row by either index or by name. The iterator object can also be used with
34enumerated column values.
35
36```c
37void process_first_row(const CassResult* result) {
38  const CassRow* row = cass_result_first_row(result);
39
40  /* Get the first column value using the index */
41  const CassValue* column1 = cass_row_get_column(row, 0);
42}
43```
44
45```c
46void process_first_row_by_name(const CassResult* result) {
47  const CassRow* row = cass_result_first_row(result);
48
49  /* Get the value of the column named "column1" */
50  const CassValue* column1 = cass_row_get_column_by_name(row, "column1");
51}
52```
53
54Once the [`CassValue`](http://datastax.github.io/cpp-driver/api/struct.CassValue/)
55has been obtained from the column, the actual value can be retrieved and
56assigned into the proper datatype.
57
58```c
59void get_values_from_row(const CassRow* row) {
60  cass_int32_t int_value;
61  const CassValue* column1 = cass_row_get_column(row, 0);
62  cass_value_get_int32(column1, &int_value);
63
64  cass_int64_t timestamp_value;
65  const CassValue* column2 = cass_row_get_column(row, 1);
66  cass_value_get_int64(column2, &timestamp_value);
67
68  const char* string_value;
69  size_t string_value_length;
70  const CassValue* column3 = cass_row_get_column(row, 2);
71  cass_value_get_string(column3, &string_value, &string_value_length);
72}
73```
74
75## Iterators
76
77Iterators can be used to iterate over the rows in a result, the columns in a
78row, or the values in a collection.
79
80**Important**: `cass_iterator_next()` invalidates values retrieved by the
81previous iteration.
82
83```c
84void iterate_over_rows(CassFuture* future) {
85  const CassResult* result = cass_future_get_result(future);
86
87  CassIterator* iterator = cass_iterator_from_result(result);
88
89  while (cass_iterator_next(iterator)) {
90    const CassRow* row = cass_iterator_get_row(iterator);
91    /* Retreive and use values from the row */
92  }
93
94  cass_iterator_free(iterator);
95
96  cass_result_free(result);
97}
98```
99
100All iterators use the same pattern, but will have different iterator creation
101and retrieval functions. Iterating over a map collection is slightly different
102because it has two values per entry, but utilizes the same basic pattern.
103
104```c
105/* Execute SELECT query where a map colleciton is returned */
106
107void iterator_over_map_value(CassFuture* future) {
108  const CassResult* result = cass_future_get_result(future);
109
110  const CassRow* row = cass_result_first_row(result);
111
112  const CassValue* map = cass_row_get_column(row, 0);
113
114  CassIterator* iterator = cass_iterator_from_map(map);
115
116  while (cass_iterator_next(iterator)) {
117    /* A seperate call is used to get the key and the value */
118    const CassValue* key = cass_iterator_get_map_key(iterator);
119    const CassValue* value = cass_iterator_get_map_value(iterator);
120
121    /* Use key/value pair */
122  }
123
124  cass_iterator_free(iterator);
125
126  cass_result_free(result);
127}
128```
129
130## Paging
131
132When communicating with Cassandra 2.0 or later, large result sets can be divided
133into multiple pages automatically. The
134[`CassResult`](http://datastax.github.io/cpp-driver/api/struct.CassResult/) object
135keeps track of the pagination state for the sequence of paging queries. When
136paging through the result set, the result object is checked to see if more pages
137exist where it is then attached to the statement before re-executing the query
138to get the next page.
139
140```c
141void page_results(CassSession* session) {
142
143  CassStatement* statement = cass_statement_new("SELECT * FROM table1", 0);
144
145  /* Return a 100 rows every time this statement is executed */
146  cass_statement_set_paging_size(statement, 100);
147
148  cass_bool_t has_more_pages = cass_true;
149
150  while (has_more_pages) {
151    CassFuture* query_future = cass_session_execute(session, statement);
152
153    const CassResult* result = cass_future_get_result(query_future);
154
155    if (result == NULL) {
156
157      /* Handle error */
158
159      cass_future_free(query_future);
160      break;
161    }
162
163    /* Get values from result... */
164
165    /* Check to see if there are more pages remaining for this result */
166    has_more_pages = cass_result_has_more_pages(result);
167
168    if (has_more_pages) {
169      /* If there are more pages we need to set the position for the next execute */
170      cass_statement_set_paging_state(statement, result);
171    }
172
173    cass_future_free(query_future);
174    cass_result_free(result);
175  }
176
177  cass_statement_free(statement);
178}
179```
180
181The [`cass_statement_set_paging_state()`] function abstracts the actual paging
182state token away from the application. The raw paging state token can be
183accessed using [`cass_result_paging_state()`] and added to a statement using
184[`cass_statement_set_paging_state_token()`].
185
186**Warning**: The paging state token should not be exposed to or come from
187untrusted environments. That paging state could be spoofed and potentially used
188to gain access to other data.
189
190[`cass_statement_set_paging_state()`]: http://datastax.github.io/cpp-driver/api/struct.CassStatement/#cass-statement-set-paging-state
191[`cass_result_paging_state()`]: http://datastax.github.io/cpp-driver/api/struct.CassResult/#cass-result-paging-state
192[`cass_statement_set_paging_state_token()`]: http://datastax.github.io/cpp-driver/api/struct.CassStatement/#cass-statement-set-paging-state-token
193