--- /dev/null
+#! /usr/bin/env python
+
+"""Find and print out function signatures from .sql file.
+
+Usage:
+ find_sql_functions.py [-h] [-s] [-p PREFIX] FILE ...
+
+Switches:
+ -h Show help
+ -p PREFIX Prefix each line with string
+ -s Check whether function is SECURITY DEFINER
+"""
+
+import sys, re, getopt
+
+rx = r"""
+^
+create \s+ (?: or \s+ replace \s+ )?
+function ( [^(]+ )
+[(] ( [^)]* ) [)]
+"""
+
+rx_secdef = r"""security\s+definer"""
+
+
+rc = re.compile(rx, re.I | re.M | re.X)
+sc = re.compile(r"\s+")
+rc_sec = re.compile(rx_secdef, re.I | re.X)
+
+def grep_file(fn, cf_prefix, cf_secdef):
+ sql = open(fn).read()
+ pos = 0
+ while 1:
+ m = rc.search(sql, pos)
+ if not m:
+ break
+ pos = m.end()
+
+ m2 = rc.search(sql, pos)
+ if m2:
+ xpos = m2.end()
+ else:
+ xpos = len(sql)
+ secdef = False
+ m2 = rc_sec.search(sql, pos, xpos)
+ if m2:
+ secdef = True
+
+ fname = m.group(1).strip()
+ fargs = m.group(2)
+
+ alist = fargs.split(',')
+ tlist = []
+ for a in alist:
+ a = a.strip()
+ toks = sc.split(a.lower())
+ if toks[0] == "out":
+ continue
+ if toks[0] in ("in", "inout"):
+ toks = toks[1:]
+ # just take last item
+ tlist.append(toks[-1])
+
+ sig = "%s(%s)" % (fname, ", ".join(tlist))
+
+ if cf_prefix:
+ ln = "%s %s;" % (cf_prefix, sig)
+ else:
+ ln = " %s(%s)," % (fname, ", ".join(tlist))
+
+ if cf_secdef and secdef:
+ ln = "%-72s -- SECDEF" % (ln)
+
+ print ln
+
+def main(argv):
+ cf_secdef = 0
+ cf_prefix = ''
+
+ try:
+ opts, args = getopt.getopt(argv, "hsp:")
+ except getopt.error, d:
+ print 'getopt:', d
+ sys.exit(1)
+
+ for o, a in opts:
+ if o == '-h':
+ print __doc__
+ sys.exit(0)
+ elif o == '-s':
+ cf_secdef = 1
+ elif o == '-p':
+ cf_prefix = a
+ else:
+ print __doc__
+ sys.exit(1)
+
+ for fn in args:
+ grep_file(fn, cf_prefix, cf_secdef)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
+