--- a/pgtoolkit/pgdiff.py Thu Jan 31 11:02:04 2013 +0100
+++ b/pgtoolkit/pgdiff.py Thu Jan 31 13:24:57 2013 +0100
@@ -26,6 +26,10 @@
from pgtoolkit.highlight import *
+from pgtoolkit.colordiff import colordiff
+
+import re
+import difflib
class PgDiffError(Exception):
@@ -134,7 +138,7 @@
class DiffFunction(DiffBase):
- def __init__(self, change, schema, function):
+ def __init__(self, change, schema, function, show_body_diff=False):
DiffBase.__init__(self)
self.level = 1
self.type = 'function'
@@ -142,18 +146,28 @@
self.schema = schema
self.function = function
self.name = function
+ self.show_body_diff = show_body_diff
def _formatchanges(self):
res = []
for x in self.changes:
type, a, b = x
if type == 'source':
- s = 'Changed source.'
+ if self.show_body_diff:
+ lines = ['Source differs:\n']
+ for line in difflib.unified_diff(a, b, lineterm=''):
+ if line[:3] in ('---', '+++'):
+ continue
+ lines.append(line + '\n')
+ diff = ''.join(lines)
+ diff = colordiff(diff)
+ res.append(diff)
+ else:
+ res.append('Source differs.')
else:
- s = ''.join(['Changed ', type, ' from ',
+ res.append(''.join(['Changed ', type, ' from ',
highlight(1,15), a, highlight(0), ' to ',
- highlight(1,15), b, highlight(0), '.'])
- res.append(s)
+ highlight(1,15), b, highlight(0), '.']))
return ' '.join(res)
@@ -249,6 +263,8 @@
self.exclude_schemas = set() # exclude these schemas from diff
self.include_tables = set()
self.exclude_tables = set()
+ self.function_regex = re.compile(r"")
+ self.function_body_diff = False
def _test_schema(self, schema):
if self.include_schemas and schema not in self.include_schemas:
@@ -264,6 +280,9 @@
return False
return True
+ def _test_function(self, function):
+ return bool(self.function_regex.match(function))
+
def _diff_names(self, src, dst):
for x in src:
if x in dst:
@@ -296,8 +315,12 @@
diff = []
if a.result != b.result:
diff.append(('result', a.result, b.result))
- if a.source != b.source:
- diff.append(('source', a.source, b.source))
+ # function source may differ in newlines (\n vs \r\n)
+ # split lines before comparison, so that these differencies are ignored
+ a_source = a.source.splitlines()
+ b_source = b.source.splitlines()
+ if a_source != b_source:
+ diff.append(('source', a_source, b_source))
return diff
def _compare_arguments(self, a, b):
@@ -387,7 +410,9 @@
def _diff_functions(self, schema, src_functions, dst_functions):
for nd in self._diff_names(src_functions, dst_functions):
- fdo = DiffFunction(change=nd[0], schema=schema, function=nd[1])
+ if not self._test_function(nd[1]):
+ continue
+ fdo = DiffFunction(change=nd[0], schema=schema, function=nd[1], show_body_diff=self.function_body_diff)
if nd[0] == '*':
# compare function body and result
a = src_functions[nd[1]]
@@ -492,13 +517,14 @@
self.exclude_schemas.clear()
self.exclude_schemas.update(exclude)
-
def filter_tables(self, include=[], exclude=[]):
self.include_tables.clear()
self.include_tables.update(include)
self.exclude_tables.clear()
self.exclude_tables.update(exclude)
+ def filter_functions(self, regex=''):
+ self.function_regex = re.compile(regex)
def _check_schema_exist(self, schema):
if not schema in self.src.schemas: