root/livinglogic.python.xist/src/ll/orasql/scripts/orafind.py @ 4422:fe09ca906d4e

Revision 4422:fe09ca906d4e, 5.2 KB (checked in by Walter Doerwald <walter@…>, 8 years ago)

Bump copyright year. Change encoding of remaining files to UTF-8. Remove trailing whitespace.

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4## Copyright 2005-2011 by LivingLogic AG, Bayreuth/Germany.
5## Copyright 2005-2011 by Walter Dörwald
6##
7## All Rights Reserved
8##
9## See orasql/__init__.py for the license
10
11
12import sys, os, argparse
13
14from ll import misc, orasql, astyle
15
16
17s4warning = astyle.Style.fromenv("LL_ORASQL_REPRANSI_WARNING", "red:black")
18s4error = astyle.Style.fromenv("LL_ORASQL_REPRANSI_ERROR", "red:black")
19s4comment = astyle.Style.fromenv("LL_ORASQL_REPRANSI_COMMENT", "black:black:bold")
20s4addedfile = astyle.Style.fromenv("LL_ORASQL_REPRANSI_ADDEDFILE", "black:green")
21s4addedline = astyle.Style.fromenv("LL_ORASQL_REPRANSI_ADDEDLINE", "green:black")
22s4removedfile = astyle.Style.fromenv("LL_ORASQL_REPRANSI_REMOVEDFILE", "black:red")
23s4removedline = astyle.Style.fromenv("LL_ORASQL_REPRANSI_REMOVEDLINE", "red:black")
24s4changedfile = astyle.Style.fromenv("LL_ORASQL_REPRANSI_CHANGEDFILE", "black:blue")
25s4changedline = astyle.Style.fromenv("LL_ORASQL_REPRANSI_CHANGEDLINE", "blue:black")
26s4pos = astyle.Style.fromenv("LL_ORASQL_REPRANSI_POS", "black:black:bold")
27s4connectstring = astyle.Style.fromenv("LL_ORASQL_REPRANSI_CONNECTSTRING", "yellow:black")
28s4connid = astyle.Style.fromenv("LL_ORASQL_REPRANSI_NOTE", "yellow:black:bold")
29s4action = astyle.Style.fromenv("LL_ORASQL_REPRANSI_NOTE", "magenta:black")
30s4object = astyle.Style.fromenv("LL_ORASQL_REPRANSI_OBJECT", "green:black")
31
32
33
34def cs(connection):
35    return s4connectstring(connection.connectstring())
36
37
38def df(obj):
39    return s4object(str(obj))
40
41
42def connid(name):
43    return s4connid("[{}]".format(name))
44
45
46def showcomment(out, *texts):
47    out.writeln(s4comment("-- ", *texts))
48
49
50def conflictmarker(prefix, *text):
51    return astyle.style_default(s4error(prefix), " ", *text)
52
53
54def showreport(out, type, countcreate, countdrop, countcollision, countmerge, countmergeconflict):
55    first = True
56    data = (("added", countcreate), ("dropped", countdrop), ("collided", countcollision), ("merged", countmerge), ("mergeconflict", countmergeconflict))
57    for (name, count) in data:
58        if count:
59            if first:
60                out.write(" => ")
61                first = False
62            else:
63                out.write("; ")
64            if name in ("collided", "mergeconflict"):
65                cls = s4error
66            else:
67                cls = s4action
68            if count > 1:
69                msg = "{} {}s {}".format(count, type, name)
70            else:
71                msg = "1 {} {}".format(type, name)
72            out.write(cls(msg))
73    if first:
74        out.write(" => identical")
75    out.writeln()
76
77
78def gettimestamp(obj, cursor, format):
79    try:
80        timestamp = obj.udate(cursor)
81    except orasql.SQLObjectNotFoundError:
82        return "doesn't exist"
83    if timestamp is not None:
84        timestamp = timestamp.strftime(format)
85    else:
86        timestamp = "without timestamp"
87    return timestamp
88
89
90def main(args=None):
91    p = argparse.ArgumentParser(description="Search for a string in all fields of all tables in an Oracle database schema")
92    p.add_argument("connectstring", help="Oracle connect string")
93    p.add_argument("searchstring", help="String to search for")
94    p.add_argument("tables", metavar="table", nargs="*", help="Limit search to those tables")
95    p.add_argument("-v", "--verbose", dest="verbose", help="Give a progress report? (default: %(default)s)", action=misc.FlagAction, default=False)
96    p.add_argument("-c", "--color", dest="color", help="Color output (default: %(default)s)", default="auto", choices=("yes", "no", "auto"))
97    p.add_argument("-i", "--ignore-case", dest="ignorecase", help="Ignore case distinctions? (default: %(default)s)", action=misc.FlagAction, default=False)
98    p.add_argument("-r", "--read-lobs", dest="readlobs", help="Read LOBs when printing records? (default: %(default)s)", action=misc.FlagAction, default=False)
99    p.add_argument("-e", "--encoding", dest="encoding", help="Encoding of the command line arguments (default: %(default)s)", default="utf-8")
100
101    args = p.parse_args(args)
102
103    if args.color == "yes":
104        color = True
105    elif args.color == "no":
106        color = False
107    else:
108        color = None
109    stdout = astyle.Stream(sys.stdout, color)
110    stderr = astyle.Stream(sys.stderr, color)
111
112    connectstring = args.connectstring.decode(args.encoding)
113    searchstring = args.searchstring.decode(args.encoding)
114    if args.ignorecase:
115        searchstring = searchstring.lower()
116    searchstring = u"%{}%".format(searchstring.replace(u"%", u"%%"))
117    tablenames = [name.decode(args.encoding).lower() for name in args.tables]
118
119    connection = orasql.connect(connectstring, readlobs=args.readlobs)
120    c = connection.cursor()
121
122    tables = list(connection.itertables())
123    for (i, table) in enumerate(tables):
124        skip = tablenames and table.name.lower() not in tablenames
125        if args.verbose:
126            msg = "skipped" if skip else "searching"
127            stderr.writeln("orafind.py: ", df(table), " #", str(i+1), "/", str(len(tables)), ": ", msg)
128        if not skip:
129            where = []
130            for col in table.itercolumns():
131                datatype = col.datatype()
132                if datatype == "clob" or datatype.startswith("varchar2"):
133                    if args.ignorecase:
134                        where.append("lower({}) like :searchstring".format(col.name))
135                    else:
136                        where.append("{} like :searchstring".format(col.name))
137            if not where:
138                continue # no string columns
139            query = "select * from {} where {}".format(table.name, " or ".join(where))
140            c.execute(query, searchstring=searchstring)
141            for r in c:
142                stdout.writeln("orafind.py: in ", df(table), ": ", repr(r))
143    return 0
144
145
146if __name__ == "__main__":
147    sys.exit(main())
Note: See TracBrowser for help on using the browser.