<commit_before>============
Client Usage
============

.. rubric:: Table of Contents

.. contents::
   :local:

Connect to a Database
=====================

Before we can start we have to import the client::

    >>> from crate import client

The client provides a ``connect()`` function which is used to establish a
connection, the first argument is the url of the server to connect to::

    >>> connection = client.connect(crate_host)

CrateDB is a clustered database providing high availability through
replication. In order for clients to make use of this property it is
recommended to specify all hosts of the cluster. This way if a server does not
respond, the request is automatically routed to the next server::

    >>> invalid_host = 'http://not_responding_host:4200'
    >>> connection = client.connect([invalid_host, crate_host])

If no ``servers`` are given, the default one ``http://127.0.0.1:4200`` is used::

    >>> connection = client.connect()
    >>> connection.client._active_servers
    ['http://127.0.0.1:4200']


If the option ``error_trace`` is set to ``True``, the client will print a whole traceback
if a server error occurs::

    >>> connection = client.connect([crate_host], error_trace=True)

It's possible to define a default timeout value in seconds for all servers
using the optional parameter ``timeout``::

    >>> connection = client.connect([crate_host, invalid_host], timeout=5)

Authentication
--------------

Users that are trusted as by definition of the ``auth.host_based.config``
setting do not need a password, but only require the ``username`` argument to
connect::

    >>> connection = client.connect([crate_host],
    ...                             username='trusted_me')

To connect to CrateDB with as a user that requires password authentication, you
also need to provide ``password`` as argument for the ``connect()`` call::

    >>> connection = client.connect([crate_host],
    ...                             username='me',
    ...                             password='<PASSWORD>')

Inserting Data
==============

.. hide::

   Use user "crate" for rest of the tests::

    >>> connection = client.connect([crate_host], timeout=2)

Before executing any statement a cursor has to be opened to perform
database operations::

    >>> cursor = connection.cursor()
    >>> cursor.execute("""INSERT INTO locations
    ... (name, date, kind, position) VALUES (?, ?, ?, ?)""",
    ...                ('Einstein Cross', '2007-03-11', 'Quasar', 7))

To bulk insert data you can use the ``executemany`` function::

    >>> cursor.executemany("""INSERT INTO locations
    ... (name, date, kind, position) VALUES (?, ?, ?, ?)""",
    ...                [('Cloverleaf', '2007-03-11', 'Quasar', 7),
    ...                 ('Old Faithful', '2007-03-11', 'Quasar', 7)])
    [{u'rowcount': 1}, {u'rowcount': 1}]

``executemany`` returns a list of results for every parameter. Each result
contains a rowcount. If an error occures the rowcount is -2 and the result
may contain an ``error_message`` depending on the error.

.. Hidden: refresh locations

    >>> cursor.execute("REFRESH TABLE locations")

Selecting Data
==============

To perform the select operation simply execute the statement on the
open cursor::

    >>> cursor.execute("SELECT name FROM locations where name = ?", ('Algol',))

To retrieve a row we can use one of the cursor's fetch functions (described below).

fetchone()
----------

``fetchone()`` with each call returns the next row from the results::

    >>> result = cursor.fetchone()
    >>> pprint(result)
    [u'Algol']

If no more data is available, an empty result is returned::

    >>> while cursor.fetchone():
    ...     pass
    >>> cursor.fetchone()

fetchmany()
-----------

``fetch_many()`` returns a list of all remaining rows, containing no more than the specified
size of rows::

    >>> cursor.execute("SELECT name FROM locations order by name")
    >>> result = cursor.fetchmany(2)
    >>> pprint(result)
    [[u'Aldebaran'], [u'Algol']]

If a size is not given, the cursor's arraysize, which defaults to '1', determines the number
of rows to be fetched::

    >>> cursor.fetchmany()
    [[u'Allosimanius Syneca']]

It's also possible to change the cursors arraysize to an other value::

    >>> cursor.arraysize = 3
    >>> cursor.fetchmany()
    [[u'Alpha Centauri'], [u'Altair'], [u'Argabuthon']]

fetchall()
----------

