text: # path: 
  # filename: db.py
  # description: WSGI application MySQL database processors
  ''' 
  # make python2 strings and dictionaries behave like python3
  from __future__ import unicode_literals
  
  try:
  	from builtins import dict, str
  except ImportError:
  	from __builtin__ import dict, str
  	
  	Copyright 2017 Mark Madere
  
  	Licensed under the Apache License, Version 2.0 (the "License");
  	you may not use this file except in compliance with the License.
  	You may obtain a copy of the License at
  
  	http://www.apache.org/licenses/LICENSE-2.0
  
  	Unless required by applicable law or agreed to in writing, software
  	distributed under the License is distributed on an "AS IS" BASIS,
  	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  	See the License for the specific language governing permissions and
  	limitations under the License.
  '''
  
  ''' external imports
  '''
  import oursql
  import re
  
  ''' internal imports
  '''
  import classes.processor
  
  ''' classes
  '''
  class Select(classes.processor.Processor):
  
  	
  	def run(self):
  
  		# vars
  		conf = self.conf
  		debug = False		
  		
  		
  		if conf.get('debug'):
  			
  			print('lib.processors.mysql.Select')
  			debug = True		
  		
  		
  		if not conf.get('conf'):
  		
  			print('Database conf not found')
  			
  			return False
  		
  		if not conf.get('sql'):
  			
  			print('SQL statement not found')
  			
  			return False
  
  		sql = self.content.fnr(conf['sql'])
  
  		# limit
  		if conf.get('limit'):
  			
  			# page
  			conf['page'] = self.content.fnr(conf.get('page',1))
  			if isinstance(conf['page'], str) and not conf['page'].isdigit():
  				conf['page'] = 1
  			
  			conf['page'] = int(conf['page'])	- 1
  			conf['limit'] = int(conf['limit'])
  			
  			sql = "%s LIMIT %d,%d" %(sql, conf['page'] * conf['limit'], int(conf['limit']))
  			
  		# debug
  		if debug:
  			print('sql: %s' %sql.__repr__())
  
  		
  		db_connection = oursql.connect(**conf.get('conf'))
  
  		conf.setdefault('reader','dict')
  		
  		if conf['reader'] == 'list':
  			select = db_connection.cursor()
  		else:
  			select = db_connection.cursor(oursql.DictCursor)
  		
  		try:
  			select.execute(sql)
  			
  			#  store result in element
  			output = select.fetchall()
  			
  			# debug
  			if debug:
  				print(output)
  				
  			# handle the returned data
  			if conf.get('result'):
  				
  				conf['result']['value'] = output
  				
  				if conf['reader'] == 'record':
  					conf['result']['entry'] = '{{0}}'
  				
  				conf['result']['format'] = 'list'
  				
  				# load data
  				if not self.content.load_data(conf['result']):
  					
  					print('failed to save - data failed to load')
  						
  					return False
  			
  			# return false if output is an empty list
  			if not output:
  				return False					
  		
  		except oursql.Error as e:
  			
  			# add mysql errors as content - useful for debugging
  			
  			conf['false'] = {'content': {'value': "MySQL error: %s" %str(e[1])}}
  			
  			print(e)
  			
  			return False
  			
  		return True
  	
  
  class Insert(classes.processor.Processor):
  
  	
  	def run(self):
  		
  		# vars
  		conf = self.conf
  		debug = False		
  		
  		
  		if conf.get('debug'):
  			
  			print('lib.processors.mysql.Insert')
  			debug = True		
  		
  		
  		if not conf.get('conf'):
  		
  			print('Database conf not found')
  			
  			return False
  		
  		if not conf.get('sql'):
  			
  			print('SQL statement not found')
  			
  			return False
  
  		sql = self.content.fnr(conf['sql'])
  		
  		# clean remaining markers in sql
  		if not conf.get('keepmarkers'):
  			pattern = re.compile(r'({{[\w|\(|\)|\.|\:|\-]+}})')
  			markers = list(set(pattern.findall(sql)))
  
  			for marker in markers:
  				sql = unicode(sql.replace(marker,''))			
  			
  		
  		# debug
  		if debug:
  			print('sql: %s' %sql.__repr__())
  		
  		db_connection = oursql.connect(**conf.get('conf'))
  		insert = db_connection.cursor()
  		
  		try:
  			insert.execute(sql, plain_query=True)
  			
  			if self.conf.get('cache_id'):
  				self.top.cache[self.conf['cache_id']] = insert.lastrowid
  			
  			return True
  
  
  		except oursql.Error as e:
  			
  			print(e)
  			
  			# we could possibly add content here
  			
  			self.conf['false'] = {'content': {'value': "MySQL error: %s" %str(e[1])}}
  			
  			return False
  			
  			
  class Update(Insert):
  	
  	''' Same as insert.
  	'''
  	pass
  