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

packages = \
['tap_mssql', 'tap_mssql.sync_strategies']

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

install_requires = \
['attrs>=16.3.0',
 'backoff>=1.8.0',
 'pendulum>=1.2.0',
 'pymssql>=2.2.1',
 'singer-python==5.9.0']

entry_points = \
{'console_scripts': ['tap-mssql = tap_mssql.__init__:main']}

setup_kwargs = {
    'name': 'tap-mssql',
    'version': '2.0.2',
    'description': 'A pipelinewise compatible tap for connecting Microsoft SQL Server',
    'long_description': '# pipelinewise-tap-mssql\n\n[Singer](https://www.singer.io/) tap that extracts data from a [mssql](https://www.mssql.com/) database and produces JSON-formatted data following the [Singer spec](https://github.com/singer-io/getting-started/blob/master/docs/SPEC.md).\n\nThis is a [PipelineWise](https://transferwise.github.io/pipelinewise) compatible tap connector.\n\n## How to use it\n\nThe recommended method of running this tap is to use it from [PipelineWise](https://transferwise.github.io/pipelinewise). When running it from PipelineWise you don\'t need to configure this tap with JSON files and most of things are automated. Please check the related documentation at [Tap mssql](https://transferwise.github.io/pipelinewise/connectors/taps/mssql.html)\n\nIf you want to run this [Singer Tap](https://singer.io) independently please read further.\n\n## Usage\n\nThis section dives into basic usage of `tap-mssql` by walking through extracting\ndata from a table. It assumes that you can connect to and read from a mssql\ndatabase.\n\n### Install\n\nFirst, make sure Python 3 is installed on your system or follow these\ninstallation instructions for [Mac](http://docs.python-guide.org/en/latest/starting/install3/osx/) or\n[Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-ubuntu-16-04).\n\nIt\'s recommended to use a virtualenv:\n\n```bash\n  python3 -m venv venv\n  pip install tap-mssql\n```\n\nor\n\n```bash\n  python3 -m venv venv\n  . venv/bin/activate\n  pip install --upgrade pip\n  pip install tap-mssql\n```\n\n#### Additional OS X Requirements\n\nIn the event you encounter install issues on OS X stating `fatal error: \'sqlfront.h\' file not found`, install FreeTDS with SQL Server compatibility:\n\n1. Download the latest version from [FreeTDS](https://www.freetds.org/)\n2. Extract and run `./configure --enable-msdblib`\n3. Run `make && make install`\n\n### Have a source database\n\nThere\'s some important business data siloed in this mssql database -- we need to\nextract it. Here\'s the table we\'d like to sync:\n\n```\nmssql> select * from example_db.animals;\n+----|----------|----------------------+\n| id | name     | likes_getting_petted |\n+----|----------|----------------------+\n|  1 | aardvark |                    0 |\n|  2 | bear     |                    0 |\n|  3 | cow      |                    1 |\n+----|----------|----------------------+\n3 rows in set (0.00 sec)\n```\n\n### Create the configuration file\n\nCreate a config file containing the database connection credentials, e.g.:\n\n```json\n{\n  "host": "localhost",\n  "database": "db",\n  "port": "3306",\n  "user": "root",\n  "password": "password"\n}\n```\n\nWindows Authentication is available! Don\'t provide a user or password and pymssql will use the user that is running the process on windows to login.\ne.g.:\n\n```json\n{\n  "host": "localhost",\n  "database": "db"\n}\n```\n\nOptional:\n\nTo filter the discovery to a particular schema within a database. This is useful if you have a large number of schemas and wish to speed up the discovery.\n\n```json\n{\n  "filter_dbs": "your database schema name"\n}\n```\n\nOptional:\n\nTo emit a date as a date without a time component or time without an UTC offset. This is helpful to avoid time conversions or to just work with a date datetype in the target database. If this boolean config item is not set, the default behaviour is `false` i.e. emit date datatypes as a datetime. It is recommended to set this on if you have time datetypes and are having issues uploading into into a target database.\n\n```json\n{\n  "use_date_datatype": true\n}\n```\n\nOptional:\n\nSet the version of TDS to use when communicating with MS SQL Server (the default is 7.3). This is used by pymssql with connecting and fetching data from SQL Server databases. See the [pymssql](https://pymssql.readthedocs.io/en/stable/index.html) documentation and [FreeTDS](https://www.freetds.org/) documentation for more details.\n\n```json\n{\n  "tds_version": "7.3"\n}\n```\n\nOptional:\n\nThe characterset for the database / source system. The default is `utf8`, however older databases might use a charactersets like [cp1252](https://en.wikipedia.org/wiki/Windows-1252) for the encoding. If you have errors with a `UnicodeDecodeError: \'utf-8\' codec can\'t decode byte ....` then a solution is examine the characterset of the source database / system and make an appropriate substitution for utf8 like cp1252.\n\n```json\n{\n  "characterset": "utf8"\n}\n```\n\nThese are the same basic configuration properties used by the mssql command-line\nclient (`mssql`).\n\n### Discovery mode\n\nThe tap can be invoked in discovery mode to find the available tables and\ncolumns in the database:\n\n```bash\n$ tap-mssql --config config.json --discover\n\n```\n\nA discovered catalog is output, with a JSON-schema description of each table. A\nsource table directly corresponds to a Singer stream.\n\n```json\n{\n  "streams": [\n    {\n      "tap_stream_id": "example_db-animals",\n      "table_name": "animals",\n      "schema": {\n        "type": "object",\n        "properties": {\n          "name": {\n            "inclusion": "available",\n            "type": ["null", "string"],\n            "maxLength": 255\n          },\n          "id": {\n            "inclusion": "automatic",\n            "minimum": -2147483648,\n            "maximum": 2147483647,\n            "type": ["null", "integer"]\n          },\n          "likes_getting_petted": {\n            "inclusion": "available",\n            "type": ["null", "boolean"]\n          }\n        }\n      },\n      "metadata": [\n        {\n          "breadcrumb": [],\n          "metadata": {\n            "row-count": 3,\n            "table-key-properties": ["id"],\n            "database-name": "example_db",\n            "selected-by-default": false,\n            "is-view": false\n          }\n        },\n        {\n          "breadcrumb": ["properties", "id"],\n          "metadata": {\n            "sql-datatype": "int(11)",\n            "selected-by-default": true\n          }\n        },\n        {\n          "breadcrumb": ["properties", "name"],\n          "metadata": {\n            "sql-datatype": "varchar(255)",\n            "selected-by-default": true\n          }\n        },\n        {\n          "breadcrumb": ["properties", "likes_getting_petted"],\n          "metadata": {\n            "sql-datatype": "tinyint(1)",\n            "selected-by-default": true\n          }\n        }\n      ],\n      "stream": "animals"\n    }\n  ]\n}\n```\n\n### Field selection\n\nIn sync mode, `tap-mssql` consumes the catalog and looks for tables and fields\nhave been marked as _selected_ in their associated metadata entries.\n\nRedirect output from the tap\'s discovery mode to a file so that it can be\nmodified:\n\n```bash\n$ tap-mssql -c config.json --discover > properties.json\n```\n\nThen edit `properties.json` to make selections. In this example we want the\n`animals` table. The stream\'s metadata entry (associated with `"breadcrumb": []`)\ngets a top-level `selected` flag, as does its columns\' metadata entries. Additionally,\nwe will mark the `animals` table to replicate using a `FULL_TABLE` strategy. For more,\ninformation, see [Replication methods and state file](#replication-methods-and-state-file).\n\n```json\n[\n  {\n    "breadcrumb": [],\n    "metadata": {\n      "row-count": 3,\n      "table-key-properties": ["id"],\n      "database-name": "example_db",\n      "selected-by-default": false,\n      "is-view": false,\n      "selected": true,\n      "replication-method": "FULL_TABLE"\n    }\n  },\n  {\n    "breadcrumb": ["properties", "id"],\n    "metadata": {\n      "sql-datatype": "int(11)",\n      "selected-by-default": true,\n      "selected": true\n    }\n  },\n  {\n    "breadcrumb": ["properties", "name"],\n    "metadata": {\n      "sql-datatype": "varchar(255)",\n      "selected-by-default": true,\n      "selected": true\n    }\n  },\n  {\n    "breadcrumb": ["properties", "likes_getting_petted"],\n    "metadata": {\n      "sql-datatype": "tinyint(1)",\n      "selected-by-default": true,\n      "selected": true\n    }\n  }\n]\n```\n\n### Sync mode\n\nWith a properties catalog that describes field and table selections, the tap can be invoked in sync mode:\n\n```bash\n$ tap-mssql -c config.json --properties properties.json\n```\n\nMessages are written to standard output following the Singer specification. The\nresultant stream of JSON data can be consumed by a Singer target.\n\n```json\n{"value": {"currently_syncing": "example_db-animals"}, "type": "STATE"}\n\n{"key_properties": ["id"], "stream": "animals", "schema": {"properties": {"name": {"inclusion": "available", "maxLength": 255, "type": ["null", "string"]}, "likes_getting_petted": {"inclusion": "available", "type": ["null", "boolean"]}, "id": {"inclusion": "automatic", "minimum": -2147483648, "type": ["null", "integer"], "maximum": 2147483647}}, "type": "object"}, "type": "SCHEMA"}\n\n{"stream": "animals", "version": 1509133344771, "type": "ACTIVATE_VERSION"}\n\n{"record": {"name": "aardvark", "likes_getting_petted": false, "id": 1}, "stream": "animals", "version": 1509133344771, "type": "RECORD"}\n\n{"record": {"name": "bear", "likes_getting_petted": false, "id": 2}, "stream": "animals", "version": 1509133344771, "type": "RECORD"}\n\n{"record": {"name": "cow", "likes_getting_petted": true, "id": 3}, "stream": "animals", "version": 1509133344771, "type": "RECORD"}\n\n{"stream": "animals", "version": 1509133344771, "type": "ACTIVATE_VERSION"}\n\n{"value": {"currently_syncing": "example_db-animals", "bookmarks": {"example_db-animals": {"initial_full_table_complete": true}}}, "type": "STATE"}\n\n{"value": {"currently_syncing": null, "bookmarks": {"example_db-animals": {"initial_full_table_complete": true}}}, "type": "STATE"}\n```\n\n## Replication methods and state file\n\nIn the above example, we invoked `tap-mssql` without providing a _state_ file\nand without specifying a replication method. The three ways to replicate a given\ntable are `FULL_TABLE`, `LOG_BASED`, and `INCREMENTAL`.\n\n### Full Table\n\nFull-table replication extracts all data from the source table each time the tap\nis invoked.\n\n### Log Based\n\nLog_Based replication extracts change data from the MS SQL Server Change Data Capture (CDC) tables you have enrolled.\n\nThis method allows you to replicate just the changes to a table e.g. the Inserts, Deletes, and Updates. For this method to work you\nmust enrol the database in question and tables that you wish to replicate.\n\nSee : https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/enable-and-disable-change-data-capture-sql-server for\nmore details.\n\nPlease Note: CDC is different to Change Tracking which is a older approach for tracking change. Log Based only works with CDC, it does\nnot work with Change Tracking!\n\nTo find out more about setting up CDC, refer to this page [MSSQL CDC Setup](MS_CDC_SETUP.md)\n\n### Incremental\n\nIncremental replication works in conjunction with a state file to only extract\nnew records each time the tap is invoked. This requires a replication key to be\nspecified in the table\'s metadata as well.\n\n#### Example\n\nLet\'s sync the `animals` table again, but this time using incremental\nreplication. The replication method and replication key are set in the\ntable\'s metadata entry in properties file:\n\n```json\n{\n  "streams": [\n    {\n      "tap_stream_id": "example_db-animals",\n      "table_name": "animals",\n      "schema": { ... },\n      "metadata": [\n        {\n          "breadcrumb": [],\n          "metadata": {\n            "row-count": 3,\n            "table-key-properties": [\n              "id"\n            ],\n            "database-name": "example_db",\n            "selected-by-default": false,\n            "is-view": false,\n            "replication-method": "INCREMENTAL",\n            "replication-key": "id"\n          }\n        },\n        ...\n      ],\n      "stream": "animals"\n    }\n  ]\n}\n```\n\nWe have no meaningful state so far, so just invoke the tap in sync mode again\nwithout a state file:\n\n```bash\n$ tap-mssql -c config.json --properties properties.json\n```\n\nThe output messages look very similar to when the table was replicated using the\ndefault `FULL_TABLE` replication method. One important difference is that the\n`STATE` messages now contain a `replication_key_value` -- a bookmark or\nhigh-water mark -- for data that was extracted:\n\n```json\n{"type": "STATE", "value": {"currently_syncing": "example_db-animals"}}\n\n{"stream": "animals", "type": "SCHEMA", "schema": {"type": "object", "properties": {"id": {"type": ["null", "integer"], "minimum": -2147483648, "maximum": 2147483647, "inclusion": "automatic"}, "name": {"type": ["null", "string"], "inclusion": "available", "maxLength": 255}, "likes_getting_petted": {"type": ["null", "boolean"], "inclusion": "available"}}}, "key_properties": ["id"]}\n\n{"stream": "animals", "type": "ACTIVATE_VERSION", "version": 1509135204169}\n\n{"stream": "animals", "type": "RECORD", "version": 1509135204169, "record": {"id": 1, "name": "aardvark", "likes_getting_petted": false}}\n\n{"stream": "animals", "type": "RECORD", "version": 1509135204169, "record": {"id": 2, "name": "bear", "likes_getting_petted": false}}\n\n{"stream": "animals", "type": "RECORD", "version": 1509135204169, "record": {"id": 3, "name": "cow", "likes_getting_petted": true}}\n\n{"type": "STATE", "value": {"bookmarks": {"example_db-animals": {"version": 1509135204169, "replication_key_value": 3, "replication_key": "id"}}, "currently_syncing": "example_db-animals"}}\n\n{"type": "STATE", "value": {"bookmarks": {"example_db-animals": {"version": 1509135204169, "replication_key_value": 3, "replication_key": "id"}}, "currently_syncing": null}}\n```\n\nNote that the final `STATE` message has a `replication_key_value` of `3`,\nreflecting that the extraction ended on a record that had an `id` of `3`.\nSubsequent invocations of the tap will pick up from this bookmark.\n\nNormally, the target will echo the last `STATE` after it\'s finished processing\ndata. For this example, let\'s manually write a `state.json` file using the\n`STATE` message:\n\n```json\n{\n  "bookmarks": {\n    "example_db-animals": {\n      "version": 1509135204169,\n      "replication_key_value": 3,\n      "replication_key": "id"\n    }\n  },\n  "currently_syncing": null\n}\n```\n\nLet\'s add some more animals to our farm:\n\n```\nmssql> insert into animals (name, likes_getting_petted) values (\'dog\', true), (\'elephant\', true), (\'frog\', false);\n```\n\n```bash\n$ tap-mssql -c config.json --properties properties.json --state state.json\n```\n\nThis invocation extracts any data since (and including) the\n`replication_key_value`:\n\n```json\n{"type": "STATE", "value": {"bookmarks": {"example_db-animals": {"replication_key": "id", "version": 1509135204169, "replication_key_value": 3}}, "currently_syncing": "example_db-animals"}}\n\n{"key_properties": ["id"], "schema": {"properties": {"name": {"maxLength": 255, "inclusion": "available", "type": ["null", "string"]}, "id": {"maximum": 2147483647, "minimum": -2147483648, "inclusion": "automatic", "type": ["null", "integer"]}, "likes_getting_petted": {"inclusion": "available", "type": ["null", "boolean"]}}, "type": "object"}, "type": "SCHEMA", "stream": "animals"}\n\n{"type": "ACTIVATE_VERSION", "version": 1509135204169, "stream": "animals"}\n\n{"record": {"name": "cow", "id": 3, "likes_getting_petted": true}, "type": "RECORD", "version": 1509135204169, "stream": "animals"}\n{"record": {"name": "dog", "id": 4, "likes_getting_petted": true}, "type": "RECORD", "version": 1509135204169, "stream": "animals"}\n{"record": {"name": "elephant", "id": 5, "likes_getting_petted": true}, "type": "RECORD", "version": 1509135204169, "stream": "animals"}\n{"record": {"name": "frog", "id": 6, "likes_getting_petted": false}, "type": "RECORD", "version": 1509135204169, "stream": "animals"}\n\n{"type": "STATE", "value": {"bookmarks": {"example_db-animals": {"replication_key": "id", "version": 1509135204169, "replication_key_value": 6}}, "currently_syncing": "example_db-animals"}}\n\n{"type": "STATE", "value": {"bookmarks": {"example_db-animals": {"replication_key": "id", "version": 1509135204169, "replication_key_value": 6}}, "currently_syncing": null}}\n```\n\n---\n\nBased on Stitch documentation\n\n## Build Instructions\n\nThis section dives into basic commands to build `tap-mssql` if an alteration is made to the code.\n\n### Setup Tools\n\nYou may need a copy of setup tools or an up to date version of setup tools to build `tap-mssql`\n\nTo do this follow these instructions.\n\n```bash\n  # Ensure you have first sourced the python virtual environment e.g.\n  source venv/bin/activate\n\n  python -m pip install --upgrade setuptools\n```\n\n### To build the tap\n\nRun the following command each time you need to rebuild the tap.\n\n```bash\n$ python setup.py install\n```\n\n### Debugging in Visual Studio Code\n\nTo run the **init**.py python program in debug mode, you need to do the following two steps. Note: This was run within a Docker Container in Visual Studio Code.\n\n1. Create a .vscode/launch.json file. Note: The parameters config.json and properties.json should point to the files you have generated in previous steps above.\n   If you want to test state, include the state parameter as shown below and prepare an appropriate state file as per the instructions in an earlier section.\n\n```json\n{\n    "version": "0.2.0",\n    "configurations": [\n        {\n            "name": "Python: Program",\n            "type": "python",\n            "request": "launch",\n            "program": "${workspaceRoot}/tap_mssql/__init__.py",\n            "args": [\n                "-c", "config.json",\n                "--properties", "properties.json"\n                "--state", "state.json"\n            ]\n        }\n    ]\n}\n```\n\n2. Add a main entry to the **init**.py file to run interactively\n\nAdd the following lines to the end of the **init**.py in the tap_mssql directory.\n\n```python\n\nif __name__ == \'__main__\':\n    main()  # pylint: disable=no-value-for-parameter\n```\n',
    'author': 'Rob Winters',
    'author_email': 'wintersrd@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://robertwinters.nl',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
