<commit_before>class ColumnError(Exception): pass

class op(object):
	def __repr__(self):
		return self.__class__.__name__
	def __eq__(self, x):
		return isinstance(x, self.__class__)

class EQUAL(op): pass
EQUAL = EQUAL()
class NOTEQUAL(op): pass
NOTEQUAL = NOTEQUAL()
class LESSTHAN(op): pass
LESSTHAN = LESSTHAN()
class LESSEQUAL(op): pass
LESSEQUAL = LESSEQUAL()
class GREATERTHAN(op): pass
GREATERTHAN = GREATERTHAN()
class GREATEREQUAL(op): pass
GREATEREQUAL = GREATEREQUAL()
class ADD(op): pass
ADD = ADD()
class CONCATENATE(op): pass
CONCATENATE = CONCATENATE()
class SUBTRACT(op): pass
SUBTRACT = SUBTRACT()
class MULTIPLY(op): pass
MULTIPLY = MULTIPLY()
class DIVIDE(op): pass
DIVIDE = DIVIDE()
class FLOORDIVIDE(op): pass
FLOORDIVIDE = FLOORDIVIDE()
class MODULO(op): pass
MODULO = MODULO()
class AND(op): pass
AND = AND()
class OR(op): pass
OR = OR()
class NOT(op): pass
NOT = NOT()
class NEGATIVE(op): pass
NEGATIVE = NEGATIVE()
class ABS(op): pass
ABS = ABS()
class LENGTH(op): pass
LENGTH = LENGTH()

