annotate sqlpython/sqlpyPlus.py @ 248:230447ce6e60

end wed
author catherine@dellzilla
date Tue, 10 Mar 2009 16:42:27 -0400
parents f0f293d83337
children 9e3e49c95abf
rev   line source
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1 """sqlpyPlus - extra features (inspired by Oracle SQL*Plus) for Luca Canali's sqlpython.py
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
2
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
3 Features include:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
4 - SQL*Plus-style bind variables
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
5 - `set autobind on` stores single-line result sets in bind variables automatically
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
6 - SQL buffer with list, run, ed, get, etc.; unlike SQL*Plus, buffer stores session's full history
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
7 - @script.sql loads and runs (like SQL*Plus)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
8 - ! runs operating-system command
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
9 - show and set to control sqlpython parameters
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
10 - SQL*Plus-style describe, spool
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
11 - write sends query result directly to file
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
12 - comments shows table and column comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
13 - compare ... to ... graphically compares results of two queries
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
14 - commands are case-insensitive
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
15 - context-sensitive tab-completion for table names, column names, etc.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
16
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
17 Use 'help' within sqlpython for details.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
18
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
19 Set bind variables the hard (SQL*Plus) way
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
20 exec :b = 3
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
21 or with a python-like shorthand
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
22 :b = 3
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
23
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
24 - catherinedevlin.blogspot.com May 31, 2006
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
25 """
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
26 import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion, datetime, pickle, binascii, subprocess
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
27 from cmd2 import Cmd, make_option, options, Statekeeper, Cmd2TestCase
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
28 from output_templates import output_templates
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
29 from plothandler import Plot
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
30 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
31 import pylab
198
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
32 except (RuntimeError, ImportError):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
33 pass
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
34
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
35 descQueries = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
36 'TABLE': ("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
37 SELECT atc.column_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
38 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?",
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
39 atc.data_type ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
40 CASE atc.data_type WHEN 'DATE' THEN ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
41 ELSE '(' ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
42 CASE atc.data_type WHEN 'NUMBER' THEN TO_CHAR(atc.data_precision) ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
43 CASE atc.data_scale WHEN 0 THEN ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
44 ELSE ',' || TO_CHAR(atc.data_scale) END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
45 ELSE TO_CHAR(atc.data_length) END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
46 END ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
47 CASE atc.data_type WHEN 'DATE' THEN '' ELSE ')' END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
48 data_type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
49 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
50 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
51 AND atc.owner = :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
52 ORDER BY atc.column_id;""",),
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
53 'PROCEDURE': ("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
54 SELECT NVL(argument_name, 'Return Value') argument_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
55 data_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
56 in_out,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
57 default_value
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
58 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
59 WHERE object_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
60 AND owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
61 AND package_name IS NULL
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
62 ORDER BY sequence;""",),
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
63 'PackageObjects':("""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
64 SELECT DISTINCT object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
65 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
66 WHERE package_name = :package_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
67 AND owner = :owner""",),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
68 'PackageObjArgs':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
69 SELECT object_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
70 argument_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
71 data_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
72 in_out,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
73 default_value
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
74 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
75 WHERE package_name = :package_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
76 AND object_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
77 AND owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
78 AND argument_name IS NOT NULL
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
79 ORDER BY sequence;""",),
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
80 'TRIGGER':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
81 SELECT description
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
82 FROM all_triggers
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
83 WHERE owner = :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
84 AND trigger_name = :object_name;
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
85 """,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
86 """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
87 SELECT table_owner,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
88 base_object_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
89 table_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
90 column_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
91 when_clause,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
92 status,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
93 action_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
94 crossedition
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
95 FROM all_triggers
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
96 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
97 AND trigger_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
98 \\t
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
99 """,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
100 ),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
101 'INDEX':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
102 SELECT index_type,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
103 table_owner,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
104 table_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
105 table_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
106 uniqueness,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
107 compression,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
108 partitioned,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
109 temporary,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
110 generated,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
111 secondary,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
112 dropped,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
113 visibility
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
114 FROM all_indexes
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
115 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
116 AND index_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
117 \\t
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
118 """,)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
119 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
120 descQueries['VIEW'] = descQueries['TABLE']
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
121 descQueries['FUNCTION'] = descQueries['PROCEDURE']
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
122
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
123 queries = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
124 'resolve': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
125 SELECT object_type, object_name, owner FROM (
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
126 SELECT object_type, object_name, user owner, 1 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
127 FROM user_objects
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
128 WHERE object_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
129 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
130 SELECT ao.object_type, ao.object_name, ao.owner, 2 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
131 FROM all_objects ao
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
132 JOIN user_synonyms us ON (us.table_owner = ao.owner AND us.table_name = ao.object_name)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
133 WHERE us.synonym_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
134 AND ao.object_type != 'SYNONYM'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
135 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
136 SELECT ao.object_type, ao.object_name, ao.owner, 3 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
137 FROM all_objects ao
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
138 JOIN all_synonyms asyn ON (asyn.table_owner = ao.owner AND asyn.table_name = ao.object_name)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
139 WHERE asyn.synonym_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
140 AND ao.object_type != 'SYNONYM'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
141 AND asyn.owner = 'PUBLIC'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
142 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
143 SELECT 'DIRECTORY' object_type, dir.directory_name, dir.owner, 6 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
144 FROM all_directories dir
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
145 WHERE dir.directory_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
146 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
147 SELECT 'DATABASE LINK' object_type, db_link, owner, 7 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
148 FROM all_db_links dbl
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
149 WHERE dbl.db_link = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
150 ) ORDER BY priority ASC,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
151 length(object_type) ASC,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
152 object_type DESC""", # preference: PACKAGE before PACKAGE BODY, TABLE before INDEX
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
153 'tabComments': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
154 SELECT comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
155 FROM all_tab_comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
156 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
157 AND table_name = :table_name""",
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
158 'colComments': """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
159 SELECT
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
160 atc.column_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
161 acc.comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
162 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
163 JOIN all_col_comments acc ON (atc.owner = acc.owner and atc.table_name = acc.table_name and atc.column_name = acc.column_name)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
164 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
165 AND atc.owner = :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
166 ORDER BY atc.column_id;""",
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
167 'oneColComments': """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
168 SELECTatc.column_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
169 acc.comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
170 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
171 JOIN all_col_comments acc ON (atc.owner = acc.owner and atc.table_name = acc.table_name and atc.column_name = acc.column_name)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
172 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
173 AND atc.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
174 AND acc.column_name = :column_name
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
175 ORDER BY atc.column_id;""",
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
176 #thanks to Senora.pm for "refs"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
177 'refs': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
178 NULL referenced_by,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
179 c2.table_name references,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
180 c1.constraint_name constraint
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
181 FROM
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
182 user_constraints c1,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
183 user_constraints c2
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
184 WHERE
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
185 c1.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
186 and c1.constraint_type ='R'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
187 and c1.r_constraint_name = c2.constraint_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
188 and c1.r_owner = c2.owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
189 and c1.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
190 UNION
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
191 SELECT c1.table_name referenced_by,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
192 NULL references,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
193 c1.constraint_name constraint
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
194 FROM
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
195 user_constraints c1,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
196 user_constraints c2
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
197 WHERE
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
198 c2.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
199 and c1.constraint_type ='R'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
200 and c1.r_constraint_name = c2.constraint_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
201 and c1.r_owner = c2.owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
202 and c1.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
203 """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
204 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
205
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
206 if float(sys.version[:3]) < 2.3:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
207 def enumerate(lst):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
208 return zip(range(len(lst)), lst)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
209
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
210 class SoftwareSearcher(object):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
211 def __init__(self, softwareList, purpose):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
212 self.softwareList = softwareList
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
213 self.purpose = purpose
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
214 self.software = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
215 def invoke(self, *args):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
216 if not self.software:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
217 (self.software, self.invokeString) = self.find()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
218 argTuple = tuple([self.software] + list(args))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
219 os.system(self.invokeString % argTuple)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
220 def find(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
221 if self.purpose == 'text editor':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
222 software = os.environ.get('EDITOR')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
223 if software:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
224 return (software, '%s %s')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
225 for (n, (software, invokeString)) in enumerate(self.softwareList):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
226 if os.path.exists(software):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
227 if n > (len(self.softwareList) * 0.7):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
228 print """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
229
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
230 Using %s. Note that there are better options available for %s,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
231 but %s couldn't find a better one in your PATH.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
232 Feel free to open up %s
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
233 and customize it to find your favorite %s program.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
234
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
235 """ % (software, self.purpose, __file__, __file__, self.purpose)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
236 return (software, invokeString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
237 stem = os.path.split(software)[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
238 for p in os.environ['PATH'].split(os.pathsep):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
239 if os.path.exists(os.sep.join([p, stem])):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
240 return (stem, invokeString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
241 raise (OSError, """Could not find any %s programs. You will need to install one,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
242 or customize %s to make it aware of yours.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
243 Looked for these programs:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
244 %s""" % (self.purpose, __file__, "\n".join([s[0] for s in self.softwareList])))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
245 #v2.4: %s""" % (self.purpose, __file__, "\n".join(s[0] for s in self.softwareList)))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
246
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
247 softwareLists = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
248 'diff/merge': [
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
249 ('/usr/bin/meld',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
250 ('/usr/bin/kdiff3',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
251 (r'C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe','"%s" %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
252 (r'C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe', '"%s" /base:"%s" /mine:"%s"'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
253 ('FileMerge','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
254 ('kompare','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
255 ('WinMerge','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
256 ('xxdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
257 ('fldiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
258 ('gtkdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
259 ('tkdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
260 ('gvimdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
261 ('diff',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
262 (r'c:\windows\system32\comp.exe',"%s %s %s")],
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
263 'text editor': [
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
264 ('gedit', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
265 ('textpad', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
266 ('notepad.exe', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
267 ('pico', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
268 ('emacs', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
269 ('vim', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
270 ('vi', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
271 ('ed', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
272 ('edlin', '%s %s')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
273 ]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
274 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
275
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
276 diffMergeSearcher = SoftwareSearcher(softwareLists['diff/merge'],'diff/merge')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
277 editSearcher = SoftwareSearcher(softwareLists['text editor'], 'text editor')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
278 editor = os.environ.get('EDITOR')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
279 if editor:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
280 editSearcher.find = lambda: (editor, "%s %s")
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
281
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
282 class CaselessDict(dict):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
283 """dict with case-insensitive keys.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
284
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
285 Posted to ASPN Python Cookbook by Jeff Donner - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66315"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
286 def __init__(self, other=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
287 if other:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
288 # Doesn't do keyword args
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
289 if isinstance(other, dict):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
290 for k,v in other.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
291 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
292 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
293 for k,v in other:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
294 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
295 def __getitem__(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
296 return dict.__getitem__(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
297 def __setitem__(self, key, value):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
298 dict.__setitem__(self, key.lower(), value)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
299 def __contains__(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
300 return dict.__contains__(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
301 def has_key(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
302 return dict.has_key(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
303 def get(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
304 return dict.get(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
305 def setdefault(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
306 return dict.setdefault(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
307 def update(self, other):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
308 for k,v in other.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
309 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
310 def fromkeys(self, iterable, value=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
311 d = CaselessDict()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
312 for k in iterable:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
313 dict.__setitem__(d, k.lower(), value)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
314 return d
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
315 def pop(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
316 return dict.pop(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
317
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
318 class Parser(object):
246
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
319 #comment_def = "--" + pyparsing.ZeroOrMore(pyparsing.CharsNotIn("\n"))
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
320 comment_def = "--" + ~ ('-' + pyparsing.CaselessKeyword('begin')) + pyparsing.ZeroOrMore(pyparsing.CharsNotIn("\n"))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
321 def __init__(self, scanner, retainSeparator=True):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
322 self.scanner = scanner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
323 self.scanner.ignore(pyparsing.sglQuotedString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
324 self.scanner.ignore(pyparsing.dblQuotedString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
325 self.scanner.ignore(self.comment_def)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
326 self.scanner.ignore(pyparsing.cStyleComment)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
327 self.retainSeparator = retainSeparator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
328 def separate(self, txt):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
329 itms = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
330 for (sqlcommand, start, end) in self.scanner.scanString(txt):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
331 if sqlcommand:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
332 if type(sqlcommand[0]) == pyparsing.ParseResults:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
333 if self.retainSeparator:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
334 itms.append("".join(sqlcommand[0]))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
335 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
336 itms.append(sqlcommand[0][0])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
337 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
338 if sqlcommand[0]:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
339 itms.append(sqlcommand[0])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
340 return itms
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
341
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
342 bindScanner = Parser(pyparsing.Literal(':') + pyparsing.Word( pyparsing.alphanums + "_$#" ))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
343
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
344 def findBinds(target, existingBinds, givenBindVars = {}):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
345 result = givenBindVars
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
346 for finding, startat, endat in bindScanner.scanner.scanString(target):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
347 varname = finding[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
348 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
349 result[varname] = existingBinds[varname]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
350 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
351 if not givenBindVars.has_key(varname):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
352 print 'Bind variable %s not defined.' % (varname)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
353 return result
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
354
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
355 class sqlpyPlus(sqlpython.sqlpython):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
356 defaultExtension = 'sql'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
357 sqlpython.sqlpython.shortcuts.update({':': 'setbind',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
358 '\\': 'psql',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
359 '@': '_load'})
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
360 multilineCommands = '''select insert update delete tselect
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
361 create drop alter _multiline_comment'''.split()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
362 sqlpython.sqlpython.noSpecialParse.append('spool')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
363 commentGrammars = pyparsing.Or([pyparsing.Literal('--') + pyparsing.restOfLine, pyparsing.cStyleComment])
246
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
364 commentGrammars = pyparsing.Or([Parser.comment_def, pyparsing.cStyleComment])
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
365 default_file_name = 'afiedt.buf'
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
366 def __init__(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
367 sqlpython.sqlpython.__init__(self)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
368 self.binds = CaselessDict()
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
369 self.settable += 'autobind commit_on_exit maxfetch maxtselctrows timeout heading wildsql'.split()
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
370 self.settable.remove('case_insensitive')
230
e1e6b820f81b improving ambiguous SETs
catherine@dellzilla
parents: 229
diff changeset
371 self.settable.sort()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
372 self.stdoutBeforeSpool = sys.stdout
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
373 self.spoolFile = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
374 self.autobind = False
229
411f78dc1e07 accept SET HEADING
catherine@dellzilla
parents: 228
diff changeset
375 self.heading = True
240
6d9a65b442b5 negative wildcards fixed
catherine@Elli.myhome.westell.com
parents: 239
diff changeset
376 self.wildsql = False
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
377
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
378 # overrides cmd's parseline
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
379 def parseline(self, line):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
380 """Parse the line into a command name and a string containing
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
381 the arguments. Returns a tuple containing (command, args, line).
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
382 'command' and 'args' may be None if the line couldn't be parsed.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
383 Overrides cmd.cmd.parseline to accept variety of shortcuts.."""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
384
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
385 cmd, arg, line = sqlpython.sqlpython.parseline(self, line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
386 if cmd in ('select', 'sleect', 'insert', 'update', 'delete', 'describe',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
387 'desc', 'comments', 'pull', 'refs', 'desc', 'triggers', 'find') \
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
388 and not hasattr(self, 'curs'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
389 print 'Not connected.'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
390 return '', '', ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
391 return cmd, arg, line
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
392
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
393 do__load = Cmd.do_load
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
394
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
395 def do_remark(self, line):
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
396 '''
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
397 REMARK is one way to denote a comment in SQL*Plus.
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
398
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
399 Wrapping a *single* SQL or PL/SQL statement in `REMARK BEGIN` and `REMARK END`
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
400 tells sqlpython to submit the enclosed code directly to Oracle as a single
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
401 unit of code.
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
402
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
403 Without these markers, sqlpython fails to properly distinguish the beginning
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
404 and end of all but the simplest PL/SQL blocks, causing errors. sqlpython also
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
405 slows down when parsing long SQL statements as it tries to determine whether
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
406 the statement has ended yet; `REMARK BEGIN` and `REMARK END` allow it to skip this
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
407 parsing.
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
408
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
409 Standard SQL*Plus interprets REMARK BEGIN and REMARK END as comments, so it is
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
410 safe to include them in SQL*Plus scripts.
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
411 '''
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
412 if not line.lower().strip().startswith('begin'):
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
413 return
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
414 statement = []
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
415 next = self.pseudo_raw_input(self.continuation_prompt)
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
416 while next.lower().split()[:2] != ['remark','end']:
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
417 statement.append(next)
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
418 next = self.pseudo_raw_input(self.continuation_prompt)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
419 return self.onecmd('\n'.join(statement))
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
420
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
421 def onecmd_plus_hooks(self, line):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
422 line = self.precmd(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
423 stop = self.onecmd(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
424 stop = self.postcmd(stop, line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
425
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
426 def do_shortcuts(self,arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
427 """Lists available first-character shortcuts
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
428 (i.e. '!dir' is equivalent to 'shell dir')"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
429 for (scchar, scto) in self.shortcuts.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
430 print '%s: %s' % (scchar, scto)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
431
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
432 def colnames(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
433 return [d[0] for d in curs.description]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
434
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
435 def sql_format_itm(self, itm, needsquotes):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
436 if itm is None:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
437 return 'NULL'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
438 if needsquotes:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
439 return "'%s'" % str(itm)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
440 return str(itm)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
441 tableNameFinder = re.compile(r'from\s+([\w$#_"]+)', re.IGNORECASE | re.MULTILINE | re.DOTALL)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
442 inputStatementFormatters = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
443 cx_Oracle.STRING: "'%s'",
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
444 cx_Oracle.DATETIME: "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')"}
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
445 inputStatementFormatters[cx_Oracle.CLOB] = inputStatementFormatters[cx_Oracle.STRING]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
446 inputStatementFormatters[cx_Oracle.TIMESTAMP] = inputStatementFormatters[cx_Oracle.DATETIME]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
447 def output(self, outformat, rowlimit):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
448 self.tblname = self.tableNameFinder.search(self.curs.statement).group(1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
449 self.colnames = [d[0] for d in self.curs.description]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
450 if outformat in output_templates:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
451 self.colnamelen = max(len(colname) for colname in self.colnames)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
452 self.coltypes = [d[1] for d in self.curs.description]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
453 self.formatters = [self.inputStatementFormatters.get(typ, '%s') for typ in self.coltypes]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
454 result = output_templates[outformat].generate(**self.__dict__)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
455 elif outformat == '\\t': # transposed
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
456 rows = [self.colnames]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
457 rows.extend(list(self.rows))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
458 transpr = [[rows[y][x] for y in range(len(rows))]for x in range(len(rows[0]))] # matrix transpose
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
459 newdesc = [['ROW N.'+str(y),10] for y in range(len(rows))]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
460 for x in range(len(self.curs.description)):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
461 if str(self.curs.description[x][1]) == "<type 'cx_Oracle.BINARY'>": # handles RAW columns
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
462 rname = transpr[x][0]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
463 transpr[x] = map(binascii.b2a_hex, transpr[x])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
464 transpr[x][0] = rname
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
465 newdesc[0][0] = 'COLUMN NAME'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
466 result = '\n' + sqlpython.pmatrix(transpr,newdesc)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
467 elif outformat in ('\\l', '\\L', '\\p', '\\b'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
468 plot = Plot()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
469 plot.build(self, outformat)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
470 plot.shelve()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
471 plot.draw()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
472 return ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
473 else:
229
411f78dc1e07 accept SET HEADING
catherine@dellzilla
parents: 228
diff changeset
474 result = sqlpython.pmatrix(self.rows, self.curs.description, self.maxfetch, heading=self.heading)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
475 return result
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
476
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
477 legalOracle = re.compile('[a-zA-Z_$#]')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
478
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
479 def select_scalar_list(self, sql, binds={}):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
480 self.curs.execute(sql, binds)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
481 return [r[0] for r in self.curs.fetchall()]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
482
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
483 columnNameRegex = re.compile(
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
484 r'select\s+(.*)from',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
485 re.IGNORECASE | re.DOTALL | re.MULTILINE)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
486 def completedefault(self, text, line, begidx, endidx):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
487 segment = completion.whichSegment(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
488 text = text.upper()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
489 completions = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
490 if segment == 'select':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
491 stmt = "SELECT column_name FROM user_tab_columns WHERE column_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
492 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
493 if not completions:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
494 stmt = "SELECT column_name FROM all_tab_columns WHERE column_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
495 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
496 if segment == 'from':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
497 columnNames = self.columnNameRegex.search(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
498 if columnNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
499 columnNames = columnNames.group(1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
500 columnNames = [c.strip().upper() for c in columnNames.split(',')]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
501 stmt1 = "SELECT table_name FROM all_tab_columns WHERE column_name = '%s' AND table_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
502 for columnName in columnNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
503 # and if columnName is * ?
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
504 completions.extend(self.select_scalar_list(stmt1 % (columnName, text)))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
505 if segment in ('from', 'update', 'insert into') and (not completions):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
506 stmt = "SELECT table_name FROM user_tables WHERE table_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
507 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
508 if not completions:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
509 stmt = """SELECT table_name FROM user_tables WHERE table_name LIKE '%s%%'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
510 UNION
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
511 SELECT DISTINCT owner FROM all_tables WHERE owner LIKE '%%%s'"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
512 completions = self.select_scalar_list(stmt % (text, text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
513 if segment in ('where', 'group by', 'order by', 'having', 'set'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
514 tableNames = completion.tableNamesFromFromClause(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
515 if tableNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
516 stmt = """SELECT column_name FROM all_tab_columns
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
517 WHERE table_name IN (%s)""" % \
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
518 (','.join("'%s'" % (t) for t in tableNames))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
519 stmt = "%s AND column_name LIKE '%s%%'" % (stmt, text)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
520 completions = self.select_scalar_list(stmt)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
521 if not segment:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
522 stmt = "SELECT object_name FROM all_objects WHERE object_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
523 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
524 return completions
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
525
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
526 columnlistPattern = pyparsing.SkipTo(pyparsing.CaselessKeyword('from'))('columns') + \
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
527 pyparsing.SkipTo(pyparsing.stringEnd)('remainder')
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
528
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
529 negator = pyparsing.Literal('!')('exclude')
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
530 colNumber = pyparsing.Optional(negator) + pyparsing.Literal('#') + pyparsing.Word('-' + pyparsing.nums, pyparsing.nums)('column_number')
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
531 colName = negator + pyparsing.Word('$_#' + pyparsing.alphas, '$_#' + pyparsing.alphanums)('column_name')
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
532 wildColName = pyparsing.Optional(negator) + pyparsing.Word('?*%$_#' + pyparsing.alphas, '?*%$_#' + pyparsing.alphanums, min=2)('column_name')
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
533 colNumber.ignore(pyparsing.cStyleComment).ignore(Parser.comment_def). \
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
534 ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString)
235
8e5f58d504d4 tightening up wildcard pyparsing
catherine@dellzilla
parents: 234
diff changeset
535 wildSqlParser = colNumber ^ colName ^ wildColName
8e5f58d504d4 tightening up wildcard pyparsing
catherine@dellzilla
parents: 234
diff changeset
536 wildSqlParser.ignore(pyparsing.cStyleComment).ignore(Parser.comment_def). \
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
537 ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
538 emptyCommaRegex = re.compile(',\s*,', re.DOTALL)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
539 deadStarterCommaRegex = re.compile('^\s*,', re.DOTALL)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
540 deadEnderCommaRegex = re.compile(',\s*$', re.DOTALL)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
541 def expandWildSql(self, arg):
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
542 try:
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
543 columnlist = self.columnlistPattern.parseString(arg)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
544 except pyparsing.ParseException:
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
545 return arg
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
546 parseresults = list(self.wildSqlParser.scanString(columnlist.columns))
239
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
547 # I would rather exclude non-wild column names in the grammar,
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
548 # but can't figure out how
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
549 parseresults = [p for p in parseresults if
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
550 p[0].column_number or
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
551 '*' in p[0].column_name or
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
552 '%' in p[0].column_name or
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
553 '?' in p[0].column_name or
239
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
554 p[0].exclude]
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
555 if not parseresults:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
556 return arg
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
557 self.curs.execute('select * ' + columnlist.remainder, self.varsUsed)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
558 columns_available = [d[0] for d in self.curs.description]
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
559 replacers = {}
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
560 included = set()
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
561 excluded = set()
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
562 for (col, startpos, endpos) in parseresults:
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
563 replacers[arg[startpos:endpos]] = []
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
564 if col.column_name:
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
565 finder = col.column_name.replace('*','.*')
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
566 finder = finder.replace('%','.*')
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
567 finder = finder.replace('?','.')
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
568 colnames = [c for c in columns_available if re.match(finder + '$', c, re.IGNORECASE)]
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
569 elif col.column_number:
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
570 idx = int(col.column_number)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
571 if idx > 0:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
572 idx -= 1
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
573 colnames = [columns_available[idx]]
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
574 if not colnames:
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
575 print 'No columns found matching criteria.'
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
576 return 'null from dual'
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
577 for colname in colnames:
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
578 if col.exclude:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
579 included.discard(colname)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
580 include_here = columns_available[:]
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
581 include_here.remove(colname)
240
6d9a65b442b5 negative wildcards fixed
catherine@Elli.myhome.westell.com
parents: 239
diff changeset
582 replacers[arg[startpos:endpos]].extend(i for i in include_here if i not in replacers[arg[startpos:endpos]])
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
583 excluded.add(colname)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
584 else:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
585 excluded.discard(colname)
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
586 replacers[arg[startpos:endpos]].append(colname)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
587
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
588 replacers = sorted(replacers.items(), key=len, reverse=True)
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
589 result = columnlist.columns
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
590 for (target, replacement) in replacers:
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
591 cols = [r for r in replacement if r not in excluded and r not in included]
238
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
592 replacement = ', '.join(cols)
254fb9d3f4c3 must fix catching regular cols as wilds, repeating on eqdbw/mtndew@orcl
catherine@Elli.myhome.westell.com
parents: 237
diff changeset
593 included.update(cols)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
594 result = result.replace(target, replacement)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
595 # some column names could get wiped out completely, so we fix their dangling commas
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
596 result = self.emptyCommaRegex.sub(',', result)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
597 result = self.deadStarterCommaRegex.sub('', result)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
598 result = self.deadEnderCommaRegex.sub('', result)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
599 if not result.strip():
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
600 print 'No columns found matching criteria.'
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
601 return 'null from dual'
237
95070e01907d not col num works
catherine@Elli.myhome.westell.com
parents: 236
diff changeset
602 return result + ' ' + columnlist.remainder
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
603
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
604 rowlimitPattern = pyparsing.Word(pyparsing.nums)('rowlimit')
204
1c3df79fd088 \n\n finally works
catherine@dellzilla
parents: 203
diff changeset
605 terminators = '; \\C \\t \\i \\p \\l \\L \\b '.split() + output_templates.keys()
199
09592342a33d ugh - parsing stripping command causes real trouble
catherine@dellzilla
parents: 198
diff changeset
606
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
607 def do_select(self, arg, bindVarsIn=None, terminator=None):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
608 """Fetch rows from a table.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
609
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
610 Limit the number of rows retrieved by appending
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
611 an integer after the terminator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
612 (example: SELECT * FROM mytable;10 )
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
613
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
614 Output may be formatted by choosing an alternative terminator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
615 ("help terminators" for details)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
616 """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
617 bindVarsIn = bindVarsIn or {}
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
618 try:
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
619 rowlimit = int(arg.parsed.suffix or 0)
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
620 except ValueError:
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
621 rowlimit = 0
206
ed46f2dba929 fixed sessinfo
catherine@Elli.myhome.westell.com
parents: 204
diff changeset
622 print "Specify desired number of rows after terminator (not '%s')" % arg.parsed.suffix
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
623 self.varsUsed = findBinds(arg, self.binds, bindVarsIn)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
624 if self.wildsql:
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
625 selecttext = self.expandWildSql(arg)
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
626 else:
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
627 selecttext = arg
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
628 self.curs.execute('select ' + selecttext, self.varsUsed)
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
629 self.rows = self.curs.fetchmany(min(self.maxfetch, (rowlimit or self.maxfetch)))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
630 self.rc = self.curs.rowcount
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
631 if self.rc > 0:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
632 self.stdout.write('\n%s\n' % (self.output(arg.parsed.terminator, rowlimit)))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
633 if self.rc == 0:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
634 print '\nNo rows Selected.\n'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
635 elif self.rc == 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
636 print '\n1 row selected.\n'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
637 if self.autobind:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
638 self.binds.update(dict(zip([''.join(l for l in d[0] if l.isalnum()) for d in self.curs.description], self.rows[0])))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
639 for (i, val) in enumerate(self.rows[0]):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
640 varname = ''.join(letter for letter in self.curs.description[i][0] if letter.isalnum() or letter == '_')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
641 self.binds[varname] = val
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
642 self.binds[str(i+1)] = val
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
643 elif self.rc < self.maxfetch:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
644 print '\n%d rows selected.\n' % self.rc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
645 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
646 print '\nSelected Max Num rows (%d)' % self.rc
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
647
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
648 def do_cat(self, arg):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
649 '''Shortcut for SELECT * FROM'''
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
650 return self.do_select(self.parsed('SELECT * FROM %s;' % arg,
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
651 terminator = arg.parsed.terminator or ';',
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
652 suffix = arg.parsed.suffix))
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
653
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
654 def _pull(self, arg, opts, vc=None):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
655 """Displays source code."""
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
656 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
657 statekeeper = Statekeeper(self, ('stdout',))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
658 try:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
659 for (owner, object_type, object_name) in self.resolve_many(arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
660 if object_type in self.supported_ddl_types:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
661 object_type = {'DATABASE LINK': 'DB_LINK', 'JAVA CLASS': 'JAVA_SOURCE'
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
662 }.get(object_type) or object_type
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
663 object_type = object_type.replace(' ', '_')
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
664 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
665 try:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
666 os.makedirs(os.path.join(owner.lower(), object_type.lower()))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
667 except OSError:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
668 pass
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
669 filename = os.path.join(owner.lower(), object_type.lower(), '%s.sql' % object_name.lower())
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
670 self.stdout = open(filename, 'w')
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
671 if vc:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
672 subprocess.call(vc + [filename])
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
673 if object_type == 'PACKAGE':
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
674 ddl = [['PACKAGE_SPEC', object_name, owner],['PACKAGE_BODY', object_name, owner]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
675 elif object_type in ['CONTEXT', 'DIRECTORY', 'JOB']:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
676 ddl = [[object_type, object_name]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
677 else:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
678 ddl = [[object_type, object_name, owner]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
679 for ddlargs in ddl:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
680 try:
246
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
681 self.stdout.write('REMARK BEGIN %s\n%s\nREMARK END\n\n' % (object_name, str(self.curs.callfunc('DBMS_METADATA.GET_DDL', cx_Oracle.CLOB, ddlargs))))
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
682 except cx_Oracle.DatabaseError, errmsg:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
683 if object_type == 'JOB':
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
684 print '%s: DBMS_METADATA.GET_DDL does not support JOBs (MetaLink DocID 567504.1)' % object_name
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
685 elif 'ORA-31603' in str(errmsg): # not found, as in package w/o package body
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
686 pass
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
687 else:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
688 raise
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
689 if opts.full:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
690 for dependent_type in ('OBJECT_GRANT', 'CONSTRAINT', 'TRIGGER'):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
691 try:
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
692 self.stdout.write('REMARK BEGIN\n%s\nREMARK END\n\n' % str(self.curs.callfunc('DBMS_METADATA.GET_DEPENDENT_DDL', cx_Oracle.CLOB,
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
693 [dependent_type, object_name, owner])))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
694 except cx_Oracle.DatabaseError:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
695 pass
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
696 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
697 self.stdout.close()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
698 except:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
699 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
700 statekeeper.restore()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
701 raise
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
702 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
703 statekeeper.restore()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
704
221
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
705 def do_show(self, arg):
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
706 '''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
707 show - display value of all sqlpython parameters
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
708 show (parameter name) - display value of a sqlpython parameter
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
709 show parameter (parameter name) - display value of an ORACLE parameter
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
710 '''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
711 if arg.startswith('param'):
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
712 try:
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
713 paramname = arg.split()[1].lower()
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
714 except IndexError:
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
715 paramname = ''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
716 self.onecmd("""SELECT name,
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
717 CASE type WHEN 1 THEN 'BOOLEAN'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
718 WHEN 2 THEN 'STRING'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
719 WHEN 3 THEN 'INTEGER'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
720 WHEN 4 THEN 'PARAMETER FILE'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
721 WHEN 5 THEN 'RESERVED'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
722 WHEN 6 THEN 'BIG INTEGER' END type,
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
723 value FROM v$parameter WHERE name LIKE '%%%s%%';""" % paramname)
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
724 else:
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
725 return Cmd.do_show(self, arg)
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
726
218
397979c7f6d6 dumping working but not for wildcards
catherine@Elli.myhome.westell.com
parents: 217
diff changeset
727 @options([make_option('-d', '--dump', action='store_true', help='dump results to files'),
397979c7f6d6 dumping working but not for wildcards
catherine@Elli.myhome.westell.com
parents: 217
diff changeset
728 make_option('-f', '--full', action='store_true', help='get dependent objects as well'),
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
729 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
218
397979c7f6d6 dumping working but not for wildcards
catherine@Elli.myhome.westell.com
parents: 217
diff changeset
730 make_option('-x', '--exact', action='store_true', help="match object name exactly")])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
731 def do_pull(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
732 """Displays source code."""
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
733 self._pull(arg, opts)
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
734
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
735 supported_ddl_types = 'CLUSTER, CONTEXT, DATABASE LINK, DIRECTORY, FUNCTION, INDEX, JOB, LIBRARY, MATERIALIZED VIEW, PACKAGE, PACKAGE BODY, PACKAGE SPEC, OPERATOR, PACKAGE, PROCEDURE, SEQUENCE, SYNONYM, TABLE, TRIGGER, VIEW, TYPE, TYPE BODY, XML SCHEMA'
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
736 do_pull.__doc__ += '\n\nSupported DDL types: ' + supported_ddl_types
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
737 supported_ddl_types = supported_ddl_types.split(', ')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
738
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
739 def _vc(self, arg, opts, program):
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
740 if not os.path.exists('.%s' % program):
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
741 create = raw_input('%s repository not yet in current directory (%s). Create (y/N)? ' %
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
742 (program, os.getcwd()))
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
743 if not create.strip().lower().startswith('y'):
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
744 return
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
745 subprocess.call([program, 'init'])
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
746 opts.dump = True
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
747 self._pull(arg, opts, vc=[program, 'add'])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
748 subprocess.call([program, 'commit', '-m', '"%s"' % opts.message or 'committed from sqlpython'])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
749
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
750 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
751 make_option('-f', '--full', action='store_true', help='get dependent objects as well'),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
752 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
753 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
754 make_option('-m', '--message', action='store', type='string', dest='message', help="message to save to hg log during commit")])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
755 def do_hg(self, arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
756 '''hg (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
757 Stores DDL on disk and puts files under Mercurial version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
758 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
759 self._vc(arg, opts, 'hg')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
760
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
761 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
762 make_option('-f', '--full', action='store_true', help='get dependent objects as well'),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
763 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
764 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
765 make_option('-m', '--message', action='store', type='string', dest='message', help="message to save to hg log during commit")])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
766 def do_bzr(self, arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
767 '''bzr (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
768 Stores DDL on disk and puts files under Bazaar version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
769 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
770 self._vc(arg, opts, 'bzr')
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
771
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
772 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
773 make_option('-f', '--full', action='store_true', help='get dependent objects as well'),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
774 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
775 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
776 make_option('-m', '--message', action='store', type='string', dest='message', help="message to save to hg log during commit")])
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
777 def do_git(self, arg, opts):
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
778 '''git (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
779 Stores DDL on disk and puts files under git version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
780 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
781 self._vc(arg, opts, 'git')
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
782
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
783 all_users_option = make_option('-a', action='store_const', dest="scope",
222
catherine@dellzilla
parents: 221
diff changeset
784 default={'col':'', 'view':'user', 'schemas':'user', 'firstcol': ''},
catherine@dellzilla
parents: 221
diff changeset
785 const={'col':', owner', 'view':'all', 'schemas':'all', 'firstcol': 'owner, '},
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
786 help='Describe all objects (not just my own)')
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
787 @options([all_users_option,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
788 make_option('-c', '--col', action='store_true', help='find column'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
789 make_option('-t', '--table', action='store_true', help='find table')])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
790 def do_find(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
791 """Finds argument in source code or (with -c) in column definitions."""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
792
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
793 capArg = arg.upper()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
794
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
795 if opts.col:
222
catherine@dellzilla
parents: 221
diff changeset
796 sql = "SELECT table_name, column_name %s FROM %s_tab_columns where column_name like '%%%s%%' ORDER BY %s table_name, column_name;" \
catherine@dellzilla
parents: 221
diff changeset
797 % (opts.scope['col'], opts.scope['view'], capArg, opts.scope['firstcol'])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
798 elif opts.table:
222
catherine@dellzilla
parents: 221
diff changeset
799 sql = "SELECT table_name %s from %s_tables where table_name like '%%%s%%' ORDER BY %s table_name;" \
catherine@dellzilla
parents: 221
diff changeset
800 % (opts.scope['col'], opts.scope['view'], capArg, opts.scope['firstcol'])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
801 else:
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
802 sql = "SELECT * from %s_source where UPPER(text) like '%%%s%%';" % (opts.scope['view'], capArg)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
803 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
804
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
805 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
806 def do_describe(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
807 "emulates SQL*Plus's DESCRIBE"
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
808 target = arg.upper()
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
809 if not target:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
810 return self.do_select(self.parsed("""SELECT object_name, object_type%s
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
811 FROM %s_objects
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
812 WHERE object_type IN ('TABLE','VIEW','INDEX')
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
813 ORDER BY object_name;""" % (opts.scope['col'], opts.scope['view']),
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
814 terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
815 object_type, owner, object_name = self.resolve(target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
816 if not object_type:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
817 return self.do_select(self.parsed("""SELECT object_name, object_type%s FROM %s_objects
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
818 WHERE object_type IN ('TABLE','VIEW','INDEX')
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
819 AND object_name LIKE '%%%s%%'
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
820 ORDER BY object_name;""" %
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
821 (opts.scope['col'], opts.scope['view'], target),
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
822 terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
823 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
824 descQ = descQueries.get(object_type)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
825 if descQ:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
826 for q in descQ:
204
1c3df79fd088 \n\n finally works
catherine@dellzilla
parents: 203
diff changeset
827 self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';' , suffix=arg.parsed.suffix),
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
828 bindVarsIn={'object_name':object_name, 'owner':owner})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
829 elif object_type == 'PACKAGE':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
830 packageContents = self.select_scalar_list(descQueries['PackageObjects'][0], {'package_name':object_name, 'owner':owner})
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
831 for packageObj_name in packageContents:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
832 self.stdout.write('Arguments to %s\n' % (packageObj_name))
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
833 sql = self.parsed(descQueries['PackageObjArgs'][0], terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix)
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
834 self.do_select(sql, bindVarsIn={'package_name':object_name, 'owner':owner, 'object_name':packageObj_name})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
835 do_desc = do_describe
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
836
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
837 def do_deps(self, arg):
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
838 target = arg.upper()
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
839 object_type, owner, object_name = self.resolve(target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
840 if object_type == 'PACKAGE BODY':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
841 q = "and (type != 'PACKAGE BODY' or name != :object_name)'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
842 object_type = 'PACKAGE'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
843 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
844 q = ""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
845 q = """SELECT name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
846 type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
847 from user_dependencies
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
848 where
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
849 referenced_name like :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
850 and referenced_type like :object_type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
851 and referenced_owner like :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
852 %s;""" % (q)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
853 self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix),
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
854 bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
855
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
856 def do_comments(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
857 'Prints comments on a table and its columns.'
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
858 target = arg.upper()
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
859 object_type, owner, object_name, colName = self.resolve_with_column(target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
860 if object_type:
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
861 self.curs.execute(queries['tabComments'], {'table_name':object_name, 'owner':owner})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
862 self.stdout.write("%s %s.%s: %s\n" % (object_type, owner, object_name, self.curs.fetchone()[0]))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
863 if colName:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
864 sql = queries['oneColComments']
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
865 bindVarsIn={'owner':owner, 'object_name': object_name, 'column_name': colName}
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
866 else:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
867 sql = queries['colComments']
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
868 bindVarsIn={'owner':owner, 'object_name': object_name}
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
869 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix),
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
870 bindVarsIn=bindVarsIn)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
871
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
872 def resolve(self, identifier):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
873 """Checks (my objects).name, (my synonyms).name, (public synonyms).name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
874 to resolve a database object's name. """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
875 parts = identifier.split('.')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
876 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
877 if len(parts) == 2:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
878 owner, object_name = parts
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
879 object_type = self.select_scalar_list('SELECT object_type FROM all_objects WHERE owner = :owner AND object_name = :object_name',
205
catherine@dellzilla
parents: 204
diff changeset
880 {'owner': owner, 'object_name': object_name.upper()}
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
881 )[0]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
882 elif len(parts) == 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
883 object_name = parts[0]
205
catherine@dellzilla
parents: 204
diff changeset
884 self.curs.execute(queries['resolve'], {'objName':object_name.upper()})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
885 object_type, object_name, owner = self.curs.fetchone()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
886 except (TypeError, IndexError):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
887 print 'Could not resolve object %s.' % identifier
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
888 object_type, owner, object_name = '', '', ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
889 return object_type, owner, object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
890
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
891 def resolve_with_column(self, identifier):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
892 colName = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
893 object_type, owner, object_name = self.resolve(identifier)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
894 if not object_type:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
895 parts = identifier.split('.')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
896 if len(parts) > 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
897 colName = parts[-1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
898 identifier = '.'.join(parts[:-1])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
899 object_type, owner, object_name = self.resolve(identifier)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
900 return object_type, owner, object_name, colName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
901
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
902 def do_resolve(self, arg):
195
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
903 target = arg.upper()
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
904 self.stdout.write(','.join(self.resolve(target))+'\n')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
905
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
906 def spoolstop(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
907 if self.spoolFile:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
908 self.stdout = self.stdoutBeforeSpool
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
909 print 'Finished spooling to ', self.spoolFile.name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
910 self.spoolFile.close()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
911 self.spoolFile = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
912
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
913 def do_spool(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
914 """spool [filename] - begins redirecting output to FILENAME."""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
915 self.spoolstop()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
916 arg = arg.strip()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
917 if not arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
918 arg = 'output.lst'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
919 if arg.lower() != 'off':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
920 if '.' not in arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
921 arg = '%s.lst' % arg
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
922 print 'Sending output to %s (until SPOOL OFF received)' % (arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
923 self.spoolFile = open(arg, 'w')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
924 self.stdout = self.spoolFile
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
925
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
926 def do_write(self, args):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
927 print 'Use (query) > outfilename instead.'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
928 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
929
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
930 def do_compare(self, args):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
931 """COMPARE query1 TO query2 - uses external tool to display differences.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
932
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
933 Sorting is recommended to avoid false hits.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
934 Will attempt to use a graphical diff/merge tool like kdiff3, meld, or Araxis Merge,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
935 if they are installed."""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
936 #TODO: Update this to use pyparsing
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
937 fnames = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
938 args2 = args.split(' to ')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
939 if len(args2) < 2:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
940 print self.do_compare.__doc__
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
941 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
942 for n in range(len(args2)):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
943 query = args2[n]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
944 fnames.append('compare%s.txt' % n)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
945 #TODO: update this terminator-stripping
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
946 if query.rstrip()[-1] != self.terminator:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
947 query = '%s%s' % (query, self.terminator)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
948 self.onecmd_plus_hooks('%s > %s' % (query, fnames[n]))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
949 diffMergeSearcher.invoke(fnames[0], fnames[1])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
950
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
951 bufferPosPattern = re.compile('\d+')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
952 rangeIndicators = ('-',':')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
953
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
954 def do_psql(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
955 '''Shortcut commands emulating psql's backslash commands.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
956
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
957 \c connect
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
958 \d desc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
959 \e edit
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
960 \g run
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
961 \h help
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
962 \i load
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
963 \o spool
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
964 \p list
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
965 \q quit
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
966 \w save
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
967 \db _dir_tablespaces
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
968 \dd comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
969 \dn _dir_schemas
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
970 \dt _dir_tables
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
971 \dv _dir_views
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
972 \di _dir_indexes
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
973 \? help psql'''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
974 commands = {}
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
975 for c in self.do_psql.__doc__.splitlines()[2:]:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
976 (abbrev, command) = c.split(None, 1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
977 commands[abbrev[1:]] = command
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
978 words = arg.split(None,1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
979 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
980 abbrev = words[0]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
981 except IndexError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
982 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
983 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
984 args = words[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
985 except IndexError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
986 args = ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
987 try:
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
988 return self.onecmd('%s %s%s%s' % (commands[abbrev], args, arg.parsed.terminator, arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
989 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
990 print 'psql command \%s not yet supported.' % abbrev
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
991
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
992 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
993 def do__dir_tables(self, arg, opts):
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
994 sql = """SELECT table_name, 'TABLE' as type%s FROM %s_tables WHERE table_name LIKE '%%%s%%';""" % \
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
995 (opts.scope['col'], opts.scope['view'], arg.upper())
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
996 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
997
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
998 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
999 def do__dir_views(self, arg, opts):
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1000 sql = """SELECT view_name, 'VIEW' as type%s FROM %s_views WHERE view_name LIKE '%%%s%%';""" % \
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
1001 (opts.scope['col'], opts.scope['view'], arg.upper())
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1002 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1003
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1004 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1005 def do__dir_indexes(self, arg, opts):
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1006 sql = """SELECT index_name, index_type%s FROM %s_indexes WHERE index_name LIKE '%%%s%%' OR table_name LIKE '%%%s%%';""" % \
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
1007 (opts.scope['col'], opts.scope['view'], arg.upper(), arg.upper())
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1008 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1009
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1010 def do__dir_tablespaces(self, arg):
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1011 sql = """SELECT tablespace_name, file_name from dba_data_files;"""
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1012 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1013
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1014 def do__dir_schemas(self, arg):
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1015 sql = """SELECT owner, count(*) AS objects FROM all_objects GROUP BY owner ORDER BY owner;"""
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1016 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1017
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1018 def do_head(self, arg):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1019 '''Shortcut for SELECT * FROM <arg>;10
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1020 The terminator (\\t, \\g, \\x, etc.) and number of rows can
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1021 be changed as for any other SELECT statement.'''
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1022 sql = self.parsed('SELECT * FROM %s;' % arg, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix)
195
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
1023 sql.parsed['suffix'] = sql.parsed.suffix or '10'
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
1024 self.do_select(self.parsed(sql))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1025
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1026 def do_print(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1027 'print VARNAME: Show current value of bind variable VARNAME.'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1028 if arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1029 if arg[0] == ':':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1030 arg = arg[1:]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1031 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1032 self.stdout.write(str(self.binds[arg])+'\n')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1033 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1034 self.stdout.write('No bind variable %s\n' % arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1035 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1036 for (var, val) in self.binds.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1037 print ':%s = %s' % (var, val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1038
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1039 assignmentScanner = Parser(pyparsing.Literal(':=') ^ '=')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1040 def do_setbind(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1041 if not arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1042 return self.do_print(arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1043 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1044 assigner, startat, endat = self.assignmentScanner.scanner.scanString(arg).next()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1045 except StopIteration:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1046 self.do_print(arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1047 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1048 var, val = arg[:startat].strip(), arg[endat:].strip()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1049 if val[0] == val[-1] == "'" and len(val) > 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1050 self.binds[var] = val[1:-1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1051 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1052 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1053 self.binds[var] = int(val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1054 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1055 except ValueError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1056 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1057 self.binds[var] = float(val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1058 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1059 except ValueError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1060 statekeeper = Statekeeper(self, ('autobind',))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1061 self.autobind = True
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1062 self.onecmd('SELECT %s AS %s FROM dual;' % (val, var))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1063 statekeeper.restore()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1064
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1065 def do_exec(self, arg):
213
a3eeea9ee8cc synched with cmd2 0.4.5
catherine@Elli.myhome.westell.com
parents: 211
diff changeset
1066 if arg.startswith(':'):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1067 self.do_setbind(arg[1:])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1068 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1069 varsUsed = findBinds(arg, self.binds, {})
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1070 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1071 self.curs.execute('begin\n%s;end;' % arg, varsUsed)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1072 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1073 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1074
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1075 '''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1076 Fails:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1077 select n into :n from test;'''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1078
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1079 def anon_plsql(self, line1):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1080 lines = [line1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1081 while True:
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
1082 line = self.pseudo_raw_input(self.continuation_prompt)
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
1083 if line == 'EOF':
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
1084 return
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1085 if line.strip() == '/':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1086 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1087 self.curs.execute('\n'.join(lines))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1088 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1089 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1090 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1091 lines.append(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1092
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1093 def do_begin(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1094 self.anon_plsql('begin ' + arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1095
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1096 def do_declare(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1097 self.anon_plsql('declare ' + arg)
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1098
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1099 def _ls_statement(self, arg, opts):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1100 if arg:
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1101 target = arg.upper()
232
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1102 if hasattr(opts, 'exact') and opts.exact:
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1103 where = """\nWHERE object_name = '%s'
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1104 OR object_type || '/' || object_name = '%s'""" % \
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1105 (target, target)
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1106 else:
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1107 where = "\nWHERE object_type || '/' || object_name LIKE '%%%s%%'" % (arg.upper().replace('*','%'))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1108 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1109 where = ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1110 if opts.all:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1111 whose = 'all'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1112 objname = "owner || '.' || object_name"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1113 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1114 whose = 'user'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1115 objname = 'object_name'
232
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1116 if hasattr(opts, 'long') and opts.long:
228
84905120d6c7 last_ddl_time is proper label
catherine@dellzilla
parents: 227
diff changeset
1117 moreColumns = ', status, last_ddl_time'
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1118 else:
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1119 moreColumns = ''
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1120
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1121 # 'Normal' sort order is DATE DESC (maybe), object type ASC, object name ASC
244
a7bc7da97a81 keeping python 2.4 compatibility
catherine@dellzilla
parents: 242
diff changeset
1122 sortdirection = (hasattr(opts, 'reverse') and opts.reverse and 'DESC') or 'ASC'
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1123 orderby = 'object_type %s, object_name %s' % (sortdirection, sortdirection)
232
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1124 if hasattr(opts, 'timesort') and opts.timesort:
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1125 orderby = 'last_ddl_time %s, %s' % (('ASC' if hasattr(opts, 'reverse') and opts.reverse else 'DESC'), orderby)
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1126 return {'objname': objname, 'moreColumns': moreColumns,
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1127 'whose': whose, 'where': where, 'orderby': orderby}
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1128
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1129 def resolve_many(self, arg, opts):
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1130 opts.long = False
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1131 clauses = self._ls_statement(arg, opts)
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1132 if opts.all:
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1133 clauses['owner'] = 'owner'
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1134 else:
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1135 clauses['owner'] = 'user'
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1136 statement = '''SELECT %(owner)s, object_type, object_name
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1137 FROM %(whose)s_objects %(where)s
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1138 ORDER BY object_type, object_name''' % clauses
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1139 self.curs.execute(statement)
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1140 return self.curs.fetchall()
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1141
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1142 @options([make_option('-l', '--long', action='store_true', help='long descriptions'),
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1143 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1144 make_option('-t', '--timesort', action='store_true', help="Sort by last_ddl_time"),
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1145 make_option('-r', '--reverse', action='store_true', help="Reverse order while sorting"),
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1146 make_option('-x', '--exact', action='store_true', default=False, help="match name exactly")])
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1147 def do_ls(self, arg, opts):
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1148 statement = '''SELECT object_type || '/' || %(objname)s AS name %(moreColumns)s
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1149 FROM %(whose)s_objects %(where)s
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1150 ORDER BY %(orderby)s;''' % self._ls_statement(arg, opts)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1151 self.do_select(self.parsed(statement, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1152
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1153 @options([make_option('-i', '--ignore-case', dest='ignorecase', action='store_true', help='Case-insensitive search')])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1154 def do_grep(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1155 """grep PATTERN TABLE - search for term in any of TABLE's fields"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1156
195
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
1157 targetnames = arg.split()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1158 pattern = targetnames.pop(0)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1159 targets = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1160 for target in targetnames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1161 if '*' in target:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1162 self.curs.execute("SELECT owner, table_name FROM all_tables WHERE table_name LIKE '%s'%s" %
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1163 (target.upper().replace('*','%')), arg.terminator)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1164 for row in self.curs:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1165 targets.append('%s.%s' % row)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1166 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1167 targets.append(target)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1168 for target in targets:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1169 print target
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1170 target = target.rstrip(';')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1171 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1172 self.curs.execute('select * from %s where 1=0' % target) # just to fill description
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1173 if opts.ignorecase:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1174 sql = ' or '.join("LOWER(%s) LIKE '%%%s%%'" % (d[0], pattern.lower()) for d in self.curs.description)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1175 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1176 sql = ' or '.join("%s LIKE '%%%s%%'" % (d[0], pattern) for d in self.curs.description)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1177 sql = self.parsed('SELECT * FROM %s WHERE %s;' % (target, sql), terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix)
199
09592342a33d ugh - parsing stripping command causes real trouble
catherine@dellzilla
parents: 198
diff changeset
1178 self.do_select(sql)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1179 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1180 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1181 import traceback
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1182 traceback.print_exc(file=sys.stdout)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1183
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1184 def do_refs(self, arg):
211
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1185 '''Lists referential integrity (foreign key constraints) on an object.'''
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1186
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1187 if not arg.strip():
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1188 print 'Usage: refs (table name)'
190
e9d0492d7358 changing refs
catherine@dellzilla
parents: 189
diff changeset
1189 result = []
205
catherine@dellzilla
parents: 204
diff changeset
1190 (type, owner, table_name) = self.resolve(arg.upper())
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1191 self.curs.execute("""SELECT constraint_name, r_owner, r_constraint_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1192 FROM all_constraints
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1193 WHERE constraint_type = 'R'
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1194 AND owner = :owner
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1195 AND table_name = :table_name""",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1196 {"owner": owner, "table_name": table_name})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1197 for (constraint_name, remote_owner, remote_constraint_name) in self.curs.fetchall():
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1198 result.append('%s on %s.%s:' % (constraint_name, owner, table_name))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1199 self.curs.execute("SELECT column_name FROM all_cons_columns WHERE owner = :owner AND constraint_name = :constraint_name ORDER BY position",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1200 {'constraint_name': constraint_name, 'owner': owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1201 result.append(" (%s)" % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1202 self.curs.execute("SELECT table_name FROM all_constraints WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1203 {'remote_owner': remote_owner, 'remote_constraint_name': remote_constraint_name})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1204 remote_table_name = self.curs.fetchone()[0]
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1205 result.append("must be in %s:" % (remote_table_name))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1206 self.curs.execute("SELECT column_name FROM all_cons_columns WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name ORDER BY position",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1207 {'remote_constraint_name': remote_constraint_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1208 result.append(' (%s)\n' % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1209 remote_table_name = table_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1210 remote_owner = owner
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1211 self.curs.execute("""SELECT owner, constraint_name, table_name, r_constraint_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1212 FROM all_constraints
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1213 WHERE (r_owner, r_constraint_name) IN
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1214 ( SELECT owner, constraint_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1215 FROM all_constraints
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
1216 WHERE table_name = :remote_table_name
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1217 AND owner = :remote_owner )""",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1218 {'remote_table_name': remote_table_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1219 for (owner, constraint_name, table_name, remote_constraint_name) in self.curs.fetchall():
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1220 result.append('%s on %s.%s:' % (constraint_name, owner, table_name))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1221 self.curs.execute("SELECT column_name FROM all_cons_columns WHERE owner = :owner AND constraint_name = :constraint_name ORDER BY position",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1222 {'constraint_name': constraint_name, 'owner': owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1223 result.append(" (%s)" % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1224 self.curs.execute("SELECT table_name FROM all_constraints WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1225 {'remote_owner': remote_owner, 'remote_constraint_name': remote_constraint_name})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1226 remote_table_name = self.curs.fetchone()[0]
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1227 result.append("must be in %s:" % (remote_table_name))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1228 self.curs.execute("SELECT column_name FROM all_cons_columns WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name ORDER BY position",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1229 {'remote_constraint_name': remote_constraint_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1230 result.append(' (%s)\n' % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1231 self.stdout.write('\n'.join(result) + "\n")
190
e9d0492d7358 changing refs
catherine@dellzilla
parents: 189
diff changeset
1232
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1233 def _test():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1234 import doctest
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1235 doctest.testmod()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1236
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1237 if __name__ == "__main__":
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1238 "Silent return implies that all unit tests succeeded. Use -v to see details."
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1239 _test()
198
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
1240 if __name__ == "__main__":
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
1241 "Silent return implies that all unit tests succeeded. Use -v to see details."
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
1242 _test()