"""
A Grammar feeding from an odbc connection.
"""

#c Copyright 2008-2021, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.


from gavo import base
from gavo import utils
from gavo.grammars.common import Grammar, RowIterator

pyodbc = utils.DeferredImport("pyodbc", "import pyodbc")


class ODBCIterator(RowIterator):
	def _iterRows(self):
		with open(self.sourceToken) as f:
			accessToken = f.read().strip()
			conn = pyodbc.connect(accessToken)
		cursor = conn.cursor()
		cursor.execute(self.grammar.query)
		keys = [d[0] for d in cursor.description]
		for row in cursor:
			yield dict(list(zip(keys, row)))


class ODBCGrammar(Grammar):
	"""A grammar that feeds from a remote database.

	This works as a sort of poor man's foreign data wrapper: you pull
	data from a remote database now and then, mogrifying it into whatever
	format you want locally.

	This expects files containing pyodbc connection strings as sources,
	so you'll normally just have one source.  Having the credentials
	externally helps keeping RDs using this safe for public version control.

	An example for an ODBC connection string::

		DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass
	
	See also http://www.connectionstrings.com/

	This will only work if pyodbc (debian: python3-pyodbc) is installed.  
	Additionally, you will have to install the odbc driver corresponding
	to your source database (e.g., odbc-postgresql).
	"""
	name_ = "odbcGrammar"

	_query = base.UnicodeAttribute("query",
		description="The query to run on the remote server.  The keys of"
			" the grammar will be the names of the result columns.",
			copyable=True)
	
	rowIterator = ODBCIterator
