Beispiel #1
0
    def configure(self,
                  oversized_ops=None,
                  log_size=None,
                  historic_logs=None,
                  reserve_logs=None,
                  throttle_wait=None,
                  throttle_limit=None):
        """Configure the parameters of the write-ahead log.

        :param oversized_ops: execute and store ops bigger than a log file
        :type oversized_ops: bool
        :param log_size: the size of each write-ahead log file
        :type log_size: int
        :param historic_logs: the number of historic log files to keep
        :type historic_logs: int
        :param reserve_logs: the number of reserve log files to allocate
        :type reserve_logs: int
        :param throttle_wait: wait time before aborting when throttled (in ms)
        :type throttle_wait: int
        :param throttle_limit: number of pending gc ops before write-throttling
        :type throttle_limit: int
        :returns: the new configuration of the write-ahead log
        :rtype: dict
        :raises arango.exceptions.WALPropertiesError: if the WAL properties
            cannot be modified
        """
        data = {}
        if oversized_ops is not None:
            data['allowOversizeEntries'] = oversized_ops
        if log_size is not None:
            data['logfileSize'] = log_size
        if historic_logs is not None:
            data['historicLogfiles'] = historic_logs
        if reserve_logs is not None:
            data['reserveLogfiles'] = reserve_logs
        if throttle_wait is not None:
            data['throttleWait'] = throttle_wait
        if throttle_limit is not None:
            data['throttleWhenPending'] = throttle_limit

        request = Request(method='put',
                          endpoint='/_admin/wal/properties',
                          data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise WALConfigureError(res)
            return {
                'oversized_ops': res.body.get('allowOversizeEntries'),
                'log_size': res.body.get('logfileSize'),
                'historic_logs': res.body.get('historicLogfiles'),
                'reserve_logs': res.body.get('reserveLogfiles'),
                'sync_interval': res.body.get('syncInterval'),
                'throttle_wait': res.body.get('throttleWait'),
                'throttle_limit': res.body.get('throttleWhenPending')
            }

        response = self.handle_request(request, handler)

        return response
Beispiel #2
0
    def properties(self):
        """Return the configuration of the write-ahead log.

        :returns: the configuration of the write-ahead log
        :rtype: dict
        :raises arango.exceptions.WALPropertiesError: if the WAL properties
            cannot be retrieved from the server
        """
        request = Request(method='get', endpoint='/_admin/wal/properties')

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise WALPropertiesError(res)
            return {
                'oversized_ops': res.body.get('allowOversizeEntries'),
                'log_size': res.body.get('logfileSize'),
                'historic_logs': res.body.get('historicLogfiles'),
                'reserve_logs': res.body.get('reserveLogfiles'),
                'sync_interval': res.body.get('syncInterval'),
                'throttle_wait': res.body.get('throttleWait'),
                'throttle_limit': res.body.get('throttleWhenPending')
            }

        response = self.handle_request(request, handler)

        return response
Beispiel #3
0
    def _add_index(self, data):
        """Helper method for creating a new index."""
        request = Request(
            method='post',
            endpoint='/_api/index',
            data=data,
            params={'collection': self._name}
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise IndexCreateError(res)
            details = res.body
            details['id'] = details['id'].split('/', 1)[1]
            details.pop('error', None)
            details.pop('code', None)
            if 'minLength' in details:
                details['min_length'] = details.pop('minLength')
            if 'geoJson' in details:
                details['geo_json'] = details.pop('geoJson')
            if 'ignoreNull' in details:
                details['ignore_none'] = details.pop('ignoreNull')
            if 'selectivityEstimate' in details:
                details['selectivity'] = details.pop('selectivityEstimate')
            if 'isNewlyCreated' in details:
                details['new'] = details.pop('isNewlyCreated')
            return details

        return self.handle_request(request, handler)
Beispiel #4
0
    def insert(self, document, sync=None):
        """Insert a new document into the vertex collection.

        If the ``"_key"`` field is present in **document**, its value is used
        as the key of the new document. Otherwise, the key is auto-generated.

        :param document: the document body
        :type document: dict
        :param sync: wait for the operation to sync to disk
        :type sync: bool | None
        :returns: the ID, revision and key of the document
        :rtype: dict
        :raises arango.exceptions.DocumentInsertError: if the document cannot
            be inserted into the collection
        """
        params = {}
        if sync is not None:
            params['waitForSync'] = sync

        request = Request(method='post',
                          endpoint='/_api/gharial/{}/vertex/{}'.format(
                              self._graph_name, self._name),
                          data=document,
                          params=params)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentInsertError(res)
            return res.body['vertex']

        return self.handle_request(request, handler)
Beispiel #5
0
    def configure(self, mode=None, limit=None):
        """Configure the AQL query cache.

        :param mode: the operation mode (``"off"``, ``"on"`` or ``"demand"``)
        :type mode: str | unicode
        :param limit: the maximum number of results to be stored
        :type limit: int
        :returns: the result of the operation
        :rtype: dict
        :raises arango.exceptions.AQLCacheConfigureError: if the
            cache properties cannot be updated
        """
        data = {}
        if mode is not None:
            data['mode'] = mode
        if limit is not None:
            data['maxResults'] = limit

        request = Request(method='put',
                          endpoint='/_api/query-cache/properties',
                          data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise AQLCacheConfigureError(res)
            return {'mode': res.body['mode'], 'limit': res.body['maxResults']}

        return self.handle_request(request, handler)
Beispiel #6
0
    def delete_index(self, index_id, ignore_missing=False):
        """Delete an index from the collection.

        :param index_id: the ID of the index to delete
        :type index_id: str  | unicode
        :param ignore_missing: ignore missing indexes
        :type ignore_missing: bool
        :returns: whether the index was deleted successfully
        :rtype: bool
        :raises arango.exceptions.IndexDeleteError: if the specified index
            cannot be deleted from the collection
        """
        request = Request(
            method='delete',
            endpoint='/_api/index/{}/{}'.format(self._name, index_id)
        )

        def handler(res):
            if res.status_code == 404 and res.error_code == 1212:
                if ignore_missing:
                    return False
                raise IndexDeleteError(res)
            if res.status_code not in HTTP_OK:
                raise IndexDeleteError(res)
            return not res.body['error']

        return self.handle_request(request, handler)
Beispiel #7
0
    def transactions(self):
        """Return details on currently running transactions.

        Fields in the returned dictionary:

        - *last_collected*: the ID of the last collected log file (at the \
        start of each running transaction) or ``None`` if no transactions are \
        running

        - *last_sealed*: the ID of the last sealed log file (at the start \
        of each running transaction) or ``None`` if no transactions are \
        running

        - *count*: the number of current running transactions

        :returns: the information about the currently running transactions
        :rtype: dict
        :raises arango.exceptions.WALTransactionListError: if the details on
            the transactions cannot be retrieved
        """

        request = Request(method='get', endpoint='/_admin/wal/transactions')

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise WALTransactionListError(res)
            return {
                'last_collected': res.body['minLastCollected'],
                'last_sealed': res.body['minLastSealed'],
                'count': res.body['runningTransactions']
            }

        response = self.handle_request(request, handler)

        return response
Beispiel #8
0
    def __contains__(self, key):
        """Check if a document exists in the collection by its key.

        :param key: the document key
        :type key: dict | str | unicode
        :returns: whether the document exists
        :rtype: bool
        :raises arango.exceptions.DocumentInError: if the check cannot
            be executed
        """

        request = Request(
            method='get',
            endpoint='/_api/document/{}/{}'.format(self._name, key)
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                if res.status_code == 404 and res.error_code == 1202:
                    return False

                raise DocumentInError(res)

            return True

        job = self.handle_request(request, handler, job_class=BaseJob)

        return job.result(raise_errors=True)
Beispiel #9
0
    def rename(self, new_name):
        """Rename the collection.

        :param new_name: the new name for the collection
        :type new_name: str  | unicode
        :returns: the new collection details
        :rtype: dict
        :raises arango.exceptions.CollectionRenameError: if the collection
            name cannot be changed
        """
        request = Request(
            method='put',
            endpoint='/_api/collection/{}/rename'.format(self._name),
            data={'name': new_name}
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise CollectionRenameError(res)
            self._name = new_name
            return {
                'id': res.body['id'],
                'is_system': res.body['isSystem'],
                'name': res.body['name'],
                'status': self._status(res.body['status']),
                'type': self.TYPES[res.body['type']]
            }

        return self.handle_request(request, handler)
Beispiel #10
0
    def next(self):
        """Read the next result from the cursor.

        :returns: the next item in the cursor
        :rtype: dict
        :raises: StopIteration, CursorNextError
        """

        if len(self.batch()) == 0:
            if not self.has_more():
                raise StopIteration

            request = Request(method='put',
                              endpoint='/_api/{}/{}'.format(
                                  self._cursor_type, self.id))

            def handler(res):
                if res.status_code not in HTTP_OK:
                    raise CursorNextError(res)
                return res.body

            job = self.handle_request(request,
                                      handler,
                                      job_class=BaseJob,
                                      use_underlying=True)

            result = job.result(raise_errors=True)

            self._data = result

        return self.batch().pop(0)
Beispiel #11
0
    def grant_user_access(self, username):
        """Grant user access to the collection.

        Appropriate permissions are required in order to execute this method.

        :param username: The name of the user.
        :type username: str | unicode
        :returns: Whether the operation was successful or not.
        :rtype: bool
        :raises arango.exceptions.UserGrantAccessError: If the operation fails.
        """
        request = Request(
            method='put',
            endpoint='/_api/user/{}/database/{}/{}'.format(
                username, self.database, self.name
            ),
            data={'grant': 'rw'}
        )

        def handler(res):
            if res.status_code in HTTP_OK:
                return True
            raise UserGrantAccessError(res)

        return self.handle_request(request, handler)
Beispiel #12
0
    def find(self, filters, offset=None, limit=None):
        """Return all documents that match the given filters.

        :param filters: the document filters
        :type filters: dict
        :param offset: the number of documents to skip initially
        :type offset: int
        :param limit: the max number of documents to return
        :type limit: int
        :returns: the document cursor
        :rtype: arango.cursor.Cursor
        :raises arango.exceptions.DocumentGetError: if the document
            cannot be fetched from the collection
        """
        data = {'collection': self._name, 'example': filters}
        if offset is not None:
            data['skip'] = offset
        if limit is not None:
            data['limit'] = limit

        request = Request(
            method='put',
            endpoint='/_api/simple/by-example',
            data=data
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return Cursor(self._conn, res.body)

        return self.handle_request(request, handler)
Beispiel #13
0
    def create_function(self, name, code):
        """Create a new AQL function.

        :param name: the name of the new AQL function to create
        :type name: str | unicode
        :param code: the definition of the function in Javascript
        :type code: str | unicode
        :returns: whether the AQL function was created successfully
        :rtype: bool
        :raises arango.exceptions.AQLFunctionCreateError: if the AQL function
            cannot be created
        """
        request = Request(method='post',
                          endpoint='/_api/aqlfunction',
                          data={
                              'name': name,
                              'code': code
                          })

        def handler(res):
            if res.status_code not in (200, 201):
                raise AQLFunctionCreateError(res)
            return not res.body['error']

        return self.handle_request(request, handler)
Beispiel #14
0
    def indexes(self):
        """Return the collection indexes.

        :returns: the collection indexes
        :rtype: [dict]
        :raises arango.exceptions.IndexListError: if the list of indexes
            cannot be retrieved

        """
        request = Request(
            method='get',
            endpoint='/_api/index',
            params={'collection': self._name}
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise IndexListError(res)

            indexes = []
            for index in res.body['indexes']:
                index['id'] = index['id'].split('/', 1)[1]
                if 'minLength' in index:
                    index['min_length'] = index.pop('minLength')
                if 'geoJson' in index:
                    index['geo_json'] = index.pop('geoJson')
                if 'ignoreNull' in index:
                    index['ignore_none'] = index.pop('ignoreNull')
                if 'selectivityEstimate' in index:
                    index['selectivity'] = index.pop('selectivityEstimate')
                indexes.append(index)
            return indexes

        return self.handle_request(request, handler)
Beispiel #15
0
    def truncate(self):
        """Truncate the collection.

        :returns: the collection details
        :rtype: dict
        :raises arango.exceptions.CollectionTruncateError: if the collection
            cannot be truncated
        """
        request = Request(
            method='put',
            endpoint='/_api/collection/{}/truncate'.format(self._name),
            command='db.{}.truncate()'.format(self._name)
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise CollectionTruncateError(res)
            return {
                'id': res.body['id'],
                'is_system': res.body['isSystem'],
                'name': res.body['name'],
                'status': self._status(res.body['status']),
                'type': self.TYPES[res.body['type']]
            }

        return self.handle_request(request, handler)
Beispiel #16
0
    def clear(self, ignore_missing=False):
        """Delete the result of the job from the server.

        :param ignore_missing: ignore missing async jobs
        :type ignore_missing: bool
        :returns: ``True`` if the result was deleted successfully, ``False``
            if the job was not found but **ignore_missing** was set to ``True``
        :rtype: bool
        :raises arango.exceptions.AsyncJobClearError: if the result of the
            async job cannot be delete from the server
        """

        request = Request(method='delete',
                          endpoint='/_api/job/{}'.format(self.id))

        def handler(res):
            if res.status_code in HTTP_OK:
                return True
            elif res.status_code == 404:
                if ignore_missing:
                    return False
                raise AsyncJobClearError(res, 'Job {} missing'.format(self.id))
            else:
                raise AsyncJobClearError(res)

        response = self._conn.underlying.handle_request(request,
                                                        handler,
                                                        job_class=BaseJob)

        return response.result(raise_errors=True)
Beispiel #17
0
    def status(self):
        """Return the status of the async job from the server.

        :returns: the status of the async job, which can be ``"pending"`` (the
            job is still in the queue), ``"done"`` (the job finished or raised
            an exception), or `"cancelled"` (the job was cancelled before
            completion)
        :rtype: str | unicode
        :raises arango.exceptions.AsyncJobStatusError: if the status of the
            async job cannot be retrieved from the server
        """

        request = Request(method='get',
                          endpoint='/_api/job/{}'.format(self.id))

        def handler(res):
            if res.status_code == 204:
                self.update('pending')
            elif res.status_code in HTTP_OK:
                self.update('done')
            elif res.status_code == 404:
                raise AsyncJobStatusError(res,
                                          'Job {} missing'.format(self.id))
            else:
                raise AsyncJobStatusError(res)

            return self._status

        response = self._conn.underlying.handle_request(request,
                                                        handler,
                                                        job_class=BaseJob)

        return response.result(raise_errors=True)
Beispiel #18
0
    def delete_database(self, name, ignore_missing=False):
        """Delete the database of the specified name.

        :param name: the name of the database to delete
        :type name: str | unicode
        :param ignore_missing: ignore missing databases
        :type ignore_missing: bool
        :returns: whether the database was deleted successfully
        :rtype: bool
        :raises arango.exceptions.DatabaseDeleteError: if the delete fails

        .. note::
            Root privileges (i.e. access to the ``_system`` database) are
            required to use this method.
        """

        request = Request(method='delete',
                          endpoint='/_api/database/{}'.format(name))

        def handler(res):
            if res.status_code not in HTTP_OK:
                if not (res.status_code == 404 and ignore_missing):
                    raise DatabaseDeleteError(res)
            return not res.body['error']

        return self.handle_request(request, handler)
Beispiel #19
0
    def get(self, key, rev=None):
        """Fetch a document by key from the edge collection.

        :param key: the document key
        :type key: str | unicode
        :param rev: the document revision
        :type rev: str | unicode | None
        :returns: the vertex document or ``None`` if not found
        :rtype: dict | None
        :raises arango.exceptions.DocumentRevisionError: if the given revision
            does not match the revision of the target document
        :raises arango.exceptions.DocumentGetError: if the document cannot
            be fetched from the collection
        """

        headers = {}

        if rev is not None:
            headers['If-Match'] = rev

        request = Request(method='get',
                          endpoint='/_api/gharial/{}/edge/{}/{}'.format(
                              self._graph_name, self._name, key),
                          headers=headers)

        def handler(res):
            if res.status_code == 412:
                raise DocumentRevisionError(res)
            elif res.status_code == 404 and res.error_code == 1202:
                return None
            elif res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return res.body['edge']

        return self.handle_request(request, handler)
Beispiel #20
0
    def close(self, ignore_missing=True):
        """Close the cursor and free the resources tied to it.

        :returns: whether the cursor was closed successfully
        :rtype: bool
        :param ignore_missing: ignore missing cursors
        :type ignore_missing: bool
        :raises: CursorCloseError
        """

        if not self.id:
            return False

        request = Request(method='delete',
                          endpoint='/_api/{}/{}'.format(
                              self._cursor_type, self.id))

        def handler(res):
            if res.status_code not in HTTP_OK:
                if res.status_code == 404 and ignore_missing:
                    return False

                raise CursorCloseError(res)

            return True

        return self.handle_request(
            request, handler, job_class=BaseJob,
            use_underlying=True).result(raise_errors=True)
Beispiel #21
0
    def statistics(self):
        """Return the collection statistics.

        :returns: the collection statistics
        :rtype: dict
        :raises arango.exceptions.CollectionStatisticsError: if the
            collection statistics cannot be retrieved
        """
        request = Request(
            method='get',
            endpoint='/_api/collection/{}/figures'.format(self._name)
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise CollectionStatisticsError(res)
            stats = res.body['figures']
            stats['compaction_status'] = stats.pop('compactionStatus', None)
            stats['document_refs'] = stats.pop('documentReferences', None)
            stats['last_tick'] = stats.pop('lastTick', None)
            stats['waiting_for'] = stats.pop('waitingFor', None)
            stats['uncollected_logfile_entries'] = stats.pop(
                'uncollectedLogfileEntries', None
            )
            return stats

        return self.handle_request(request, handler)
Beispiel #22
0
    def flush(self, sync=True, garbage_collect=True):
        """Flush the write-ahead log to collection journals and data files.

        :param sync: block until data is synced to disk
        :type sync: bool
        :param garbage_collect: block until flushed data is garbage collected
        :type garbage_collect: bool
        :returns: whether the write-ahead log was flushed successfully
        :rtype: bool
        :raises arango.exceptions.WALFlushError: it the WAL cannot
            be flushed
        """
        data = {'waitForSync': sync, 'waitForCollector': garbage_collect}

        request = Request(method='put',
                          endpoint='/_admin/wal/flush',
                          data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise WALFlushError(res)
            return not res.body.get('error')

        response = self.handle_request(request, handler)

        return response
Beispiel #23
0
    def checksum(self, with_rev=False, with_data=False):
        """Return the collection checksum.

        :param with_rev: include the document revisions in the checksum
            calculation
        :type with_rev: bool
        :param with_data: include the document data in the checksum
            calculation
        :type with_data: bool
        :returns: the collection checksum
        :rtype: int
        :raises arango.exceptions.CollectionChecksumError: if the
            collection checksum cannot be retrieved
        """
        request = Request(
            method='get',
            endpoint='/_api/collection/{}/checksum'.format(self._name),
            params={'withRevision': with_rev, 'withData': with_data}
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise CollectionChecksumError(res)
            return int(res.body['checksum'])

        return self.handle_request(request, handler)
Beispiel #24
0
    def __getitem__(self, key):
        """Return a document by its key from the collection.

        :param key: the document key
        :type key: str  | unicode
        :returns: the document
        :rtype: dict
        :raises arango.exceptions.DocumentGetError: if the document cannot
            be fetched from the collection
        """

        request = Request(
            method='get',
            endpoint='/_api/document/{}/{}'.format(self._name, key)
        )

        def handler(res):
            if res.status_code == 404 and res.error_code == 1202:
                return None
            elif res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return res.body

        job = self.handle_request(request, handler, job_class=BaseJob)

        return job.result(raise_errors=True)
Beispiel #25
0
    def all(self,
            skip=None,
            limit=None):
        """Return all documents in the collection using a server cursor.

        :param skip: the number of documents to skip
        :type skip: int
        :param limit: the max number of documents fetched by the cursor
        :type limit: int
        :returns: the document cursor
        :rtype: arango.cursor.Cursor
        :raises arango.exceptions.DocumentGetError: if the documents in
            the collection cannot be retrieved
        """

        data = {'collection': self._name}
        if skip is not None:
            data['skip'] = skip
        if limit is not None:
            data['limit'] = limit

        request = Request(
            method='put',
            endpoint='/_api/simple/all',
            data=data
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return Cursor(self._conn, res.body)

        return self.handle_request(request, handler)
Beispiel #26
0
    def user_access(self, username):
        """Return a user's access details for the collection.

        Appropriate permissions are required in order to execute this method.

        :param username: The name of the user.
        :type username: str | unicode
        :returns: The access details (e.g. ``"rw"``, ``None``)
        :rtype: str | unicode | None
        :raises: arango.exceptions.UserAccessError: If the retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/user/{}/database/{}/{}'.format(
                username, self.database, self.name
            )
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise UserAccessError(res)
            result = res.body['result'].lower()
            if result == 'none':
                return None
            else:
                return result

        return self.handle_request(request, handler)
Beispiel #27
0
    def update_match(self,
                     filters,
                     body,
                     limit=None,
                     keep_none=True,
                     sync=None):
        """Update matching documents in the collection.

        :param filters: the filters
        :type filters: dict
        :param body: the document body
        :type body: dict
        :param limit: the max number of documents to return
        :type limit: int
        :param keep_none: if ``True``, the fields with value ``None``
            are retained in the document, otherwise the fields are removed
            from the document completely
        :type keep_none: bool
        :param sync: wait for the operation to sync to disk
        :type sync: bool
        :returns: the number of documents updated
        :rtype: int
        :raises arango.exceptions.DocumentUpdateError: if the documents
            cannot be updated
        """
        data = {
            'collection': self._name,
            'example': filters,
            'newValue': body,
            'keepNull': keep_none,
        }
        if limit is not None:
            data['limit'] = limit
        if sync is not None:
            data['waitForSync'] = sync

        if self._conn.type != 'transaction':
            command = None
        else:
            command = 'db.{}.updateByExample({},{},{})'.format(
                self._name,
                dumps(filters),
                dumps(body),
                dumps(data)
            )

        request = Request(
            method='put',
            endpoint='/_api/simple/update-by-example',
            data=data,
            command=command
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentUpdateError(res)
            return res.body['updated']

        return self.handle_request(request, handler)
Beispiel #28
0
    def execute(self,
                query,
                count=False,
                batch_size=None,
                ttl=None,
                bind_vars=None,
                full_count=None,
                max_plans=None,
                optimizer_rules=None):
        """Execute the query and return the result cursor.

        :param query: the AQL query to execute
        :type query: str | unicode
        :param count: whether the document count should be returned
        :type count: bool
        :param batch_size: maximum number of documents in one round trip
        :type batch_size: int
        :param ttl: time-to-live for the cursor (in seconds)
        :type ttl: int
        :param bind_vars: key-value pairs of bind parameters
        :type bind_vars: dict
        :param full_count: include count before last LIMIT
        :param max_plans: maximum number of plans the optimizer generates
        :type max_plans: int
        :param optimizer_rules: list of optimizer rules
        :type optimizer_rules: list
        :returns: document cursor
        :rtype: arango.cursor.Cursor
        :raises arango.exceptions.AQLQueryExecuteError: if the query cannot be
            executed
        :raises arango.exceptions.CursorCloseError: if the cursor cannot be
            closed properly
        """
        options = {}
        if full_count is not None:
            options['fullCount'] = full_count
        if max_plans is not None:
            options['maxNumberOfPlans'] = max_plans
        if optimizer_rules is not None:
            options['optimizer'] = {'rules': optimizer_rules}

        data = {'query': query, 'count': count}
        if batch_size is not None:
            data['batchSize'] = batch_size
        if ttl is not None:
            data['ttl'] = ttl
        if bind_vars is not None:
            data['bindVars'] = bind_vars
        if options:
            data['options'] = options

        request = Request(method='post', endpoint='/_api/cursor', data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise AQLQueryExecuteError(res)
            return Cursor(self._conn, res.body)

        return self.handle_request(request, handler)
Beispiel #29
0
    def find_in_box(self,
                    latitude1,
                    longitude1,
                    latitude2,
                    longitude2,
                    skip=None,
                    limit=None,
                    geo_field=None):
        """Return all documents in an rectangular area.

        :param latitude1: the first latitude
        :type latitude1: int
        :param longitude1: the first longitude
        :type longitude1: int
        :param latitude2: the second latitude
        :type latitude2: int
        :param longitude2: the second longitude
        :type longitude2: int
        :param skip: the number of documents to skip
        :type skip: int
        :param limit: the max number of documents to return (if 0 is given all
            documents are returned)
        :type limit: int
        :param geo_field: the field to use for geo index
        :type geo_field: str  | unicode
        :returns: the document cursor
        :rtype: arango.cursor.Cursor
        :raises arango.exceptions.DocumentGetError: if the documents
            cannot be fetched from the collection
        """
        data = {
            'collection': self._name,
            'latitude1': latitude1,
            'longitude1': longitude1,
            'latitude2': latitude2,
            'longitude2': longitude2,
        }
        if skip is not None:
            data['skip'] = skip
        if limit is not None:
            data['limit'] = limit
        if geo_field is not None:
            data['geo'] = '/'.join([self._name, geo_field])

        request = Request(
            method='put',
            endpoint='/_api/simple/within-rectangle',
            data=data
        )

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return Cursor(self._conn, res.body)

        return self.handle_request(request, handler)
Beispiel #30
0
    def create_database(self, name, users=None, username=None, password=None):
        """Create a new database.

        :param name: the name of the new database
        :type name: str | unicode
        :param users: the list of users with access to the new database, where
            each user is a dictionary with keys ``"username"``, ``"password"``,
            ``"active"`` and ``"extra"``.
        :type users: [dict]
        :param username: the username for authentication (if set, overrides
            the username specified during the client initialization)
        :type username: str | unicode
        :param password: the password for authentication (if set, overrides
            the password specified during the client initialization
        :type password: str | unicode
        :returns: the database object
        :rtype: arango.database.Database
        :raises arango.exceptions.DatabaseCreateError: if the create fails

        .. note::
            Here is an example entry in **users**:

            .. code-block:: python

                {
                    'username': '******',
                    'password': '******',
                    'active': True,
                    'extra': {'Department': 'IT'}
                }

            If **users** is not set, only the root and the current user are
            granted access to the new database by default.
        """

        data = {
            'name': name,
        }

        if users is not None:
            data['users'] = [{
                'username': user['username'],
                'passwd': user['password'],
                'active': user.get('active', True),
                'extra': user.get('extra', {})
            } for user in users]

        request = Request(method='post', endpoint='/_api/database', data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DatabaseCreateError(res)
            return self.db(name, username, password)

        return self.handle_request(request, handler)