# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['rqlalchemy']

package_data = \
{'': ['*']}

install_requires = \
['pyrql>=0.6.0,<0.7.0', 'sqlalchemy>=1.2,<2.0']

setup_kwargs = {
    'name': 'rqlalchemy',
    'version': '0.4.1',
    'description': '"Resource Query Language for SQLAlchemy"',
    'long_description': '# RQLAlchemy\n\n[![Build Status](https://travis-ci.org/pjwerneck/rqlalchemy.svg?branch=develop)](https://travis-ci.org/pjwerneck/rqlalchemy)\n\nResource Query Language extension for SQLAlchemy\n\n## Overview\n\nResource Query Language (RQL) is a query language designed for use in URIs, with object-style data structures.\n\nrqlalchemy is an RQL extension for SQLAlchemy. It easily allows exposing SQLAlchemy tables or models as an HTTP API endpoint and performing complex queries using only querystring parameters.\n\n## Installing\n\n```\npip install rqlalchemy\n```\n\n## Usage\n\nRQL queries can be supported by an application using SQLAlchemy by adding the `rqlalchemy.RQLQueryMixIn` class as a mix-in class to your base `Query` class:\n\n```python\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import Query as BaseQuery\n\nfrom rqlalchemy import RQLQueryMixIn\n\n# create the declarative base\nBase = declarative_base()\n\n# create the custom query class\nclass RQLQuery(BaseQuery, RQLQueryMixIn):\n    _rql_default_limit = 10\n    _rql_max_limit = 100\n\n# assign the custom query class to the declarative base\nBase.query_class = RQLQuery\n```\n\nWith that in place, you can perform RQL queries by passing the querystring to the query `rql()` method. For example, if you have a Flask HTTP API with an users collection endpoint querying your `User` model:\n\n```python\nfrom urllib.parse import unquote\n\nfrom flask import request\n\n@app.route(\'/users\')\ndef get_users_collection():\n    qs = unquote(request.query_string.decode(request.charset))\n    query = session.query(User).rql(qs)\n    users = query.rql_all()\n\n    return render_response(users)\n```\n\n### Aggregates\n\nAs with the base SQLAlchemy Query class, you can retrieve results with the `all()` method, or by iterating over the query, however, if you want to support RQL expressions with aggregate functions or querying functions that result in a subset of columns, you must retrieve the results with `rql_all()`.\n\n### Pagination\n\nRQLAlchemy offers limit/offset pagination with the `rql_paginate()` method, which returns the requested page, the RQL expressions for previous and next pages if available, and the total number of items.\n\n```python\nfrom urllib.parse import unquote\n\nfrom flask import request\n\n@app.route(\'/users\')\ndef get_users_collection():\n    qs = unquote(request.query_string.decode(request.charset))\n    query = session.query(User).rql(qs)\n    page, previous_page, next_page, total = query.rql_paginate()\n\n    response = {"data": page,\n                "total": total,\n               }\n\n    if previous_page:\n        response["previous"] = \'/users?\' + previous_page\n\n    if next_page:\n        response["next"] = \'/users?\' + next_page\n\n    return render_response(response)\n```\n\nKeep in mind that pagination requires a limit, either a `_rql_default_limit` value, a querystring `limit(x)`, or the `limit` parameter to the `rql()` method. Calling `rql_paginate()` without a limit will raise `RQLQueryError`.\n\n\n## Reference Table\n\n| RQL                     | SQLAlchemy                                         | Obs.                                                                                                                            |\n|-------------------------|----------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|\n| QUERYING                |                                                    |                                                                                                                                 |\n| select(a,b,c,...)       | .query(Model.a, Model.b, Model.c,...)              |                                                                                                                                 |\n| values(a)               | [o.a for o in query.from_self(a)]                  |                                                                                                                                 |\n| limit(count,start?)     | .limit(count).offset(start)                        |                                                                                                                                 |\n| sort(attr1)             | .order_by(attr)                                    |                                                                                                                                 |\n| sort(-attr1)            | .order_by(attr.desc())                             |                                                                                                                                 |\n| distinct()              | .distinct()                                        |                                                                                                                                 |\n| first()                 | .limit(1)                                          |                                                                                                                                 |\n| one()                   | [query.one()]                                      |                                                                                                                                 |\n| FILTERING               |                                                    |                                                                                                                                 |\n| eq(attr,value)          | .filter(Model.attr == value)                       |                                                                                                                                 |\n| ne(attr,value)          | .filter(Model.attr != value)                       |                                                                                                                                 |\n| lt(attr,value)          | .filter(Model.attr < value)                        |                                                                                                                                 |\n| le(attr,value)          | .filter(Model.attr <= value)                       |                                                                                                                                 |\n| gt(attr,value)          | .filter(Model.attr > value)                        |                                                                                                                                 |\n| ge(attr,value)          | .filter(Model.attr >= value)                       |                                                                                                                                 |\n| in(attr,value)          | .filter(Model.attr.in_(value)                      |                                                                                                                                 |\n| out(attr,value)         | .filter(not_(Model.attr.in_(value)))               |                                                                                                                                 |\n| contains(attr,value)    | .filter(Model.contains(value))                     | Produces a LIKE expression when filtering against a string, or an IN expression when filtering against an iterable relationship |\n| excludes(attr,value)    | .filter(not_(Model.contains(value)))               | See above.                                                                                                                      |\n| and(expr1,expr2,...)    | .filter(and_(expr1, expr2, ...))                   |                                                                                                                                 |\n| or(expr1,expr2,...)     | .filter(or_(expr1, expr2, ...))                    |                                                                                                                                 |\n| AGGREGATING             |                                                    | All aggregation functions return scalar results.                                                                                |\n| aggregate(a,b\\(c\\),...) | .query(Model.a, func.b(Model.c)).group_by(Model.a) |                                                                                                                                 |\n| sum(attr)               | .query(func.sum(Model.attr))                       |                                                                                                                                 |\n| mean(attr)              | .query(func.avg(Model.attr))                       |                                                                                                                                 |\n| max(attr)               | .query(func.max(Model.attr))                       |                                                                                                                                 |\n| min(attr)               | .query(func.min(Model.attr))                       |                                                                                                                                 |\n| count()                 | .query(func.count())                               |                                                                                                                                 |\n',
    'author': 'Pedro Werneck',
    'author_email': 'pjwerneck@gmail.com',
    'url': 'https://github.com/pjwerneck/rqlalchemy',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.5,<4.0',
}


setup(**setup_kwargs)