class driver_base(object):
	'''Base class for database drivers
	
	This class abstracts away a lot of the logic needed to implement a database
	driver for webdb. Derived classes must overload the following methods to
	have a working driver. If the task is best accomplished using a single SQL
	command, the method ending in '_sql' should be defined, as the alternatives
	use those to accomplish their tasks. For more information, view documentation
	on each specific method
	
	  * list_tables or list_tables_sql
	     - list all tables in the database. Implements: db.conform
	  * list_columns or list_columns_sql
	     - list all columns defined in a table. Implements: db.conform
	  * create_table, create_table_sql, create_table_if_nexists,
	    or create_table_if_nexists_sql
	     - create tables (if missing). Implements: db.__setattr__, db.migrate
	  * rename_table or rename_table_sql.
	     - changes a table's name. Implements: db.migrate
	  * add_column or add_column_sql
	     - adds a new column to a table. Implements: db.migrate
	  * select or select_sql
	     - retrieves rows from a table. Implements: Where.select, table.select
	  * insert or insert_sql
	     - adds rows to a table. Implements: table.insert
	  * update or update_sql
	     - alters records in a table. Implements: Where.update, row.update
	  * delete or delete_sql
	     - removes records from a table. Implements: Where.delete, row.delete,
	       table.__delitem__, table.__delattr__
	
	Additionally, the following variables must be defined.
	
	  * operators: a dictionary mapping operator objects (EQUAL, MULTIPLY, etc.)
	      to functions that format those operations. See drivers/sqlite.py
	  * webdb_types: a dictionary mapping webdb column types to names of database
	      column types. Used for defining tables
	  * driver_types: a dictionary mapping database column types to webdb column
	      types. Used when conforming.
	
	The following methods should be defined by subclasses if the database uses
	non-standard syntax
	
	  * identifier
	     - checks that a table or column name uses valid characters, and is properly
	       escaped (to avoid keywords). Default encloses name in double quotes (")
	  * literal
	     - formats a literal value to be used in an sql expression. 
	  * column_name
	     - returns the name of a column. Default returns dot (.) joined result
	       of identifier on its arguments, i.e. "table"."column" 
	  * format_column
	     - returns a column definition for its Column object argument

	The following methods may be defined by subclasses, but are not required for
	normal use.
	
	  * drop_column or drop_column_sql
	     - removes a column and all its data from a table. Columns in a table
	       which don't appear in a table definition are ignored.
	       Implements: table.drop_column
	'''

	def __init__(self, connection):
		self.connection = connection
		self.depth = 0
		self.cursor = None

	def __enter__(self):
		self.depth += 1
		if self.cursor is None:
			self.cursor = self.connection.cursor()
		return self.cursor
		
	def __exit__(self, obj, exc, tb):
		self.depth -= 1
		if self.depth == 0:
			if obj:
				self.connection.rollback()
			else:
				self.connection.commit()
			self.cursor = None
		
	def execute(self, sql, values=()):
		self.lastsql = sql
		with self as cursor:
			try:
				return cursor.execute(sql, values)
			except sqlite3.OperationalError, e:
				raise Exception(e, sql, values)
		
	def identifier(self, name):
		if not name.replace('_','').isalnum():
			raise ColumnError("Column names can only contain letters, numbers, and underscores. Got %r" % name)
		return '"%s"'%name

	def literal(self, value, cast=None):
		if value is None:
			return 'NULL'
		elif isinstance(value, basestring) or cast in ('TEXT','BLOB'):
			return "'%s'"%str(value).replace("'", "''")
		elif cast in ('INT', 'REAL'):
			return '%g'%value
		else:
			return value
			
	def column_name(self, table, col):
		return '.'.join(map(self.identifier, (table, col)))
	
	def expression(self, x):
		if isinstance(x, list):
			operator = x[0]
			return '(%s)'%self.operators[operator](*map(self.expression,x[1:]))
		elif hasattr(x, 'table') and hasattr(x, 'name'): #Column duck-typed
			return self.column_name(x.table._name, x.name)
		else:
			return self.literal(x)
		
	def parse_where(self, where_clause):
		if where_clause:
			clause = self.expression(where_clause)
			if clause:
				clause = ' WHERE '+clause
		else:
			clause = ''
		return clause
		
	def format_column(self, column):
		return '%(name)s %(type)s%(notnull)s%(default)s' % {
			'name': self.identifier(column.name),
			'type': self.map_type(column.type),
			'notnull': ' NOT NULL' if column.notnull else '',<commit_msg>Where objects can be evaluated by drivers.base.expression<commit_after>class ColumnError(Exception): pass

class op(object):
	def __repr__(self):
		return self.__class__.__name__
	def __eq__(self, x):
		return isinstance(x, self.__class__)

class EQUAL(op): pass
EQUAL = EQUAL()
class NOTEQUAL(op): pass
NOTEQUAL = NOTEQUAL()
class LESSTHAN(op): pass
LESSTHAN = LESSTHAN()
class LESSEQUAL(op): pass
LESSEQUAL = LESSEQUAL()
class GREATERTHAN(op): pass
GREATERTHAN = GREATERTHAN()
class GREATEREQUAL(op): pass
GREATEREQUAL = GREATEREQUAL()
class ADD(op): pass
ADD = ADD()
class CONCATENATE(op): pass
CONCATENATE = CONCATENATE()
class SUBTRACT(op): pass
SUBTRACT = SUBTRACT()
class MULTIPLY(op): pass
MULTIPLY = MULTIPLY()
class DIVIDE(op): pass
DIVIDE = DIVIDE()
class FLOORDIVIDE(op): pass
FLOORDIVIDE = FLOORDIVIDE()
class MODULO(op): pass
MODULO = MODULO()
class AND(op): pass
AND = AND()
class OR(op): pass
OR = OR()
class NOT(op): pass
NOT = NOT()
class NEGATIVE(op): pass
NEGATIVE = NEGATIVE()
class ABS(op): pass
ABS = ABS()
class LENGTH(op): pass
LENGTH = LENGTH()

class driver_base(object):
	'''Base class for database drivers
	
	This class abstracts away a lot of the logic needed to implement a database
	driver for webdb. Derived classes must overload the following methods to
	have a working driver. If the task is best accomplished using a single SQL
	command, the method ending in '_sql' should be defined, as the alternatives
	use those to accomplish their tasks. For more information, view documentation
	on each specific method
	
	  * list_tables or list_tables_sql
	     - list all tables in the database. Implements: db.conform
	  * list_columns or list_columns_sql
	     - list all columns defined in a table. Implements: db.conform
	  * create_table, create_table_sql, create_table_if_nexists,
	    or create_table_if_nexists_sql
	     - create tables (if missing). Implements: db.__setattr__, db.migrate
	  * rename_table or rename_table_sql.
	     - changes a table's name. Implements: db.migrate
	  * add_column or add_column_sql
	     - adds a new column to a table. Implements: db.migrate
	  * select or select_sql
	     - retrieves rows from a table. Implements: Where.select, table.select
	  * insert or insert_sql
	     - adds rows to a table. Implements: table.insert
	  * update or update_sql
	     - alters records in a table. Implements: Where.update, row.update
	  * delete or delete_sql
	     - removes records from a table. Implements: Where.delete, row.delete,
	       table.__delitem__, table.__delattr__
	
	Additionally, the following variables must be defined.
	
	  * operators: a dictionary mapping operator objects (EQUAL, MULTIPLY, etc.)
	      to functions that format those operations. See drivers/sqlite.py
	  * webdb_types: a dictionary mapping webdb column types to names of database
	      column types. Used for defining tables
	  * driver_types: a dictionary mapping database column types to webdb column
	      types. Used when conforming.
	
	The following methods should be defined by subclasses if the database uses
	non-standard syntax
	
	  * identifier
	     - checks that a table or column name uses valid characters, and is properly
	       escaped (to avoid keywords). Default encloses name in double quotes (")
	  * literal
	     - formats a literal value to be used in an sql expression. 
	  * column_name
	     - returns the name of a column. Default returns dot (.) joined result
	       of identifier on its arguments, i.e. "table"."column" 
	  * format_column
	     - returns a column definition for its Column object argument

	The following methods may be defined by subclasses, but are not required for
	normal use.
	
	  * drop_column or drop_column_sql
	     - removes a column and all its data from a table. Columns in a table
	       which don't appear in a table definition are ignored.
	       Implements: table.drop_column
	'''

	def __init__(self, connection):
		self.connection = connection
		self.depth = 0
		self.cursor = None

	def __enter__(self):
		self.depth += 1
		if self.cursor is None:
			self.cursor = self.connection.cursor()
		return self.cursor
		
	def __exit__(self, obj, exc, tb):
		self.depth -= 1
		if self.depth == 0:
			if obj:
				self.connection.rollback()
			else:
				self.connection.commit()
			self.cursor = None
		
	def execute(self, sql, values=()):
		self.lastsql = sql
		with self as cursor:
			try:
				return cursor.execute(sql, values)
			except sqlite3.OperationalError, e:
				raise Exception(e, sql, values)
		
	def identifier(self, name):
		if not name.replace('_','').isalnum():
			raise ColumnError("Column names can only contain letters, numbers, and underscores. Got %r" % name)
		return '"%s"'%name

	def literal(self, value, cast=None):
		if value is None:
			return 'NULL'
		elif isinstance(value, basestring) or cast in ('TEXT','BLOB'):
			return "'%s'"%str(value).replace("'", "''")
		elif cast in ('INT', 'REAL'):
			return '%g'%value
		else:
			return value
			
	def column_name(self, table, col):
		return '.'.join(map(self.identifier, (table, col)))
	
	def expression(self, x):
		if isinstance(x, list):
			operator = x[0]
			return '(%s)'%self.operators[operator](*map(self.expression,x[1:]))
		elif hasattr(x, 'table') and hasattr(x, 'name'): #Column duck-typed
			return self.column_name(x.table._name, x.name)
		elif hasattr(x, '_where_tree'): #Where duck-typed
			return self.expression(x._where_tree)
		else:
			return self.literal(x)
		
	def parse_where(self, where_clause):
		if where_clause:
			clause = self.expression(where_clause)
			if clause:
				clause = ' WHERE '+clause
		else:
			clause = ''
		return clause
		
	def format_column(self, column):
		return '%(name)s %(type)s%(notnull)s%(default)s' % {
			'name': self.identifier(column.name),
			'type': self.map_type(column.type),
			'notnull': ' NOT NULL' if column.notnull else '',
{'fraction_non_alphanumeric': 0.09849332759362893, 'fraction_numerical': 0.0012053379250968575, 'mean_word_length': 3.7219512195121953, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6501121', 'n_tokens_mistral': 3954, 'n_tokens_neox': 3560, 'n_words': 1281}