82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
|
#!/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()
|
||
|
|