nutools/wofixsql.py

82 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
u"""%(scriptname)s: Afficher une requête SQL d'un fichier de log WebObjects
USAGE
%(scriptname)s 'line'
cat /var/log/WebObjets/App-1 | %(scriptname)s
Les fichiers de logs WebObjects, quand ils contiennent des requêtes SQL, ne sont
pas exploitables directement: la requête et les arguments sont disjoints. Ce
script fusionne la requête et les arguments pour générer une requête SQL
utilisable directement.
Il faut spécifier en argument la ligne complète du fichier de log, e.g.
%(scriptname)s '[2012-11-07 09:58:31 GST]... "SELECT..." withBindings:...'
Sinon, les lignes sont lues depuis l'entrée standard."""
import os, sys, re
from os import path
from ulib.all import *
def display_help():
uprint(__doc__ % globals())
RE_NUMERIC = re.compile('\d+$')
RE_QUOTED = re.compile(r'".*"$')
def fixvalue(v):
if RE_NUMERIC.match(v) is not None:
# Les valeurs numériques sont données telles quelles
return v
if RE_QUOTED.match(v) is not None:
# Les valeurs chaines sont entre guillemets
return "'" + v[1:-1] + "'"
# Sinon, on assume que c'est une date
return "to_date('" + v + "', 'YYYY-MM-DD HH24:MI:SS')"
RE_LINE = re.compile(r'[^"]*"([^"]*)" withBindings: (.*)>')
RE_VAR = re.compile(r'\d+:(.*?)\(\w+\)')
def fixsql(line, raiseerror=True):
mo = RE_LINE.match(line)
if mo is None:
if raiseerror: raise ValueError("%s: Chaine invalide" % line)
else: return None
sql = mo.group(1)
vars = map(fixvalue, RE_VAR.findall(mo.group(2)))
for var in vars:
pos = sql.index('?')
if pos == -1:
if raiseerror: raise ValueError("%s: Chaine invalide (nombre de ? non cohérent)" % line)
else: return None
sql = sql[:pos] + var + sql[pos+1:]
return sql + ';'
def run_wofixsql():
options, longoptions = build_options([
('h', 'help', "Afficher l'aide"),
])
options, args = get_args(None, options, longoptions)
for option, value in options:
if option in ('-h', '--help'):
display_help()
sys.exit(0)
if args:
for arg in args:
print fixsql(arg)
else:
while True:
try: line = raw_input()
except EOFError: break
sql = fixsql(line, False)
if sql is not None: print sql
if __name__ == '__main__':
run_wofixsql()