Connector/C++ 8.0 X DevAPI Reference {#devapi_ref}
====================================

Connector/C++ 8.0 implements the X DevAPI, as described in
the [X DevAPI User Guide]
(http://dev.mysql.com/doc/x-devapi-userguide/en/index.html).
The X DevAPI allows one to work with MySQL Servers implementing a document store
via the X Plugin. One can also execute plain SQL queries using this API.

To get started, check out some of the main X DevAPI classes:

- To access data first create a @link mysqlx::abi2::r0::Session `Session`@endlink
object. Keep in mind that @link mysqlx::abi2::r0::Session `Session`@endlink is
not thread safe!

- To manipulate data stored in a document collection or a table, create
  a @link mysqlx::abi2::r0::Collection `Collection`@endlink or a @link mysqlx::abi2::r0::Table
  `Table`@endlink object using methods `getCollection()` or `getTable()` of
  a @link mysqlx::abi2::r0::Schema `Schema`@endlink object obtained from the session.

- Queries and other statements are created using methods of the `Collection`
  or `Table` class, such as `find()`. They are executed with method `execute()`.

- Results of a query are examined using @link mysqlx::abi2::r0::DocResult
 `DocResult`@endlink or @link mysqlx::abi2::r0::RowResult `RowResult`@endlink instances
  returned from `execute()` method. Method `fetchOne()` fetches the next item
  (a document or a row) from the result until there are no more items left.
  Method `fetchAll()` can fetch all items at once and store them in an STL
  container.

- Documents and rows from query results are represented by @link mysqlx::abi2::r0::DbDoc
  `DbDoc`@endlink and @link mysqlx::abi2::r0::Row `Row`@endlink instances, respectively.

A more complete example of code that access MySQL Document Store using
the X DevAPI is presented below. See also the [list of X DevAPI classes]
(@ref devapi).


### Sample code which uses Connector/C++ with X DevAPI ###

The following Connector/C++ application connects to a MySQL Server with
X Plugin, creates a document collection, adds a few documents to it, queries
the collection and displays the result. The sample code can be found in file
`testapp/devapi_test.cc` in the source distribution of Connector/C++ 8.0.
See @ref usage for instructions on how to build the sample code.

@dontinclude devapi_test.cc

Code which uses X DevAPI should include the `mysql_devapi.h` header. The API
is declared within the `mysqlx` namespace:

@skip #include <mysqlx/xdevapi.h>
@until using namespace

To create an @link mysqlx::abi2::r0::Session `Session` @endlink object, specify DNS name
of a MySQL Server, the port on which the plugin listens (default port is 33060)
and user credentials:

@skipline main
@until Session

Another way of specifying session parameters is by means of a `mysqlx`
connection string like `"mysqlx://mike:s3cr3t!@localhost:13009"`. Once created,
the session is ready to be used. If the session can not be established,
the `Session` constructor throws an error.

To manipulate documents in a collection, create a @link mysqlx::abi2::r0::Collection
`Collection`@endlink object, first asking session for that collection's
@link mysqlx::abi2::r0::Schema `Schema`@endlink:

@skipline cout
@until Collection

The `true` parameter to @link mysqlx::abi2::r0::Schema::createCollection
`createCollection()`@endlink method specifies that collection should be re-used
if it already exists. Without this parameter an attempt to create an already
existing collection produces an error. It is also possible to create
a `Collection` object directly, without creating the `Schema` instance:
~~~~~~~~
Collection coll = sess.getSchema("test").getCollection("c1",true)
~~~~~~~~

Before adding documents to the collection, all the existing documents are
removed first using the @link mysqlx::abi2::r0::Collection::remove `Collection::remove()`@endlink
method (expression "true" selects all documents in the collection):

@skipline remove("true")

Note that the `remove()` method returns an operation that must
be explicitly executed to take effect. When executed, operation returns
a result (ignored here; the results are used later).

To insert documents use the @link mysqlx::abi2::r0::Collection::add
`Collection::add()`@endlink method. Documents are described by JSON strings
using the same syntax as MySQL Server. Note that double quotes are required
around field names and they must be escaped inside C strings, unless the new
C++11 `R"(...)"` string literal syntax is used as in the example below:

@skipline {
@until cout
@until cout
@until cout
@until cout
@until }

Result of the `add()` operation is stored in the `add` variable to be able
to read identifiers of the documents that were added. These identifiers are
generated by the connector, unless an added document contains an `"_id"` field
which specifies its identifier. Note how internal code block is used to delete
the result when it is no longer needed.

@note It is possible to chain several `add()` calls as follows:
  `coll.add(doc1).add(doc2)...add(docN).execute()`. It is also possible to pass
  several documents to a single `add()` call:
  `coll.add(doc1, ..., docN).execute()`. Another option is to pass
  to `Collection::add()` an STL container with several documents.

To query documents of a collection use the @link mysqlx::abi2::r0::Collection::find
`Collection::find()`@endlink method:

@skipline coll.find(

The result of the `find()` operation is stored in a variable of type
@link mysqlx::abi2::r0::DocResult `DocResult`@endlink which gives access to the returned
documents that satisfy the selection criteria. These documents can be fetched
one by one using the @link mysqlx::abi2::r0::DocResult::fetchOne
`DocResult::fetchOne()`@endlink method, until it returns a null document that
signals end of the sequence:

@skipline fetchOne()
@until cout

Given a @link mysqlx::abi2::r0::DbDoc `DbDoc`@endlink object it is possible to iterate
over its fields as follows:

@skipline for
@until }

Note how the @link mysqlx::abi2::r0::DbDoc::operator[] `operator[]`@endlink is used
to access values of document fields:

@skipline name
@until cout

The value of a field is automatically converted to a corresponding C++ type.
If the C++ type does not match the type of the field value, conversion error
is thrown.

Fields which are sub-documents can be converted to the `DbDoc` type. The
following code demonstrates how to process a `"date"` field which is
a sub-document. Note how methods @link mysqlx::abi2::r0::DbDoc::hasField
`DbDoc::hasField()`@endlink and @link mysqlx::abi2::r0::DbDoc::fieldType
`DbDoc::fieldType()`@endlink are used to examine existence and type of a field
within a document.

@skipline if
@until }
@until }

In case of arrays, currently no conversion to C++ types is defined. However,
individual elements of an array value can be accessed using `operator[]` or
they can be iterated using range for loop.

@skipline if
@until }
@until }

Any errors thrown by Connector/C++ derive from the `mysqlx::Error` type and can
be processed as follows:

@skipline catch
@until }


The complete code of the example is presented below:

@include devapi_test.cc

A sample output produced by this code:

~~~~~~~
Creating session on localhost, port 13009 ...
Session accepted, creating collection...
Inserting documents...
- added doc with id: AA71B4BF6B72E511BD76001E684A06F0
- added doc with id: 2885B4BF6B72E511BD76001E684A06F0
- added doc with id: 3492B4BF6B72E511BD76001E684A06F0
- added doc with id: myuuid-1
Fetching documents...

doc#0: {"_id": "AEFD9C44EB77E5116134001E684A06F0", "age": 3, "date": {"day": 20, "month": "Apr"}, "name": "baz"}
 field `_id`: AEFD9C44EB77E5116134001E684A06F0
 field `age`: 3
 field `date`: <document>
 field `name`: baz
 name: baz
- date field
  date `day`: 20
  date `month`: Apr
  month: Apr
  day: 20

doc#1: {"_id": "A0ABC08DAABAD1110C120800273BD115", "age": 2, "name": "bar", "toys": ["car", "ball"]}
 field `_id`: A0ABC08DAABAD1110C120800273BD115
 field `age`: 2
 field `name`: bar
 field `toys`: <array with 2 element(s)>
 name: bar
- toys:
  car
  ball

Done!
~~~~~~~


<!--
  Copyright (c) 2015, 2020, Oracle and/or its affiliates.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License, version 2.0, as
  published by the Free Software Foundation.

  This program is also distributed with certain software (including
  but not limited to OpenSSL) that is licensed under separate terms,
  as designated in a particular file or component or in included license
  documentation.  The authors of MySQL hereby grant you an
  additional permission to link the program and your derivative works
  with the separately licensed software that they have included with
  MySQL.

  Without limiting anything contained in the foregoing, this file,
  which is part of MySQL Connector/C++, is also subject to the
  Universal FOSS Exception, version 1.0, a copy of which can be found at
  http://oss.oracle.com/licenses/universal-foss-exception.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License, version 2.0, for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
-->