``fetchall()`` returns a list of all remaining rows::

    >>> cursor.execute("SELECT name FROM locations order by name")
    >>> result = cursor.fetchall()
    >>> pprint(result)
    [['Aldebaran'],
     ['Algol'],
     ['Allosimanius Syneca'],
     ['Alpha Centauri'],
     ['Altair'],
     ['Argabuthon'],
     ['Arkintoofle Minor'],
     ['Bartledan'],
     ['Cloverleaf'],
     ['Creameries'],
     ['Double Quasar'],
     ['Einstein Cross'],
     ['Folfanga'],
     ['Galactic Sector QQ7 Active J Gamma'],
     ['Galaxy'],
     ['North West Ripple'],<commit_msg>Fix test failures<commit_after>============
Client Usage
============

.. rubric:: Table of Contents

.. contents::
   :local:

Connect to a Database
=====================

Before we can start we have to import the client::

    >>> from crate import client

The client provides a ``connect()`` function which is used to establish a
connection, the first argument is the url of the server to connect to::

    >>> connection = client.connect(crate_host)

CrateDB is a clustered database providing high availability through
replication. In order for clients to make use of this property it is
recommended to specify all hosts of the cluster. This way if a server does not
respond, the request is automatically routed to the next server::

    >>> invalid_host = 'http://not_responding_host:4200'
    >>> connection = client.connect([invalid_host, crate_host])

If no ``servers`` are given, the default one ``http://127.0.0.1:4200`` is used::

    >>> connection = client.connect()
    >>> connection.client._active_servers
    ['http://127.0.0.1:4200']


If the option ``error_trace`` is set to ``True``, the client will print a whole traceback
if a server error occurs::

    >>> connection = client.connect([crate_host], error_trace=True)

It's possible to define a default timeout value in seconds for all servers
using the optional parameter ``timeout``::

    >>> connection = client.connect([crate_host, invalid_host], timeout=5)

Authentication
--------------

Users that are trusted as by definition of the ``auth.host_based.config``
setting do not need a password, but only require the ``username`` argument to
connect::

    >>> connection = client.connect([crate_host],
    ...                             username='trusted_me')

To connect to CrateDB with as a user that requires password authentication, you
also need to provide ``password`` as argument for the ``connect()`` call::

    >>> connection = client.connect([crate_host],
    ...                             username='me',
    ...                             password='<PASSWORD>')

Inserting Data
==============

.. hide::

   Use user "crate" for rest of the tests::

    >>> connection = client.connect([crate_host], timeout=2)

Before executing any statement a cursor has to be opened to perform
database operations::

    >>> cursor = connection.cursor()
    >>> cursor.execute("""INSERT INTO locations
    ... (name, date, kind, position) VALUES (?, ?, ?, ?)""",
    ...                ('Einstein Cross', '2007-03-11', 'Quasar', 7))

To bulk insert data you can use the ``executemany`` function::

    >>> cursor.executemany("""INSERT INTO locations
    ... (name, date, kind, position) VALUES (?, ?, ?, ?)""",
    ...                [('Cloverleaf', '2007-03-11', 'Quasar', 7),
    ...                 ('Old Faithful', '2007-03-11', 'Quasar', 7)])
    [{u'rowcount': 1}, {u'rowcount': 1}]

``executemany`` returns a list of results for every parameter. Each result
contains a rowcount. If an error occures the rowcount is -2 and the result
may contain an ``error_message`` depending on the error.

.. Hidden: refresh locations

    >>> cursor.execute("REFRESH TABLE locations")

Selecting Data
==============

To perform the select operation simply execute the statement on the
open cursor::

    >>> cursor.execute("SELECT name FROM locations where name = ?", ('Algol',))

To retrieve a row we can use one of the cursor's fetch functions (described below).

fetchone()
----------

``fetchone()`` with each call returns the next row from the results::

    >>> result = cursor.fetchone()
    >>> pprint(result)
    [u'Algol']

If no more data is available, an empty result is returned::

    >>> while cursor.fetchone():
    ...     pass
    >>> cursor.fetchone()

fetchmany()
-----------

``fetch_many()`` returns a list of all remaining rows, containing no more than the specified
size of rows::

    >>> cursor.execute("SELECT name FROM locations order by name")
    >>> result = cursor.fetchmany(2)
    >>> pprint(result)
    [[u'Aldebaran'], [u'Algol']]

If a size is not given, the cursor's arraysize, which defaults to '1', determines the number
of rows to be fetched::

    >>> cursor.fetchmany()
    [[u'Allosimanius Syneca']]

It's also possible to change the cursors arraysize to an other value::

    >>> cursor.arraysize = 3
    >>> cursor.fetchmany()
    [[u'Alpha Centauri'], [u'Altair'], [u'Argabuthon']]

fetchall()
----------

``fetchall()`` returns a list of all remaining rows::

    >>> cursor.execute("SELECT name FROM locations order by name")
    >>> result = cursor.fetchall()
    >>> pprint(result)
    [['Aldebaran'],
     ['Algol'],
     ['Allosimanius Syneca'],
     ['Alpha Centauri'],
     ['Altair'],
     ['Argabuthon'],
     ['Arkintoofle Minor'],
     ['Bartledan'],
     ['Cloverleaf'],
     ['Einstein Cross'],
     ['Folfanga'],
     ['Galactic Sector QQ7 Active J Gamma'],
     ['Galaxy'],
     ['North West Ripple'],
{'fraction_non_alphanumeric': 0.15575506910118025, 'fraction_numerical': 0.012105316251387067, 'mean_word_length': 3.240376390076989, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1948277', 'n_tokens_mistral': 2890, 'n_tokens_neox': 2729, 'n_words': 1044}