# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['medoo', 'medoo.database']

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

extras_require = \
{'all': ['mysql-connector-python>=8,<9',
         'psycopg2>=2,<3',
         'pymssql>=2,<3',
         'cx-Oracle>=8,<9'],
 'mssql': ['pymssql>=2,<3'],
 'mysql': ['mysql-connector-python>=8,<9'],
 'oracle': ['cx-Oracle>=8,<9'],
 'postgresql': ['psycopg2>=2,<3']}

setup_kwargs = {
    'name': 'medoo',
    'version': '0.1.2',
    'description': 'A lightweight database framework for python',
    'long_description': '# pymedoo - A lightweight database framework for python\n\nit\'s inspired by [Medoo][1] for PHP and [Records][7] for python.\n\n[![Pypi][8]][15]\n[![Github][9]][16]\n[![Codacy][10]][17]\n[![Codacy coverage][11]][17]\n![Building][12]\n\n## Install\n\n```bash\npip install medoo\n```\n\n## Required packages for databases\n\n| Database | Package   | Install |\n|----------|---------  | --------|\n| sqlite   | [sqlite3][2]   | `pip install medoo[sqlite]` |\n| mysql    | ~~[pymysql][3]~~(dropped) Use [mysql.connector][13] instead. See [#6][14] | `pip install medoo[mysql]` |\n| pgsql    | [psycopg2][4]  | `pip install medoo[pgsql]` |\n| mssql    | [pymssql][5]   | `pip install medoo[mssql]` |\n| oracle   | [cx_Oracle][6] | `pip install medoo[oracle]` |\n\nInstall forr all supported databases:\n\n```bash\npip install medoo[all]\n```\n\n## Get started\n\n### SELECT\n\n```python\nfrom medoo import Medoo\n\n# For other arguments, please refer to the original connect function of each client.\nme = Medoo(dbtype = \'sqlite\', database = \'file:///path/to/test.sqlite\')\n\n# SELECT * FROM "Customers"\nrs = me.select(\'Customers\')\n\nprint(rs.export(\'csv\', delimiter = \'\\t\'))\n```\n\n|CustomerID|CustomerName|ContactName|Address|City|PostalCode|Country|\n|-|-|-|-|-|-|-|\n|1|Alfreds Futterkiste|Maria Anders|Obere Str. 57|Berlin|12209|Germany|\n|2|Ana Trujillo Emparedados y helados|Ana Trujillo|Avda. de la Constitución 2222|México D.F.|5021|Mexico|\n|3|Antonio Moreno Taquería|Antonio Moreno|Mataderos 2312|México D.F.|5023|Mexico|\n|4|Around the Horn|Thomas Hardy|120 Hanover Sq.|London|WA1 1DP|UK|\n|5|Berglunds snabbköp|Christina Berglund|Berguvsvägen 8|Luleå|S-958 22|Sweden|\n\n```python\n# SELECT "CustomerID","CustomerName" FROM "Customers"\nme.select(\'Customers\', \'CustomerID, CustomerName\')\nme.select(\'Customers\', [\'CustomerID\', \'CustomerName\'])\n\n# SELECT "C"."CustomerID" AS "CustomerID","C"."CustomerName" AS "name" FROM "Customers" AS "C"\nme.select(\'Customers(C)\', [\'C.CustomerID(id)\', \'C.CustomerName(name)\'])\n\n# SELECT DISTINCT "Country" FROM "Customers"\nme.select(\'Customers\', \'Country\', distinct = True)\n\n# SELECT COUNT("CustomerID") FROM "Customers"\nme.select(\'Customers\', \'CustomerID|COUNT\')\n\n# SELECT COUNT(DISTINCT "CustomerID") AS "c" FROM "Customers"\nme.select(\'Customers\', \'CustomerID|.COUNT(c)\')\n\n# SELECT "CustomerID"+1 FROM "Customers"\nfrom medoo import Field, Raw\nme.select(\'Customers\', Field(\'CustomerID\')+1)\n\n# SELECT \'Name: \' || CustomerName AS name FROM "Customers"\nrs = me.select(\'Customers\', Raw("\'Name: \' || CustomerName AS name"))\nfor r in rs: print(r.name)\n```\n\n```\nName: Alfreds Futterkiste\nName: Ana Trujillo Emparedados y helados\nName: Antonio Moreno Taquería\nName: Around the Horn\nName: Berglunds snabbköp\n```\n\n### WHERE\n\n#### Single condition\n\n```python\n# SELECT * FROM "Customers" WHERE "CustomerID" = 1\nme.select(\'Customers\', where = {\'CustomerID\': 1})\n\n# SELECT * FROM "Customers" WHERE "CustomerID" < 3\nme.select(\'Customers\', where = {\'CustomerID[<]\': 3})\n\n# SELECT * FROM "Customers" WHERE "CustomerID" IN (1,2,3)\nme.select(\'Customers\', where = {\'CustomerID\': (1,2,3)})\n\n# SELECT * FROM "Customers" WHERE "CustomerName" LIKE \'%b%\' OR "CustomerName" LIKE \'%c%\'\nme.select(\'Customers\', where = {\'CustomerName[~]\': (\'a\', \'b\')})\n\n# SELECT * FROM "Customers" WHERE "CustomerID" BETWEEN 1 AND 3\nme.select(\'Customers\', where = {\'CustomerID[<>]\': (1,3)})\n\n# SELECT * FROM "Customers" WHERE NOT "CustomerID" BETWEEN 1 AND 3\nme.select(\'Customers\', where = {\'!CustomerID[<>]\': (1,3)})\n\n# SELECT * FROM "Customers" WHERE "CustomerID" IS NULL\nme.select(\'Customers\', where = {\'CustomerID[is]\': None}) # where = {\'id[==]\': None}\n\n# SELECT * FROM "Customers" WHERE INSTR("CustomerName", \'Antonio\')\nme.select(\'Customers\', where = {Raw(\'INSTR("CustomerName", \\\'Antonio\\\')\'):None})\n```\n\n#### Compond\n\n```python\n# SELECT * FROM "Customers" WHERE "CustomerID" IN (1,2,3) AND "CustomerName" LIKE \'%b%\'\nme.select(\'Customers\', where = {\n    \'CustomerID\': (1,2,3),\n    \'CustomerName[~]\': \'b\'\n})\n# SELECT * FROM "Customers"\n# WHERE ("CustomerID" IN (1,2,3) AND "CustomerName" LIKE \'%b%\') AND\n# ("CustomerName" = \'cd\' OR "CustomerID" = 2) AND\n# ("CustomerID" < 3 AND NOT "CustomerName" = \'bc\')\nme.select(\'Customers\', where = {\n    \'AND\': {\n        \'CustomerID\': (1,2,3),\n        \'CustomerName[~]\': \'b\'\n    },\n    \'OR\': {\n        \'CustomerName\': \'cd\',\n        \'CustomerID\': 2\n    },\n    # you can use comment to distinguish multiple ANDs and ORs\n    \'AND #2\': {\n        \'CustomerID[<]\': 3,\n        \'!CustomerName\': \'bc\'\n    }\n})\n```\n\n#### Modifier\n\n```python\n# SELECT * FROM "Customers" ORDER BY "CustomerID" DESC, "CustomerName" ASC LIMIT 2 OFFSET 1\n# MSSQL:\n# SELECT * FROM "Customers" ORDER BY "CustomerID" DESC, "CustomerName" ASC\n# OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY\nme.select(\'Customers\', where = {\n    \'ORDER\': {\'CustomerID\': \'desc\', \'CustomerName\': \'asc\'},\n    \'LIMIT\': (2, 1)\n})\n\n# SELECT COUNT("CustomerID") AS "c","CustomerName" FROM "Customers" GROUP BY "Country" HAVING "CustomerID" > 1\nme.select(\'Customers\', \'CustomerID|count(c), CustomerName\', where = {\n    \'GROUP\': \'Country\',\n    \'HAVING\': {\'CustomerID[>]\': 1}\n})\n```\n\n### Using subquery\n\n```python\nprint(me.select(\'Orders\').export(\'csv\', delimiter = \'\\t\'))\n```\n\n|OrderID|CustomerID|OrderDate|\n|-|-|-|\n|10308|2|1996-09-18|\n|10309|37|1996-09-19|\n|10310|77|1996-09-20|\n\n```python\n# SELECT * FROM "Customers" AS "C",(SELECT "CustomerID" FROM "Orders") AS "O"\n#   WHERE "C"."CustomerID" = "O"."CustomerID"\nme.select([\n    \'Customers(C)\', # the first table\n    me.builder.select(\'Orders\', \'CustomerID\', sub = \'O\')\n], where = {\n    \'C.CustomerID\': Field(\'O.CustomerID\')\n})\n\n# SELECT * FROM "Customers" WHERE "CustomerID" IN (SELECT "CustomerID" FROM "Orders")\nme.select(\'Customers\', where = {\n    \'CustomerID\': me.builder.select(\'Orders\', \'CustomerID\')\n})\n```\n\n### JOIN\n\n```python\n# SELECT "O"."OrderID","C"."CustomerName","O"."OrderDate" FROM "Orders" AS "O"\n#   INNER JOIN "Customers" AS "C" ON "C"."CustomerID"="O"."CustomerID"\nme.select(\'Orders(O)\', \'O.OrderID,C.CustomerName,O.OrderDate\', join = {\n    \'Customers(C)\': \'CustomerID\'\n})\n\n# equivalent to\nme.select(\'Orders(O)\', \'O.OrderID,C.CustomerName,O.OrderDate\', join = {\n    \'[><]Customers(C)\': \'CustomerID\'\n})\n# [>] LEFT JOIN, [<] RIGHT JOIN [<>] FULL OUTER JOIN\n\n# Join on multiple columns (same in different tables)\n# join = { \'[><]Customers(C)\': [\'CustomerID\', \'OtherColumn\'] }\n\n# Join on different columns: JOIN "Customers" AS "C" ON "C"."CustomerID"="O"."OtherID"\n# join = { \'[><]Customers(C)\': {\'CustomerID\', \'OtherID\'} }\n\n# You can join multiple tables, use OrderedDict if you want to keep the order.\n```\n\n### UNION\n\n```python\n# SELECT "CustomerID" FROM "Customers" UNION SELECT "CustomerID" FROM "Orders"\nme.union(\n    me.builder.select(\'Customers\', \'CustomerID\'),\n    me.builder.select(\'Orders\', \'CustomerID\')\n)\n\n# SELECT "CustomerID" FROM "Customers" UNION ALL SELECT "CustomerID" FROM "Orders"\nme.union(\n    me.builder.select(\'Customers\', \'CustomerID\'),\n    me.builder.select(\'Orders\', \'CustomerID\', sub = True)\n)\n```\n\n### Records\n\n`Medoo.select` and `Medoo.union` return a collection of records, which is basically a generator, but you can still get items from it, as it will consume the generate if necessary. The idea is borrowed from [Records][7].\n\n```python\nrecords = me.select(\'Customers\', \'CustomerID(id)\')\nrecord  = records.first() # <Record {\'id\': 1}>\n\n# equivalent to\nrecord  = records[0]\n\n# you may also select other rows: records[1], records[2]\n# or return all rows:\nprint(records.all())\n\n# you can also export the records\n# this is the courtesy from tablib (https://github.com/kennethreitz/tablib)\n# check the kwargs with its documentation\nprint(records.export(\'csv\', delimiter = \'\\t\'))\n\n# You can also apply tablib\'s other function on the data:\n# records.tldata.<function>(<args>)\n\n# to get the value of each field from a record:\nprint(record[0]) # 1\nprint(record[\'id\']) # 1\nprint(record.id) # 1\nprint(record.as_dict()) # {\'id\': 1}\n```\n\n### INSERT\n\n```python\n# INSERT INTO "Orders" ("OrderID","CustomerID","OrderDate") VALUES (1,2,\'1999-09-09\'),(2,8,\'2001-10-12\')\nme.insert(\n    \'Orders\', # table\n    \'OrderID, CustomerID, OrderDate\', # fields\n    (1,2,\'1999-09-09\'), # values\n    (2,8,\'2001-10-12\')\n    # ...\n)\n# get the last insert row id\nprint(me.id()) # 5\n\n# INSERT INTO "Orders" ("OrderID","CustomerID","OrderDate") VALUES (1,2,\'1999-09-09\'),(2,8,\'2001-10,12\')\nme.insert(\n    \'Orders\', # table\n    {\'OrderID\': 1, \'CustomerID\': 2, \'OrderDate\': \'1999-09-09\'}, # fields with the first value\n    (2,8,\'2001-10-12\')\n    # ...\n)\nme.insert(\n    \'Orders\', # table\n    {\'OrderID\': 1, \'CustomerID\': 2, \'OrderDate\': \'1999-09-09\'}, # fields with the first value\n    {\'OrderID\': 2, \'CustomerID\': 8, \'OrderDate\': \'2001-10-12\'}  # specify the fields as well\n    # ...\n)\n# Or if your values have all the fields\n# INSERT INTO "Orders" VALUES (1,2,\'1999-09-09\'),(2,8,\'2001-10-12\')\nme.insert(\n    \'Orders\', # table\n    (1,2,\'1999-09-09\')\n    (2,8,\'2001-10-12\')\n    # ...\n)\n\n# You may hold the changes until all data inserted\nme.insert(..., commit = False)\nme.insert(..., commit = False)\nme.insert(..., commit = False)\nme.insert(..., commit = False)\nme.commit()\n# This applies with UPDATE and DELETE as well.\n```\n\n### UPDATE\n\n```python\n# UPDATE "Orders" SET "CustomerID"=10 WHERE "OrderID" = 2\nme.update(\n    \'Orders\', # table\n    data  = {\'CustomerID\': 10},\n    where = {\'OrderID\': 2}\n)\n# UPDATE "Orders" SET "CustomerID"="CustomerID"+1 WHERE "OrderID" = 2\nme.update(\n    \'Orders\', # table\n    data  = {\'CustomerID[+]\': 1},\n    where = {\'OrderID\': 2}\n)\n```\n\n### DELETE\n\n```python\n# DELETE FROM "Orders" WHERE "OrderID" = 2\nme.delete(\'Orders\', where = {\'OrderID\': 2})\n```\n\n### Other functions of `Medoo`\n\n```python\n# Fetch a single value\nme.get(\'Customers\', \'CustomerID\', where = {\'CustomerName\': \'Around the Horn\'}) # == 1\n\n# Check if a record exists\nme.has(\'Customers\', where = {\'CustomerID\': 10}) # == False\n\n# Return the last query\nme.last() # SELECT * FROM "Customers" WHERE "CustomerID" = 10\n\n# Show all the queries bound with `me`\n\n# You have to passing `logging = True` to `Medoo(..., logging = True)`\nme.log()\n\n# Return the errors\nme.error()\n\n# Submit an SQL query\nme.query(sql, commit = True)\n```\n\n### Extending `pymedoo`\n\n`pymedoo` is highly extendable, including the operators in `WHERE` conditions and `UPDATE SET` clause, `JOIN` operators, and some functions such as how to quote the table names, field names and values. All of these have been defined with `Dialect` class, what you need to do is just extend this class and specify it to the `Medoo` instance.\nFor example, let\'s define a case-insensitive `LIKE` operator using a shortcut `~~`:\n\n```python\nfrom medoo import Medoo, Dialect\n\nclass MyDialect(Dialect):\n    OPERATOR_MAP = {\n        \'~~\': \'ilike\'\n    }\n\n    @classmethod\n    def ilike(klass, field, value):\n        # support single value\n        if not isinstance(value, list):\n            value = [value]\n\n        terms = [\n            "UPPER({}) LIKE UPPER({})".format(field, klass.value(v)) # quote the value\n            for v in value\n        ]\n        # use OR to connect\n        return \' OR \'.join(terms)\n\n# tell medoo to use this dialect\nme = Medoo(...)\nme.dialect(MyDialect)\n\n# SELECT * FROM "Customers" WHERE UPPER("CustomerName") LIKE UPPER(\'%an%\')\nrecords = me.select(\'Customers\', where = {\n    \'CustomerName[~~]\': \'%an%\'\n})\nprint(records.export(\'csv\', delimiter = \'\\t\'))\n```\n\n|CustomerID|CustomerName|ContactName|Address|City|PostalCode|Country|\n|-|-|-|-|-|-|-|\n|2|Ana Trujillo Emparedados y helados|Ana Trujillo|Avda. de la Constitución 2222|México D.F.|5021|Mexico|\n|3|Antonio Moreno Taquería|Antonio Moreno|Mataderos 2312|México D.F.|5023|Mexico|\n\n[1]: https://medoo.in/\n[2]: https://docs.python.org/2/library/sqlite3.html\n[3]: https://github.com/PyMySQL/PyMySQL\n[4]: http://initd.org/psycopg/docs/\n[5]: http://www.pymssql.org/en/stable/\n[6]: https://oracle.github.io/python-cx_Oracle/\n[7]: https://github.com/kennethreitz/records\n[8]: https://img.shields.io/pypi/v/medoo.svg?style=flat-square\n[9]: https://img.shields.io/github/tag/pwwang/pymedoo.svg?style=flat-square\n[10]: https://img.shields.io/codacy/grade/c049a2bf5ca84484b885cfbfedc27eab.svg?style=flat-square\n[11]: https://img.shields.io/codacy/coverage/c049a2bf5ca84484b885cfbfedc27eab.svg?style=flat-square\n[12]: https://img.shields.io/github/workflow/status/pwwang/pymedoo/Build%20and%20Deploy?style=flat-square\n[13]: https://dev.mysql.com/doc/connector-python/en/\n[14]: https://github.com/pwwang/pymedoo/issues/6\n[15]: https://pypi.org/project/pymedoo/\n[16]: https://github.com/pwwang/pymedoo\n[17]: https://app.codacy.com/gh/pwwang/pymedoo\n',
    'author': 'pwwang',
    'author_email': 'pwwang@pwwang.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://github.com/pwwang/pymedoo',
    'packages': packages,
    'package_data': package_data,
    'extras_require': extras_require,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
