Alien-SVN
view release on metacpan or search on metacpan
src/subversion/build/transform_sql.py view on Meta::CPAN
if match.group(3) == None:
info = 'NULL'
else:
info = '"' + match.group(3) + '"'
self.output.write('#define STMT_%d_INFO {"STMT_%s", %s}\n' %
(self.stmt_count, match.group(1), info))
self.output.write('#define STMT_%d \\\n' % (self.stmt_count,))
self.var_printed = True
self.stmt_count += 1
def _sub_include(self, match):
filepath = os.path.join(self.dirpath, match.group(1) + '.sql')
self.close_define()
self.process_file(open(filepath).read())
def _sub_define(self, match):
define = match.group(1)
self.output.write(' APR_STRINGIFY(%s) \\\n' % define)
def __init__(self, dirpath, output, var_name, token_map):
self.dirpath = dirpath
self.output = output
self.var_name = var_name
self.token_map = token_map
self.stmt_count = 0
self.var_printed = False
self._directives = {
self.re_format : self._sub_format,
self.re_statement : self._sub_statement,
self.re_include : self._sub_include,
self.re_define : self._sub_define,
}
def process_file(self, input):
input = self.re_comments.sub('', input)
for line in input.split('\n'):
line = line.replace('"', '\\"')
# IS_STRICT_DESCENDANT_OF()
# A common operation in the working copy is determining descendants of
# a node. To allow Sqlite to use its indexes to provide the answer we
# must provide simple less than and greater than operations.
#
# For relative paths that consist of one or more components like 'subdir'
# we can accomplish this by comparing local_relpath with 'subdir/' and
# 'subdir0' ('/'+1 = '0')
#
# For the working copy root this case is less simple and not strictly
# valid utf-8/16 (but luckily Sqlite doesn't validate utf-8 nor utf-16).
# The binary blob x'FFFF' is higher than any valid utf-8 and utf-16
# sequence.
#
# So for the root we can compare with > '' and < x'FFFF'. (This skips the
# root itself and selects all descendants)
#
# '/'+1 == '0'
line = re.sub(
r'IS_STRICT_DESCENDANT_OF[(]([A-Za-z_.]+), ([?][0-9]+)[)]',
r"(((\1) > (CASE (\2) WHEN '' THEN '' ELSE (\2) || '/' END))" +
r" AND ((\1) < CASE (\2) WHEN '' THEN X'FFFF' ELSE (\2) || '0' END))",
line)
# RELPATH_SKIP_JOIN(x, y, z) skips the x prefix from z and the joins the
# result after y. In other words it replaces x with y, but follows the
# relpath rules.
line = re.sub(
r'RELPATH_SKIP_JOIN[(]([?]?[A-Za-z0-9_.]+), ' +
r'([?]?[A-Za-z0-9_.]+), ' +
r'([?]?[A-Za-z0-9_.]+)[)]',
r"(CASE WHEN (\1) = '' THEN RELPATH_JOIN(\2, \3) " +
r"WHEN (\2) = '' THEN RELPATH_SKIP_ANCESTOR(\1, \3) " +
r"WHEN SUBSTR((\3), 1, LENGTH(\1)) = (\1) " +
r"THEN " +
r"CASE WHEN LENGTH(\1) = LENGTH(\3) THEN (\2) " +
r"WHEN SUBSTR((\3), LENGTH(\1)+1, 1) = '/' " +
r"THEN (\2) || SUBSTR((\3), LENGTH(\1)+1) " +
r"END " +
r"END)",
line)
# RELPATH_JOIN(x, y) joins x to y following the svn_relpath_join() rules
line = re.sub(
r'RELPATH_JOIN[(]([?]?[A-Za-z0-9_.]+), ([?]?[A-Za-z0-9_.]+)[)]',
r"(CASE WHEN (\1) = '' THEN (\2) " +
r"WHEN (\2) = '' THEN (\1) " +
r"ELSE (\1) || '/' || (\2) " +
r"END)",
line)
# RELPATH_SKIP_ANCESTOR(x, y) skips the x prefix from y following the
# svn_relpath_skip_ancestor() rules. Returns NULL when y is not below X.
line = re.sub(
r'RELPATH_SKIP_ANCESTOR[(]([?]?[A-Za-z0-9_.]+), ' +
r'([?]?[A-Za-z0-9_.]+)[)]',
r"(CASE WHEN (\1) = '' THEN (\2) " +
r" WHEN SUBSTR((\2), 1, LENGTH(\1)) = (\1) " +
r" THEN " +
r"CASE WHEN LENGTH(\1) = LENGTH(\2) THEN '' " +
r"WHEN SUBSTR((\2), LENGTH(\1)+1, 1) = '/' " +
r"THEN SUBSTR((\2), LENGTH(\1)+2) " +
r"END" +
r" END)",
line)
# Another preprocessing.
for symbol, string in self.token_map.iteritems():
# ### This doesn't sql-escape 'string'
line = re.sub(r'\b%s\b' % re.escape(symbol), "'%s'" % string, line)
if line.strip():
handled = False
for regex, handler in self._directives.iteritems():
( run in 0.754 second using v1.01-cache-2.11-cpan-02777c243ea )