annotate sqlpython/sqlpyPlus.py @ 310:c897add05eb1

fixed grep bug
author catherine@Elli.myhome.westell.com
date Thu, 26 Mar 2009 10:21:31 -0400
parents 0d16630d8e04
children 38ac0fbb2b63
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 = {
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
36 'TABLE': {
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
37 True: # long description
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
38 ("""
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
39 SELECT atc.column_id "#",
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
40 atc.column_name,
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
41 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?",
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
42 atc.data_type ||
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
43 CASE atc.data_type WHEN 'DATE' THEN ''
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
44 ELSE '(' ||
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
45 CASE atc.data_type WHEN 'NUMBER' THEN TO_CHAR(atc.data_precision) ||
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
46 CASE atc.data_scale WHEN 0 THEN ''
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
47 ELSE ',' || TO_CHAR(atc.data_scale) END
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
48 ELSE TO_CHAR(atc.data_length) END
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
49 END ||
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
50 CASE atc.data_type WHEN 'DATE' THEN '' ELSE ')' END
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
51 data_type,
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
52 acc.comments
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
53 FROM all_tab_columns atc
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
54 JOIN all_col_comments acc ON (acc.owner = atc.owner AND acc.table_name = atc.table_name AND acc.column_name = atc.column_name)
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
55 WHERE atc.table_name = :object_name
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
56 AND atc.owner = :owner
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
57 ORDER BY atc.column_id;""",),
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
58 None: # short description
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
59 ("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
60 SELECT atc.column_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
61 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?",
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
62 atc.data_type ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
63 CASE atc.data_type WHEN 'DATE' THEN ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
64 ELSE '(' ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
65 CASE atc.data_type WHEN 'NUMBER' THEN TO_CHAR(atc.data_precision) ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
66 CASE atc.data_scale WHEN 0 THEN ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
67 ELSE ',' || TO_CHAR(atc.data_scale) END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
68 ELSE TO_CHAR(atc.data_length) END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
69 END ||
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
70 CASE atc.data_type WHEN 'DATE' THEN '' ELSE ')' END
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
71 data_type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
72 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
73 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
74 AND atc.owner = :owner
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
75 ORDER BY atc.column_id;""",)
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
76 }
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
77 ,
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
78
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
79 'PROCEDURE': ("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
80 SELECT NVL(argument_name, 'Return Value') argument_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
81 data_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
82 in_out,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
83 default_value
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
84 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
85 WHERE object_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
86 AND owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
87 AND package_name IS NULL
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
88 ORDER BY sequence;""",),
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
89 'PackageObjects':("""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
90 SELECT DISTINCT object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
91 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
92 WHERE package_name = :package_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
93 AND owner = :owner""",),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
94 'PackageObjArgs':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
95 SELECT object_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
96 argument_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
97 data_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
98 in_out,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
99 default_value
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
100 FROM all_arguments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
101 WHERE package_name = :package_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
102 AND object_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
103 AND owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
104 AND argument_name IS NOT NULL
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
105 ORDER BY sequence;""",),
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
106 'TRIGGER':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
107 SELECT description
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
108 FROM all_triggers
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
109 WHERE owner = :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
110 AND trigger_name = :object_name;
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
111 """,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
112 """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
113 SELECT table_owner,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
114 base_object_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
115 table_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
116 column_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
117 when_clause,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
118 status,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
119 action_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
120 crossedition
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
121 FROM all_triggers
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
122 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
123 AND trigger_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
124 \\t
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
125 """,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
126 ),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
127 'INDEX':("""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
128 SELECT index_type,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
129 table_owner,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
130 table_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
131 table_type,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
132 uniqueness,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
133 compression,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
134 partitioned,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
135 temporary,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
136 generated,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
137 secondary,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
138 dropped,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
139 visibility
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
140 FROM all_indexes
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
141 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
142 AND index_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
143 \\t
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
144 """,)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
145 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
146 descQueries['VIEW'] = descQueries['TABLE']
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
147 descQueries['FUNCTION'] = descQueries['PROCEDURE']
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
148
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
149 queries = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
150 'resolve': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
151 SELECT object_type, object_name, owner FROM (
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
152 SELECT object_type, object_name, user owner, 1 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
153 FROM user_objects
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
154 WHERE object_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
155 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
156 SELECT ao.object_type, ao.object_name, ao.owner, 2 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
157 FROM all_objects ao
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
158 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
159 WHERE us.synonym_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
160 AND ao.object_type != 'SYNONYM'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
161 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
162 SELECT ao.object_type, ao.object_name, ao.owner, 3 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
163 FROM all_objects ao
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
164 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
165 WHERE asyn.synonym_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
166 AND ao.object_type != 'SYNONYM'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
167 AND asyn.owner = 'PUBLIC'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
168 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
169 SELECT 'DIRECTORY' object_type, dir.directory_name, dir.owner, 6 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
170 FROM all_directories dir
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
171 WHERE dir.directory_name = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
172 UNION ALL
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
173 SELECT 'DATABASE LINK' object_type, db_link, owner, 7 priority
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
174 FROM all_db_links dbl
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
175 WHERE dbl.db_link = :objName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
176 ) ORDER BY priority ASC,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
177 length(object_type) ASC,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
178 object_type DESC""", # preference: PACKAGE before PACKAGE BODY, TABLE before INDEX
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
179 'tabComments': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
180 SELECT comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
181 FROM all_tab_comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
182 WHERE owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
183 AND table_name = :table_name""",
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
184 'colComments': """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
185 SELECT
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
186 atc.column_name,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
187 acc.comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
188 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
189 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
190 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
191 AND atc.owner = :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
192 ORDER BY atc.column_id;""",
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
193 'oneColComments': """
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
194 SELECTatc.column_name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
195 acc.comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
196 FROM all_tab_columns atc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
197 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
198 WHERE atc.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
199 AND atc.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
200 AND acc.column_name = :column_name
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
201 ORDER BY atc.column_id;""",
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
202 #thanks to Senora.pm for "refs"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
203 'refs': """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
204 NULL referenced_by,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
205 c2.table_name references,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
206 c1.constraint_name constraint
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
207 FROM
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
208 user_constraints c1,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
209 user_constraints c2
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
210 WHERE
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
211 c1.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
212 and c1.constraint_type ='R'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
213 and c1.r_constraint_name = c2.constraint_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
214 and c1.r_owner = c2.owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
215 and c1.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
216 UNION
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
217 SELECT c1.table_name referenced_by,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
218 NULL references,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
219 c1.constraint_name constraint
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
220 FROM
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
221 user_constraints c1,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
222 user_constraints c2
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
223 WHERE
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
224 c2.table_name = :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
225 and c1.constraint_type ='R'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
226 and c1.r_constraint_name = c2.constraint_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
227 and c1.r_owner = c2.owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
228 and c1.owner = :owner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
229 """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
230 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
231
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
232 class SoftwareSearcher(object):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
233 def __init__(self, softwareList, purpose):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
234 self.softwareList = softwareList
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
235 self.purpose = purpose
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
236 self.software = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
237 def invoke(self, *args):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
238 if not self.software:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
239 (self.software, self.invokeString) = self.find()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
240 argTuple = tuple([self.software] + list(args))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
241 os.system(self.invokeString % argTuple)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
242 def find(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
243 if self.purpose == 'text editor':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
244 software = os.environ.get('EDITOR')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
245 if software:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
246 return (software, '%s %s')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
247 for (n, (software, invokeString)) in enumerate(self.softwareList):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
248 if os.path.exists(software):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
249 if n > (len(self.softwareList) * 0.7):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
250 print """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
251
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
252 Using %s. Note that there are better options available for %s,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
253 but %s couldn't find a better one in your PATH.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
254 Feel free to open up %s
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
255 and customize it to find your favorite %s program.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
256
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
257 """ % (software, self.purpose, __file__, __file__, self.purpose)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
258 return (software, invokeString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
259 stem = os.path.split(software)[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
260 for p in os.environ['PATH'].split(os.pathsep):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
261 if os.path.exists(os.sep.join([p, stem])):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
262 return (stem, invokeString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
263 raise (OSError, """Could not find any %s programs. You will need to install one,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
264 or customize %s to make it aware of yours.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
265 Looked for these programs:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
266 %s""" % (self.purpose, __file__, "\n".join([s[0] for s in self.softwareList])))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
267
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
268 softwareLists = {
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
269 'diff/merge': [
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
270 ('/usr/bin/meld',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
271 ('/usr/bin/kdiff3',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
272 (r'C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe','"%s" %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
273 (r'C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe', '"%s" /base:"%s" /mine:"%s"'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
274 ('FileMerge','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
275 ('kompare','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
276 ('WinMerge','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
277 ('xxdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
278 ('fldiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
279 ('gtkdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
280 ('tkdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
281 ('gvimdiff','%s %s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
282 ('diff',"%s %s %s"),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
283 (r'c:\windows\system32\comp.exe',"%s %s %s")],
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
284 'text editor': [
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
285 ('gedit', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
286 ('textpad', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
287 ('notepad.exe', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
288 ('pico', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
289 ('emacs', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
290 ('vim', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
291 ('vi', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
292 ('ed', '%s %s'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
293 ('edlin', '%s %s')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
294 ]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
295 }
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
296
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
297 diffMergeSearcher = SoftwareSearcher(softwareLists['diff/merge'],'diff/merge')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
298 editSearcher = SoftwareSearcher(softwareLists['text editor'], 'text editor')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
299 editor = os.environ.get('EDITOR')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
300 if editor:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
301 editSearcher.find = lambda: (editor, "%s %s")
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
302
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
303 class CaselessDict(dict):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
304 """dict with case-insensitive keys.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
305
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
306 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
307 def __init__(self, other=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
308 if other:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
309 # Doesn't do keyword args
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
310 if isinstance(other, dict):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
311 for k,v in other.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
312 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
313 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
314 for k,v in other:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
315 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
316 def __getitem__(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
317 return dict.__getitem__(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
318 def __setitem__(self, key, value):
273
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
319 try:
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
320 key = key.lower()
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
321 except AttributeError:
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
322 pass
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
323 dict.__setitem__(self, key, value)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
324 def __contains__(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
325 return dict.__contains__(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
326 def has_key(self, key):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
327 return dict.has_key(self, key.lower())
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
328 def get(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
329 return dict.get(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
330 def setdefault(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
331 return dict.setdefault(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
332 def update(self, other):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
333 for k,v in other.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
334 dict.__setitem__(self, k.lower(), v)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
335 def fromkeys(self, iterable, value=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
336 d = CaselessDict()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
337 for k in iterable:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
338 dict.__setitem__(d, k.lower(), value)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
339 return d
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
340 def pop(self, key, def_val=None):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
341 return dict.pop(self, key.lower(), def_val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
342
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
343 class Parser(object):
246
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
344 comment_def = "--" + ~ ('-' + pyparsing.CaselessKeyword('begin')) + pyparsing.ZeroOrMore(pyparsing.CharsNotIn("\n"))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
345 def __init__(self, scanner, retainSeparator=True):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
346 self.scanner = scanner
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
347 self.scanner.ignore(pyparsing.sglQuotedString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
348 self.scanner.ignore(pyparsing.dblQuotedString)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
349 self.scanner.ignore(self.comment_def)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
350 self.scanner.ignore(pyparsing.cStyleComment)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
351 self.retainSeparator = retainSeparator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
352 def separate(self, txt):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
353 itms = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
354 for (sqlcommand, start, end) in self.scanner.scanString(txt):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
355 if sqlcommand:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
356 if type(sqlcommand[0]) == pyparsing.ParseResults:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
357 if self.retainSeparator:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
358 itms.append("".join(sqlcommand[0]))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
359 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
360 itms.append(sqlcommand[0][0])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
361 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
362 if sqlcommand[0]:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
363 itms.append(sqlcommand[0])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
364 return itms
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
365
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
366 bindScanner = Parser(pyparsing.Literal(':') + pyparsing.Word( pyparsing.alphanums + "_$#" ))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
367
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
368 def findBinds(target, existingBinds, givenBindVars = {}):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
369 result = givenBindVars
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
370 for finding, startat, endat in bindScanner.scanner.scanString(target):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
371 varname = finding[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
372 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
373 result[varname] = existingBinds[varname]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
374 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
375 if not givenBindVars.has_key(varname):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
376 print 'Bind variable %s not defined.' % (varname)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
377 return result
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
378
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
379 class ResultSet(list):
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
380 pass
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
381
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
382 class Result(tuple):
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
383 def __str__(self):
272
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
384 return '\n'.join('%s: %s' % (colname, self[idx])
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
385 for (idx, colname) in enumerate(self.resultset.colnames))
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
386 def __getattr__(self, attr):
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
387 attr = attr.lower()
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
388 try:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
389 return self[self.resultset.colnames.index(attr)]
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
390 except ValueError:
307
e804c08292b3 several bugs out
catherine@dellzilla
parents: 306
diff changeset
391 if attr in ('colnames', 'statement', 'bindvars', 'resultset'):
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
392 return getattr(self.resultset, attr)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
393 else:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
394 raise AttributeError, "available columns are: " + ", ".join(self.resultset.colnames)
273
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
395 def bind(self):
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
396 for (idx, colname) in enumerate(self.resultset.colnames):
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
397 self.resultset.pystate['binds'][colname] = self[idx]
277
6ffe31149306 now passing tests
catherine@Elli.myhome.westell.com
parents: 275
diff changeset
398 self.resultset.pystate['binds'][str(idx+1)] = self[idx]
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
399
288
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
400 def centeredSlice(lst, center=0, width=1):
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
401 width = max(width, -1)
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
402 if center < 0:
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
403 end = center + width + 1
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
404 if end >= 0:
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
405 end = None
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
406 return lst[center-width:end]
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
407 else:
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
408 return lst[max(center-width,0):center+width+1]
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
409
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
410 class sqlpyPlus(sqlpython.sqlpython):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
411 defaultExtension = 'sql'
289
3cade02da892 replacing manual abbreviations with abbrev param
catherine@Elli.myhome.westell.com
parents: 285
diff changeset
412 abbrev = True
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
413 sqlpython.sqlpython.shortcuts.update({':': 'setbind',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
414 '\\': 'psql',
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
415 '@': 'get'})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
416 multilineCommands = '''select insert update delete tselect
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
417 create drop alter _multiline_comment'''.split()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
418 sqlpython.sqlpython.noSpecialParse.append('spool')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
419 commentGrammars = pyparsing.Or([pyparsing.Literal('--') + pyparsing.restOfLine, pyparsing.cStyleComment])
246
b5d4a122354a can round-trip a package now
catherine@dellzilla
parents: 245
diff changeset
420 commentGrammars = pyparsing.Or([Parser.comment_def, pyparsing.cStyleComment])
259
c0847a4c7f49 one-shot connection changes
catherine@Elli.myhome.westell.com
parents: 257
diff changeset
421 prefixParser = pyparsing.Optional(pyparsing.Word(pyparsing.nums)('connection_number')
c0847a4c7f49 one-shot connection changes
catherine@Elli.myhome.westell.com
parents: 257
diff changeset
422 + ':')
309
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
423 reserved_words = [
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
424 'alter', 'begin', 'comment', 'create', 'delete', 'drop', 'end', 'for', 'grant',
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
425 'insert', 'intersect', 'lock', 'minus', 'on', 'order', 'rename',
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
426 'resource', 'revoke', 'select', 'share', 'start', 'union', 'update',
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
427 'where', 'with']
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
428 default_file_name = 'afiedt.buf'
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
429 def __init__(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
430 sqlpython.sqlpython.__init__(self)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
431 self.binds = CaselessDict()
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
432 self.settable += 'autobind commit_on_exit maxfetch maxtselctrows scan serveroutput sql_echo store_results timeout heading wildsql'.split()
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
433 self.settable.remove('case_insensitive')
230
e1e6b820f81b improving ambiguous SETs
catherine@dellzilla
parents: 229
diff changeset
434 self.settable.sort()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
435 self.stdoutBeforeSpool = sys.stdout
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
436 self.sql_echo = False
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
437 self.spoolFile = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
438 self.autobind = False
229
411f78dc1e07 accept SET HEADING
catherine@dellzilla
parents: 228
diff changeset
439 self.heading = True
240
6d9a65b442b5 negative wildcards fixed
catherine@Elli.myhome.westell.com
parents: 239
diff changeset
440 self.wildsql = False
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
441 self.serveroutput = True
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
442 self.scan = True
292
d727f209acf9 py really working right now
catherine@dellzilla
parents: 291
diff changeset
443 self.nonpythoncommand = 'sql'
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
444 self.substvars = {}
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
445 self.result_history = []
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
446 self.store_results = True
309
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
447
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
448 self.pystate = {'r': [], 'binds': self.binds, 'substs': self.substvars}
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
449
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
450 # overrides cmd's parseline
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
451 def parseline(self, line):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
452 """Parse the line into a command name and a string containing
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
453 the arguments. Returns a tuple containing (command, args, line).
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
454 'command' and 'args' may be None if the line couldn't be parsed.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
455 Overrides cmd.cmd.parseline to accept variety of shortcuts.."""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
456
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
457 cmd, arg, line = sqlpython.sqlpython.parseline(self, line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
458 if cmd in ('select', 'sleect', 'insert', 'update', 'delete', 'describe',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
459 'desc', 'comments', 'pull', 'refs', 'desc', 'triggers', 'find') \
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
460 and not hasattr(self, 'curs'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
461 print 'Not connected.'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
462 return '', '', ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
463 return cmd, arg, line
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
464
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
465 def dbms_output(self):
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
466 "Dumps contents of Oracle's DBMS_OUTPUT buffer (where PUT_LINE goes)"
261
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
467 try:
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
468 line = self.curs.var(cx_Oracle.STRING)
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
469 status = self.curs.var(cx_Oracle.NUMBER)
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
470 self.curs.callproc('dbms_output.get_line', [line, status])
261
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
471 while not status.getvalue():
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
472 self.stdout.write(line.getvalue())
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
473 self.stdout.write('\n')
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
474 self.curs.callproc('dbms_output.get_line', [line, status])
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
475 except AttributeError:
0044cfa5867a disconnections worked out
catherine@dellzilla
parents: 259
diff changeset
476 pass
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
477
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
478 def postcmd(self, stop, line):
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
479 """Hook method executed just after a command dispatch is finished."""
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
480 if self.serveroutput:
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
481 self.dbms_output()
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
482 return stop
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
483
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
484 def do_remark(self, line):
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
485 '''
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
486 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
487
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
488 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
489 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
490 unit of code.
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
491
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
492 Without these markers, sqlpython fails to properly distinguish the beginning
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
493 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
494 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
495 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
496 parsing.
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
497
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
498 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
499 safe to include them in SQL*Plus scripts.
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
500 '''
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
501 if not line.lower().strip().startswith('begin'):
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
502 return
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
503 statement = []
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
504 next = self.pseudo_raw_input(self.continuation_prompt)
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
505 while next.lower().split()[:2] != ['remark','end']:
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
506 statement.append(next)
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
507 next = self.pseudo_raw_input(self.continuation_prompt)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
508 return self.onecmd('\n'.join(statement))
272
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
509
292
d727f209acf9 py really working right now
catherine@dellzilla
parents: 291
diff changeset
510 def do_py(self, arg):
272
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
511 '''
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
512 py <command>: Executes a Python command.
297
f4e8919c5cdf adjust docstring for windows
catherine@dellzilla
parents: 296
diff changeset
513 py: Enters interactive Python mode.
f4e8919c5cdf adjust docstring for windows
catherine@dellzilla
parents: 296
diff changeset
514 End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, 'exit()`.
292
d727f209acf9 py really working right now
catherine@dellzilla
parents: 291
diff changeset
515 Past SELECT results are exposed as list `r`;
275
df78546969c9 spacing change in py doc
catherine@Elli.myhome.westell.com
parents: 274
diff changeset
516 most recent resultset is `r[-1]`.
292
d727f209acf9 py really working right now
catherine@dellzilla
parents: 291
diff changeset
517 SQL bind, substitution variables are exposed as `binds`, `substs`.
296
ba5d5483e0db shortened docstring to avoid word wrap
catherine@dellzilla
parents: 293
diff changeset
518 SQL and sqlpython commands can be issued with `sql("your command")`.
272
fee766daa57b yay py works fully
catherine@Elli.myhome.westell.com
parents: 271
diff changeset
519 '''
292
d727f209acf9 py really working right now
catherine@dellzilla
parents: 291
diff changeset
520 return Cmd.do_py(self, arg)
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
521
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
522 def do_get(self, args):
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
523 """
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
524 `get {script.sql}` or `@{script.sql}` runs the command(s) in {script.sql}.
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
525 If additional arguments are supplied, they are assigned to &1, &2, etc.
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
526 """
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
527 fname, args = args.split()[0], args.split()[1:]
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
528 for (idx, arg) in enumerate(args):
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
529 self.substvars[str(idx+1)] = arg
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
530 return Cmd.do__load(self, fname)
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
531
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
532 def onecmd_plus_hooks(self, line):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
533 line = self.precmd(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
534 stop = self.onecmd(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
535 stop = self.postcmd(stop, line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
536
257
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
537 def _onchange_serveroutput(self, old, new):
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
538 if new:
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
539 self.curs.callproc('dbms_output.enable', [])
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
540 else:
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
541 self.curs.callproc('dbms_output.disable', [])
6d4d90fb2082 dbms_output.put_line working
catherine@Elli.myhome.westell.com
parents: 254
diff changeset
542
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
543 def do_shortcuts(self,arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
544 """Lists available first-character shortcuts
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
545 (i.e. '!dir' is equivalent to 'shell dir')"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
546 for (scchar, scto) in self.shortcuts.items():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
547 print '%s: %s' % (scchar, scto)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
548
254
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
549 tableNameFinder = re.compile(r'from\s+([\w$#_"]+)', re.IGNORECASE | re.MULTILINE | re.DOTALL)
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
550 inputStatementFormatters = {
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
551 cx_Oracle.STRING: "'%s'",
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
552 cx_Oracle.DATETIME: "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')"}
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
553 inputStatementFormatters[cx_Oracle.CLOB] = inputStatementFormatters[cx_Oracle.STRING]
b61e21386383 oops, restore lines of code after sql_format_item
catherine@Elli.myhome.westell.com
parents: 253
diff changeset
554 inputStatementFormatters[cx_Oracle.TIMESTAMP] = inputStatementFormatters[cx_Oracle.DATETIME]
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
555 def output(self, outformat, rowlimit):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
556 self.tblname = self.tableNameFinder.search(self.curs.statement).group(1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
557 self.colnames = [d[0] for d in self.curs.description]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
558 if outformat in output_templates:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
559 self.colnamelen = max(len(colname) for colname in self.colnames)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
560 self.coltypes = [d[1] for d in self.curs.description]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
561 self.formatters = [self.inputStatementFormatters.get(typ, '%s') for typ in self.coltypes]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
562 result = output_templates[outformat].generate(**self.__dict__)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
563 elif outformat == '\\t': # transposed
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
564 rows = [self.colnames]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
565 rows.extend(list(self.rows))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
566 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
567 newdesc = [['ROW N.'+str(y),10] for y in range(len(rows))]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
568 for x in range(len(self.curs.description)):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
569 if str(self.curs.description[x][1]) == "<type 'cx_Oracle.BINARY'>": # handles RAW columns
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
570 rname = transpr[x][0]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
571 transpr[x] = map(binascii.b2a_hex, transpr[x])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
572 transpr[x][0] = rname
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
573 newdesc[0][0] = 'COLUMN NAME'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
574 result = '\n' + sqlpython.pmatrix(transpr,newdesc)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
575 elif outformat in ('\\l', '\\L', '\\p', '\\b'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
576 plot = Plot()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
577 plot.build(self, outformat)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
578 plot.shelve()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
579 plot.draw()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
580 return ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
581 else:
308
4d24fea42364 py scripts working again
catherine@Elli.myhome.westell.com
parents: 307
diff changeset
582 result = sqlpython.pmatrix(self.rows, self.curs.description,
4d24fea42364 py scripts working again
catherine@Elli.myhome.westell.com
parents: 307
diff changeset
583 self.maxfetch, heading=self.heading,
4d24fea42364 py scripts working again
catherine@Elli.myhome.westell.com
parents: 307
diff changeset
584 restructuredtext = (outformat == '\\r'))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
585 return result
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
586
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
587 legalOracle = re.compile('[a-zA-Z_$#]')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
588
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
589 def select_scalar_list(self, sql, binds={}):
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
590 self._execute(sql, binds)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
591 return [r[0] for r in self.curs.fetchall()]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
592
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
593 columnNameRegex = re.compile(
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
594 r'select\s+(.*)from',
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
595 re.IGNORECASE | re.DOTALL | re.MULTILINE)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
596 def completedefault(self, text, line, begidx, endidx):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
597 segment = completion.whichSegment(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
598 text = text.upper()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
599 completions = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
600 if segment == 'select':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
601 stmt = "SELECT column_name FROM user_tab_columns WHERE column_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
602 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
603 if not completions:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
604 stmt = "SELECT column_name FROM all_tab_columns WHERE column_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
605 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
606 if segment == 'from':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
607 columnNames = self.columnNameRegex.search(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
608 if columnNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
609 columnNames = columnNames.group(1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
610 columnNames = [c.strip().upper() for c in columnNames.split(',')]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
611 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
612 for columnName in columnNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
613 # and if columnName is * ?
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
614 completions.extend(self.select_scalar_list(stmt1 % (columnName, text)))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
615 if segment in ('from', 'update', 'insert into') and (not completions):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
616 stmt = "SELECT table_name FROM user_tables WHERE table_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
617 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
618 if not completions:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
619 stmt = """SELECT table_name FROM user_tables WHERE table_name LIKE '%s%%'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
620 UNION
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
621 SELECT DISTINCT owner FROM all_tables WHERE owner LIKE '%%%s'"""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
622 completions = self.select_scalar_list(stmt % (text, text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
623 if segment in ('where', 'group by', 'order by', 'having', 'set'):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
624 tableNames = completion.tableNamesFromFromClause(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
625 if tableNames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
626 stmt = """SELECT column_name FROM all_tab_columns
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
627 WHERE table_name IN (%s)""" % \
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
628 (','.join("'%s'" % (t) for t in tableNames))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
629 stmt = "%s AND column_name LIKE '%s%%'" % (stmt, text)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
630 completions = self.select_scalar_list(stmt)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
631 if not segment:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
632 stmt = "SELECT object_name FROM all_objects WHERE object_name LIKE '%s%%'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
633 completions = self.select_scalar_list(stmt % (text))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
634 return completions
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
635
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
636 columnlistPattern = pyparsing.SkipTo(pyparsing.CaselessKeyword('from'))('columns') + \
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
637 pyparsing.SkipTo(pyparsing.stringEnd)('remainder')
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
638
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
639 negator = pyparsing.Literal('!')('exclude')
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
640 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
641 colName = negator + pyparsing.Word('$_#' + pyparsing.alphas, '$_#' + pyparsing.alphanums)('column_name')
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
642 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
643 colNumber.ignore(pyparsing.cStyleComment).ignore(Parser.comment_def). \
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
644 ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString)
235
8e5f58d504d4 tightening up wildcard pyparsing
catherine@dellzilla
parents: 234
diff changeset
645 wildSqlParser = colNumber ^ colName ^ wildColName
8e5f58d504d4 tightening up wildcard pyparsing
catherine@dellzilla
parents: 234
diff changeset
646 wildSqlParser.ignore(pyparsing.cStyleComment).ignore(Parser.comment_def). \
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
647 ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
648 emptyCommaRegex = re.compile(',\s*,', re.DOTALL)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
649 deadStarterCommaRegex = re.compile('^\s*,', re.DOTALL)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
650 deadEnderCommaRegex = re.compile(',\s*$', re.DOTALL)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
651 def expandWildSql(self, arg):
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
652 try:
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
653 columnlist = self.columnlistPattern.parseString(arg)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
654 except pyparsing.ParseException:
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
655 return arg
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
656 parseresults = list(self.wildSqlParser.scanString(columnlist.columns))
239
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
657 # 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
658 # but can't figure out how
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
659 parseresults = [p for p in parseresults if
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
660 p[0].column_number or
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
661 '*' in p[0].column_name or
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
662 '%' in p[0].column_name or
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
663 '?' in p[0].column_name or
239
4c563c2218e6 catching standard names caught
catherine@Elli.myhome.westell.com
parents: 238
diff changeset
664 p[0].exclude]
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
665 if not parseresults:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
666 return arg
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
667 self.curs.execute('select * ' + columnlist.remainder, self.varsUsed)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
668 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
669 replacers = {}
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
670 included = set()
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
671 excluded = set()
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
672 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
673 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
674 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
675 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
676 finder = finder.replace('%','.*')
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
677 finder = finder.replace('?','.')
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
678 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
679 elif col.column_number:
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
680 idx = int(col.column_number)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
681 if idx > 0:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
682 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
683 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
684 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
685 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
686 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
687 for colname in colnames:
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
688 if col.exclude:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
689 included.discard(colname)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
690 include_here = columns_available[:]
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
691 include_here.remove(colname)
240
6d9a65b442b5 negative wildcards fixed
catherine@Elli.myhome.westell.com
parents: 239
diff changeset
692 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
693 excluded.add(colname)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
694 else:
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
695 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
696 replacers[arg[startpos:endpos]].append(colname)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
697
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
698 replacers = sorted(replacers.items(), key=len, reverse=True)
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
699 result = columnlist.columns
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
700 for (target, replacement) in replacers:
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
701 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
702 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
703 included.update(cols)
236
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
704 result = result.replace(target, replacement)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
705 # 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
706 result = self.emptyCommaRegex.sub(',', result)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
707 result = self.deadStarterCommaRegex.sub('', result)
7f999b141fcd debugging streamlined wild sql
catherine@dellzilla
parents: 235
diff changeset
708 result = self.deadEnderCommaRegex.sub('', result)
242
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
709 if not result.strip():
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
710 print 'No columns found matching criteria.'
8866fe0706c3 message when all columns excluded
catherine@dellzilla
parents: 241
diff changeset
711 return 'null from dual'
237
95070e01907d not col num works
catherine@Elli.myhome.westell.com
parents: 236
diff changeset
712 return result + ' ' + columnlist.remainder
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
713
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
714 def do_prompt(self, args):
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
715 print args
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
716
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
717 def do_accept(self, args):
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
718 try:
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
719 prompt = args[args.lower().index('prompt ')+7:]
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
720 except ValueError:
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
721 prompt = ''
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
722 varname = args.lower().split()[0]
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
723 self.substvars[varname] = self.pseudo_raw_input(prompt)
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
724
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
725 def ampersand_substitution(self, raw, regexpr, isglobal):
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
726 subst = regexpr.search(raw)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
727 while subst:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
728 fullexpr, var = subst.group(1), subst.group(2)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
729 print 'Substitution variable %s found in:' % fullexpr
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
730 print raw[max(subst.start()-20, 0):subst.end()+20]
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
731 if var in self.substvars:
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
732 val = self.substvars[var]
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
733 else:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
734 val = raw_input('Substitution for %s (SET SCAN OFF to halt substitution): ' % fullexpr)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
735 if val.lower().split() == ['set','scan','off']:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
736 self.scan = False
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
737 return raw
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
738 if isglobal:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
739 self.substvars[var] = val
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
740 raw = raw.replace(fullexpr, val)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
741 print 'Substituted %s for %s' % (val, fullexpr)
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
742 subst = regexpr.search(raw) # do not FINDALL b/c we don't want to ask twice
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
743 return raw
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
744
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
745 numericampre = re.compile('(&(\d+))')
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
746 doubleampre = re.compile('(&&([a-zA-Z\d_$#]+))', re.IGNORECASE)
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
747 singleampre = re.compile( '(&([a-zA-Z\d_$#]+))', re.IGNORECASE)
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
748 def preparse(self, raw, **kwargs):
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
749 if self.scan:
284
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
750 raw = self.ampersand_substitution(raw, regexpr=self.numericampre, isglobal=False)
ad20675a17f7 working on adding accept, prompt
catherine@dellzilla
parents: 281
diff changeset
751 if self.scan:
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
752 raw = self.ampersand_substitution(raw, regexpr=self.doubleampre, isglobal=True)
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
753 if self.scan:
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
754 raw = self.ampersand_substitution(raw, regexpr=self.singleampre, isglobal=False)
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
755 return raw
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
756
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
757 rowlimitPattern = pyparsing.Word(pyparsing.nums)('rowlimit')
308
4d24fea42364 py scripts working again
catherine@Elli.myhome.westell.com
parents: 307
diff changeset
758 terminators = '; \\C \\t \\i \\p \\l \\L \\b \\r'.split() + output_templates.keys()
199
09592342a33d ugh - parsing stripping command causes real trouble
catherine@dellzilla
parents: 198
diff changeset
759
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
760 @options([make_option('-r', '--row', type="int", default=-1,
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
761 help='Bind row #ROW instead of final row (zero-based)')])
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
762 def do_bind(self, arg=None, opts={}):
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
763 '''
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
764 Inserts the results from the final row in the last completed SELECT statement
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
765 into bind variables with names corresponding to the column names. When the optional
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
766 `autobind` setting is on, this will be issued automatically after every query that
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
767 returns exactly one row.
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
768 '''
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
769 try:
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
770 self.pystate['r'][-1][opts.row].bind()
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
771 except IndexError:
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
772 print self.do_bind.__doc__
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
773
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
774 def do_select(self, arg, bindVarsIn=None, terminator=None):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
775 """Fetch rows from a table.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
776
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
777 Limit the number of rows retrieved by appending
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
778 an integer after the terminator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
779 (example: SELECT * FROM mytable;10 )
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
780
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
781 Output may be formatted by choosing an alternative terminator
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
782 ("help terminators" for details)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
783 """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
784 bindVarsIn = bindVarsIn or {}
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
785 try:
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
786 rowlimit = int(arg.parsed.suffix or 0)
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
787 except ValueError:
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
788 rowlimit = 0
206
ed46f2dba929 fixed sessinfo
catherine@Elli.myhome.westell.com
parents: 204
diff changeset
789 print "Specify desired number of rows after terminator (not '%s')" % arg.parsed.suffix
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
790 if arg.parsed.terminator == '\\t':
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
791 rowlimit = rowlimit or self.maxtselctrows
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
792 self.varsUsed = findBinds(arg, self.binds, bindVarsIn)
233
dc7683970717 beginning wildsql
catherine@Elli.myhome.westell.com
parents: 232
diff changeset
793 if self.wildsql:
234
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
794 selecttext = self.expandWildSql(arg)
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
795 else:
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
796 selecttext = arg
a86efbca3da9 ha ha ha - wildcards in selects working now
catherine@dellzilla
parents: 233
diff changeset
797 self.curs.execute('select ' + selecttext, self.varsUsed)
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
798 self.rows = self.curs.fetchmany(min(self.maxfetch, (rowlimit or self.maxfetch)))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
799 self.rc = self.curs.rowcount
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
800 if self.rc > 0:
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
801 resultset = ResultSet()
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
802 resultset.colnames = [d[0].lower() for d in self.curs.description]
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
803 resultset.pystate = self.pystate
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
804 resultset.statement = 'select ' + selecttext
273
9d67065ea030 data into/out of py via binds
catherine@Elli.myhome.westell.com
parents: 272
diff changeset
805 resultset.varsUsed = self.varsUsed
271
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
806 resultset.extend([Result(r) for r in self.rows])
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
807 for row in resultset:
fbe23b635300 py object manipulation almost done
catherine@dellzilla
parents: 265
diff changeset
808 row.resultset = resultset
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
809 self.pystate['r'].append(resultset)
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
810 self.stdout.write('\n%s\n' % (self.output(arg.parsed.terminator, rowlimit)))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
811 if self.rc == 0:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
812 print '\nNo rows Selected.\n'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
813 elif self.rc == 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
814 print '\n1 row selected.\n'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
815 if self.autobind:
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
816 self.do_bind()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
817 elif self.rc < self.maxfetch:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
818 print '\n%d rows selected.\n' % self.rc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
819 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
820 print '\nSelected Max Num rows (%d)' % self.rc
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
821
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
822 def do_cat(self, arg):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
823 '''Shortcut for SELECT * FROM'''
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
824 return self.do_select(self.parsed('SELECT * FROM %s;' % arg,
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
825 terminator = arg.parsed.terminator or ';',
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
826 suffix = arg.parsed.suffix))
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
827
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
828 def _pull(self, arg, opts, vc=None):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
829 """Displays source code."""
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
830 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
831 statekeeper = Statekeeper(self, ('stdout',))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
832 try:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
833 for (owner, object_type, object_name) in self.resolve_many(arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
834 if object_type in self.supported_ddl_types:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
835 object_type = {'DATABASE LINK': 'DB_LINK', 'JAVA CLASS': 'JAVA_SOURCE'
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
836 }.get(object_type) or object_type
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
837 object_type = object_type.replace(' ', '_')
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
838 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
839 try:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
840 os.makedirs(os.path.join(owner.lower(), object_type.lower()))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
841 except OSError:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
842 pass
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
843 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
844 self.stdout = open(filename, 'w')
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
845 if vc:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
846 subprocess.call(vc + [filename])
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
847 if object_type == 'PACKAGE':
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
848 ddl = [['PACKAGE_SPEC', object_name, owner],['PACKAGE_BODY', object_name, owner]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
849 elif object_type in ['CONTEXT', 'DIRECTORY', 'JOB']:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
850 ddl = [[object_type, object_name]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
851 else:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
852 ddl = [[object_type, object_name, owner]]
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
853 for ddlargs in ddl:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
854 try:
288
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
855 code = str(self.curs.callfunc('DBMS_METADATA.GET_DDL', cx_Oracle.CLOB, ddlargs))
305
9c727d6afdc0 docs changes
catherine@dellzilla
parents: 297
diff changeset
856 if hasattr(opts, 'lines') and opts.lines:
288
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
857 code = code.splitlines()
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
858 template = "%%-%dd:%%s" % len(str(len(code)))
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
859 code = '\n'.join(template % (n+1, line) for (n, line) in enumerate(code))
305
9c727d6afdc0 docs changes
catherine@dellzilla
parents: 297
diff changeset
860 if hasattr(opts, 'num') and (opts.num is not None):
288
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
861 code = code.splitlines()
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
862 code = centeredSlice(code, center=opts.num+1, width=opts.width)
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
863 code = '\n'.join(code)
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
864 self.stdout.write('REMARK BEGIN %s\n%s\nREMARK END\n\n' % (object_name, code))
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
865 except cx_Oracle.DatabaseError, errmsg:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
866 if object_type == 'JOB':
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
867 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
868 elif 'ORA-31603' in str(errmsg): # not found, as in package w/o package body
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
869 pass
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
870 else:
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
871 raise
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
872 if opts.full:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
873 for dependent_type in ('OBJECT_GRANT', 'CONSTRAINT', 'TRIGGER'):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
874 try:
245
05c90f80815c trying REMARK BEGIN / REMARK END
catherine@Elli.myhome.westell.com
parents: 244
diff changeset
875 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
876 [dependent_type, object_name, owner])))
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
877 except cx_Oracle.DatabaseError:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
878 pass
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
879 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
880 self.stdout.close()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
881 except:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
882 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
883 statekeeper.restore()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
884 raise
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
885 if opts.dump:
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
886 statekeeper.restore()
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
887
221
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
888 def do_show(self, arg):
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
889 '''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
890 show - display value of all sqlpython parameters
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
891 show (parameter name) - display value of a sqlpython parameter
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
892 show parameter (parameter name) - display value of an ORACLE parameter
265
041c656dc8e5 show err working nicely now
catherine@Elli.myhome.westell.com
parents: 264
diff changeset
893 show err (object type/name) - errors from latest PL/SQL object compilation.
041c656dc8e5 show err working nicely now
catherine@Elli.myhome.westell.com
parents: 264
diff changeset
894 show all err (type/name) - all compilation errors from the user's PL/SQL objects.
221
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
895 '''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
896 if arg.startswith('param'):
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
897 try:
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
898 paramname = arg.split()[1].lower()
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
899 except IndexError:
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
900 paramname = ''
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
901 self.onecmd("""SELECT name,
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
902 CASE type WHEN 1 THEN 'BOOLEAN'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
903 WHEN 2 THEN 'STRING'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
904 WHEN 3 THEN 'INTEGER'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
905 WHEN 4 THEN 'PARAMETER FILE'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
906 WHEN 5 THEN 'RESERVED'
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
907 WHEN 6 THEN 'BIG INTEGER' END type,
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
908 value FROM v$parameter WHERE name LIKE '%%%s%%';""" % paramname)
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
909 else:
264
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
910 argpieces = arg.lower().split()
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
911 try:
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
912 if argpieces[0][:3] == 'err':
265
041c656dc8e5 show err working nicely now
catherine@Elli.myhome.westell.com
parents: 264
diff changeset
913 return self._show_errors(all_users=False, limit=1, targets=argpieces[1:])
264
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
914 elif (argpieces[0], argpieces[1][:3]) == ('all','err'):
265
041c656dc8e5 show err working nicely now
catherine@Elli.myhome.westell.com
parents: 264
diff changeset
915 return self._show_errors(all_users=False, limit=None, targets=argpieces[2:])
264
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
916 except IndexError:
a8deaa38f11e show errors works. limiting ls
catherine@Elli.myhome.westell.com
parents: 261
diff changeset
917 pass
221
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
918 return Cmd.do_show(self, arg)
3a59ca05f980 added show parameter
catherine@Elli.myhome.westell.com
parents: 220
diff changeset
919
218
397979c7f6d6 dumping working but not for wildcards
catherine@Elli.myhome.westell.com
parents: 217
diff changeset
920 @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
921 make_option('-f', '--full', action='store_true', help='get dependent objects as well'),
288
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
922 make_option('-l', '--lines', action='store_true', help='print line numbers'),
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
923 make_option('-n', '--num', type='int', help='only code near line #num'),
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
924 make_option('-w', '--width', type='int', default=5,
e7578e7ff9dd sliced pull almost working...
catherine@dellzilla
parents: 286
diff changeset
925 help='# of lines before and after --lineNo'),
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
926 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
927 make_option('-x', '--exact', action='store_true', help="match object name exactly")])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
928 def do_pull(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
929 """Displays source code."""
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
930 self._pull(arg, opts)
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
931
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
932 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
933 do_pull.__doc__ += '\n\nSupported DDL types: ' + supported_ddl_types
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
934 supported_ddl_types = supported_ddl_types.split(', ')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
935
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
936 def _vc(self, arg, opts, program):
248
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
937 if not os.path.exists('.%s' % program):
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
938 create = raw_input('%s repository not yet in current directory (%s). Create (y/N)? ' %
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
939 (program, os.getcwd()))
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
940 if not create.strip().lower().startswith('y'):
230447ce6e60 end wed
catherine@dellzilla
parents: 247
diff changeset
941 return
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
942 subprocess.call([program, 'init'])
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
943 opts.dump = True
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
944 self._pull(arg, opts, vc=[program, 'add'])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
945 subprocess.call([program, 'commit', '-m', '"%s"' % opts.message or 'committed from sqlpython'])
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
946
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
947 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
948 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
949 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
950 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
951 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
952 def do_hg(self, arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
953 '''hg (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
954 Stores DDL on disk and puts files under Mercurial version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
955 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
956 self._vc(arg, opts, 'hg')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
957
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
958 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
959 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
960 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
961 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
962 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
963 def do_bzr(self, arg, opts):
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
964 '''bzr (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
965 Stores DDL on disk and puts files under Bazaar version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
966 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
967 self._vc(arg, opts, 'bzr')
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
968
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
969 @options([
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
970 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
971 make_option('-a', '--all', action='store_true', help="all schemas' objects"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
972 make_option('-x', '--exact', action='store_true', help="match object name exactly"),
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
973 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
974 def do_git(self, arg, opts):
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
975 '''git (opts) (objects):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
976 Stores DDL on disk and puts files under git version control.
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
977 Args specify which objects to store, same format as `ls`.'''
224
582c84365f6a svn sucks - supporting git instead
catherine@dellzilla
parents: 223
diff changeset
978 self._vc(arg, opts, 'git')
220
01af6bfbe78f hg works
catherine@Elli.myhome.westell.com
parents: 219
diff changeset
979
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
980 all_users_option = make_option('-a', action='store_const', dest="scope",
222
catherine@dellzilla
parents: 221
diff changeset
981 default={'col':'', 'view':'user', 'schemas':'user', 'firstcol': ''},
catherine@dellzilla
parents: 221
diff changeset
982 const={'col':', owner', 'view':'all', 'schemas':'all', 'firstcol': 'owner, '},
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
983 help='Describe all objects (not just my own)')
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
984 @options([all_users_option,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
985 make_option('-c', '--col', action='store_true', help='find column'),
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
986 make_option('-t', '--table', action='store_true', help='find table')])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
987 def do_find(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
988 """Finds argument in source code or (with -c) in column definitions."""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
989
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
990 capArg = arg.upper()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
991
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
992 if opts.col:
222
catherine@dellzilla
parents: 221
diff changeset
993 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
994 % (opts.scope['col'], opts.scope['view'], capArg, opts.scope['firstcol'])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
995 elif opts.table:
222
catherine@dellzilla
parents: 221
diff changeset
996 sql = "SELECT table_name %s from %s_tables where table_name like '%%%s%%' ORDER BY %s table_name;" \
catherine@dellzilla
parents: 221
diff changeset
997 % (opts.scope['col'], opts.scope['view'], capArg, opts.scope['firstcol'])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
998 else:
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
999 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
1000 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
1001
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1002
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1003 @options([all_users_option,
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1004 make_option('-l', '--long', action='store_true', help='include column #, comments')])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1005 def do_describe(self, arg, opts):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1006 "emulates SQL*Plus's DESCRIBE"
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1007 target = arg.upper()
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1008 objnameclause = ''
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1009 if target:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1010 objnameclause = "AND object_name LIKE '%%%s%%' " % target
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1011 object_type, owner, object_name = self.resolve(target)
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1012 if (not target) or (not object_type):
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1013 if opts.long:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1014 query = """SELECT o.object_name, o.object_type, o.owner, c.comments
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1015 FROM all_objects o
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1016 LEFT OUTER JOIN all_tab_comments c ON (o.owner = c.owner AND o.object_name = c.table_name AND o.object_type = 'TABLE')
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1017 WHERE object_type IN ('TABLE','VIEW','INDEX')
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1018 %sORDER BY object_name;""" % objnameclause
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1019 else:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1020 query = """SELECT object_name, object_type%s
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1021 FROM %s_objects
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1022 WHERE object_type IN ('TABLE','VIEW','INDEX')
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1023 %sORDER BY object_name;""" % \
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1024 (opts.scope['col'], opts.scope['view'], objnameclause)
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1025 return self.do_select(self.parsed(query, terminator=arg.parsed.terminator or ';',
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1026 suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1027 self.stdout.write("%s %s.%s\n" % (object_type, owner, object_name))
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1028 try:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1029 if object_type == 'TABLE':
309
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
1030 if opts.long:
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
1031 self._execute(queries['tabComments'], {'table_name':object_name, 'owner':owner})
0d16630d8e04 added table comment to desc -l
catherine@Elli.myhome.westell.com
parents: 308
diff changeset
1032 self.stdout.write(self.curs.fetchone()[0])
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1033 descQ = descQueries[object_type][opts.long]
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1034 else:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1035 descQ = descQueries[object_type][opts.long]
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1036 for q in descQ:
204
1c3df79fd088 \n\n finally works
catherine@dellzilla
parents: 203
diff changeset
1037 self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';' , suffix=arg.parsed.suffix),
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1038 bindVarsIn={'object_name':object_name, 'owner':owner})
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1039 except KeyError:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1040 if object_type == 'PACKAGE':
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1041 packageContents = self.select_scalar_list(descQueries['PackageObjects'][0], {'package_name':object_name, 'owner':owner})
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1042 for packageObj_name in packageContents:
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1043 self.stdout.write('Arguments to %s\n' % (packageObj_name))
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1044 sql = self.parsed(descQueries['PackageObjArgs'][0], terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix)
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1045 self.do_select(sql, bindVarsIn={'package_name':object_name, 'owner':owner, 'object_name':packageObj_name})
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1046
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1047
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1048 def do_deps(self, arg):
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1049 '''Lists all objects that are dependent upon the object.'''
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1050 target = arg.upper()
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1051 object_type, owner, object_name = self.resolve(target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1052 if object_type == 'PACKAGE BODY':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1053 q = "and (type != 'PACKAGE BODY' or name != :object_name)'"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1054 object_type = 'PACKAGE'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1055 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1056 q = ""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1057 q = """SELECT name,
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1058 type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1059 from user_dependencies
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1060 where
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1061 referenced_name like :object_name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1062 and referenced_type like :object_type
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1063 and referenced_owner like :owner
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1064 %s;""" % (q)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1065 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
1066 bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1067
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1068 def do_comments(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1069 'Prints comments on a table and its columns.'
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1070 target = arg.upper()
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1071 object_type, owner, object_name, colName = self.resolve_with_column(target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1072 if object_type:
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1073 self._execute(queries['tabComments'], {'table_name':object_name, 'owner':owner})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1074 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
1075 if colName:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1076 sql = queries['oneColComments']
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1077 bindVarsIn={'owner':owner, 'object_name': object_name, 'column_name': colName}
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1078 else:
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1079 sql = queries['colComments']
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1080 bindVarsIn={'owner':owner, 'object_name': object_name}
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1081 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
1082 bindVarsIn=bindVarsIn)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1083
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1084 def _resolve(self, identifier):
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1085 parts = identifier.split('.')
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1086 if len(parts) == 2:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1087 owner, object_name = parts
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1088 object_type = self.select_scalar_list('SELECT object_type FROM all_objects WHERE owner = :owner AND object_name = :object_name',
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1089 {'owner': owner, 'object_name': object_name.upper()}
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1090 )[0]
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1091 elif len(parts) == 1:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1092 object_name = parts[0]
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1093 self._execute(queries['resolve'], {'objName':object_name.upper()})
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1094 object_type, object_name, owner = self.curs.fetchone()
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1095 return object_type, owner, object_name
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1096
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1097 def resolve(self, identifier):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1098 """Checks (my objects).name, (my synonyms).name, (public synonyms).name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1099 to resolve a database object's name. """
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1100 try:
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1101 return self._resolve(identifier)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1102 except (TypeError, IndexError):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1103 print 'Could not resolve object %s.' % identifier
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1104 return '', '', ''
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1105
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1106 def resolve_with_column(self, identifier):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1107 colName = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1108 object_type, owner, object_name = self.resolve(identifier)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1109 if not object_type:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1110 parts = identifier.split('.')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1111 if len(parts) > 1:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1112 colName = parts[-1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1113 identifier = '.'.join(parts[:-1])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1114 object_type, owner, object_name = self.resolve(identifier)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1115 return object_type, owner, object_name, colName
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1116
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1117 def do_resolve(self, arg):
195
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
1118 target = arg.upper()
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
1119 self.stdout.write(','.join(self.resolve(target))+'\n')
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1120
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1121 def spoolstop(self):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1122 if self.spoolFile:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1123 self.stdout = self.stdoutBeforeSpool
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1124 print 'Finished spooling to ', self.spoolFile.name
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1125 self.spoolFile.close()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1126 self.spoolFile = None
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1127
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1128 def do_spool(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1129 """spool [filename] - begins redirecting output to FILENAME."""
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1130 self.spoolstop()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1131 arg = arg.strip()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1132 if not arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1133 arg = 'output.lst'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1134 if arg.lower() != 'off':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1135 if '.' not in arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1136 arg = '%s.lst' % arg
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1137 print 'Sending output to %s (until SPOOL OFF received)' % (arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1138 self.spoolFile = open(arg, 'w')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1139 self.stdout = self.spoolFile
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1140
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1141 def do_write(self, args):
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1142 'Obsolete command. Use (query) > outfilename instead.'
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1143 print self.do_write.__doc__
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1144 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1145
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1146 def do_compare(self, args):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1147 """COMPARE query1 TO query2 - uses external tool to display differences.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1148
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1149 Sorting is recommended to avoid false hits.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1150 Will attempt to use a graphical diff/merge tool like kdiff3, meld, or Araxis Merge,
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1151 if they are installed."""
193
01548a399ccf big switch to ParsedString
catherine@dellzilla
parents: 192
diff changeset
1152 #TODO: Update this to use pyparsing
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1153 fnames = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1154 args2 = args.split(' to ')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1155 if len(args2) < 2:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1156 print self.do_compare.__doc__
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1157 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1158 for n in range(len(args2)):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1159 query = args2[n]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1160 fnames.append('compare%s.txt' % n)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1161 #TODO: update this terminator-stripping
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1162 if query.rstrip()[-1] != self.terminator:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1163 query = '%s%s' % (query, self.terminator)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1164 self.onecmd_plus_hooks('%s > %s' % (query, fnames[n]))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1165 diffMergeSearcher.invoke(fnames[0], fnames[1])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1166
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1167 bufferPosPattern = re.compile('\d+')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1168 rangeIndicators = ('-',':')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1169
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1170 def do_psql(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1171 '''Shortcut commands emulating psql's backslash commands.
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1172
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1173 \c connect
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1174 \d desc
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1175 \e edit
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1176 \g run
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1177 \h help
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1178 \i load
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1179 \o spool
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1180 \p list
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1181 \q quit
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1182 \w save
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1183 \db _dir_tablespaces
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1184 \dd comments
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1185 \dn _dir_schemas
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1186 \dt _dir_tables
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1187 \dv _dir_views
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1188 \di _dir_indexes
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1189 \? help psql'''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1190 commands = {}
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1191 for c in self.do_psql.__doc__.splitlines()[2:]:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1192 (abbrev, command) = c.split(None, 1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1193 commands[abbrev[1:]] = command
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1194 words = arg.split(None,1)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1195 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1196 abbrev = words[0]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1197 except IndexError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1198 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1199 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1200 args = words[1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1201 except IndexError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1202 args = ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1203 try:
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1204 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
1205 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1206 print 'psql command \%s not yet supported.' % abbrev
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1207
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1208 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1209 def do__dir_tables(self, arg, opts):
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1210 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1211 Lists all tables whose names match argument.
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1212 '''
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1213 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
1214 (opts.scope['col'], opts.scope['view'], arg.upper())
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1215 if self.sql_echo:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1216 print sql
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1217 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1218
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1219 @options([all_users_option])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1220 def do__dir_views(self, arg, opts):
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1221 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1222 Lists all views whose names match argument.
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1223 '''
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1224 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
1225 (opts.scope['col'], opts.scope['view'], arg.upper())
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1226 if self.sql_echo:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1227 print sql
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1228 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1229
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1230 def do__dir_indexes(self, arg):
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1231 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1232 Called with an exact table name, lists the indexes of that table.
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1233 Otherwise, acts as shortcut for `ls index/*(arg)*`
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1234 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1235 try:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1236 table_type, table_owner, table_name = self._resolve(arg)
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1237 except TypeError, IndexError:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1238 return self.onecmd('ls Index/*%s*' % arg)
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1239 sql = """SELECT owner, index_name, index_type FROM all_indexes
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1240 WHERE table_owner = :table_owner
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1241 AND table_name = :table_name;
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1242 ORDER BY owner, index_name"""
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1243 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix),
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1244 bindVarsIn = {'table_owner': table_owner, 'table_name': table_name})
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1245
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1246 def do__dir_tablespaces(self, arg):
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1247 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1248 Lists all tablespaces.
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1249 '''
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1250 sql = """SELECT tablespace_name, file_name from dba_data_files;"""
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1251 if self.sql_echo:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1252 print sql
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1253 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1254
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1255 def do__dir_schemas(self, arg):
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1256 '''
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1257 Lists all object owners, together with the number of objects they own.
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1258 '''
194
932893dcf0c9 useTerminatorFrom
catherine@dellzilla
parents: 193
diff changeset
1259 sql = """SELECT owner, count(*) AS objects FROM all_objects GROUP BY owner ORDER BY owner;"""
251
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1260 if self.sql_echo:
aa33f495a289 reworked \di - not truly better?
catherine@Elli.myhome.westell.com
parents: 250
diff changeset
1261 print sql
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1262 self.do_select(self.parsed(sql, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1263
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1264 def do_head(self, arg):
226
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1265 '''Shortcut for SELECT * FROM <arg>;10
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1266 The terminator (\\t, \\g, \\x, etc.) and number of rows can
6701c3f097f9 more comments
catherine@Elli.myhome.westell.com
parents: 224
diff changeset
1267 be changed as for any other SELECT statement.'''
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1268 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
1269 sql.parsed['suffix'] = sql.parsed.suffix or '10'
196
7940955920a8 little fixes
catherine@dellzilla
parents: 195
diff changeset
1270 self.do_select(self.parsed(sql))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1271
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1272 def do_print(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1273 'print VARNAME: Show current value of bind variable VARNAME.'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1274 if arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1275 if arg[0] == ':':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1276 arg = arg[1:]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1277 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1278 self.stdout.write(str(self.binds[arg])+'\n')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1279 except KeyError:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1280 self.stdout.write('No bind variable %s\n' % arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1281 else:
250
aec778ef82b6 print full help on -h
catherine@Elli.myhome.westell.com
parents: 249
diff changeset
1282 for (var, val) in sorted(self.binds.items()):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1283 print ':%s = %s' % (var, val)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1284
285
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1285 def split_on_parser(self, parser, arg):
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1286 try:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1287 assigner, startat, endat = parser.scanner.scanString(arg).next()
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1288 return (arg[:startat].strip(), arg[endat:].strip())
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1289 except StopIteration:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1290 return ''.join(arg.split()[:1]), ''
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1291
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1292 assignmentScanner = Parser(pyparsing.Literal(':=') ^ '=')
285
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1293 def interpret_variable_assignment(self, arg):
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1294 '''
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1295 Accepts strings like `foo = 'bar'` or `baz := 22`, returning Python
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1296 variables as appropriate
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1297 '''
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1298 var, val = self.split_on_parser(self.assignmentScanner, arg)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1299 if not var:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1300 return None, None
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1301 if (len(val) > 1) and ((val[0] == val[-1] == "'") or (val[0] == val[-1] == '"')):
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1302 return var, val[1:-1]
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1303 try:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1304 return var, int(val)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1305 except ValueError:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1306 try:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1307 return var, float(val)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1308 except ValueError:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1309 # use the conversions implicit in cx_Oracle's select to
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1310 # cast the value into an appropriate type (dates, for instance)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1311 try:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1312 self.curs.execute('SELECT %s FROM dual' % val)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1313 return var, self.curs.fetchone()[0]
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1314 except cx_Oracle.DatabaseError:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1315 return var, val # we give up and assume it's a string
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1316
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1317 def do_setbind(self, arg):
285
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1318 '''Sets or shows values of bind (`:`) variables.'''
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1319 if not arg:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1320 return self.do_print(arg)
285
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1321 var, val = self.interpret_variable_assignment(arg)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1322 if val:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1323 self.binds[var] = val
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1324 else:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1325 return self.do_print(var)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1326
285
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1327 def do_define(self, arg):
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1328 '''Sets or shows values of substitution (`&`) variables.'''
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1329 if not arg:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1330 for (substvar, val) in sorted(self.substvars.items()):
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1331 print 'DEFINE %s = "%s" (%s)' % (substvar, val, type(val))
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1332 var, val = self.interpret_variable_assignment(arg)
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1333 if val:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1334 self.substvars[var] = val
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1335 else:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1336 if var in self.substvars:
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1337 print 'DEFINE %s = "%s" (%s)' % (var, self.substvars[var], type(self.substvars[var]))
316abf2191a4 substvar define working now
catherine@dellzilla
parents: 284
diff changeset
1338
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1339 def do_exec(self, arg):
213
a3eeea9ee8cc synched with cmd2 0.4.5
catherine@Elli.myhome.westell.com
parents: 211
diff changeset
1340 if arg.startswith(':'):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1341 self.do_setbind(arg[1:])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1342 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1343 varsUsed = findBinds(arg, self.binds, {})
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1344 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1345 self.curs.execute('begin\n%s;end;' % arg, varsUsed)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1346 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1347 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1348
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1349 '''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1350 Fails:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1351 select n into :n from test;'''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1352
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1353 def anon_plsql(self, line1):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1354 lines = [line1]
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1355 while True:
247
f0f293d83337 begin docs
catherine@dellzilla
parents: 246
diff changeset
1356 line = self.pseudo_raw_input(self.continuation_prompt)
241
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
1357 if line == 'EOF':
d1f1022d2387 trying remark_begin
catherine@Elli.myhome.westell.com
parents: 240
diff changeset
1358 return
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1359 if line.strip() == '/':
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1360 try:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1361 self.curs.execute('\n'.join(lines))
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1362 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1363 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1364 return
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1365 lines.append(line)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1366
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1367 def do_begin(self, arg):
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1368 '''
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1369 PL/SQL blocks can be used normally in sqlpython, though enclosing statements in
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1370 REMARK BEGIN... REMARK END statements can help with parsing speed.'''
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1371 self.anon_plsql('begin ' + arg)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1372
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1373 def do_declare(self, arg):
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1374 self.anon_plsql('declare ' + arg)
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1375
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1376 def _ls_statement(self, arg, opts):
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1377 if arg:
280
8ea39093ddf2 struggling with catching terminator after /*
catherine@dellzilla
parents: 277
diff changeset
1378 target = arg.upper().replace('*','%')
8ea39093ddf2 struggling with catching terminator after /*
catherine@dellzilla
parents: 277
diff changeset
1379 where = """\nWHERE object_type || '/' || object_name LIKE '%s'
8ea39093ddf2 struggling with catching terminator after /*
catherine@dellzilla
parents: 277
diff changeset
1380 OR object_name LIKE '%s'""" % (target, target)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1381 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1382 where = ''
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1383 if opts.all:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1384 whose = 'all'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1385 objname = "owner || '.' || object_name"
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1386 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1387 whose = 'user'
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1388 objname = 'object_name'
232
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1389 if hasattr(opts, 'long') and opts.long:
228
84905120d6c7 last_ddl_time is proper label
catherine@dellzilla
parents: 227
diff changeset
1390 moreColumns = ', status, last_ddl_time'
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1391 else:
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1392 moreColumns = ''
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1393
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1394 # '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
1395 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
1396 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
1397 if hasattr(opts, 'timesort') and opts.timesort:
52adb09094b3 fixed bugs in VC introduced by sort-order options
catherine@dellzilla
parents: 230
diff changeset
1398 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
1399 return {'objname': objname, 'moreColumns': moreColumns,
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1400 'whose': whose, 'where': where, 'orderby': orderby}
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1401
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1402 def resolve_many(self, arg, opts):
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1403 opts.long = False
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1404 clauses = self._ls_statement(arg, opts)
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1405 if opts.all:
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1406 clauses['owner'] = 'owner'
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1407 else:
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1408 clauses['owner'] = 'user'
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1409 statement = '''SELECT %(owner)s, object_type, object_name
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1410 FROM %(whose)s_objects %(where)s
217
a65b98938596 multi-pull working pretty well
catherine@Elli.myhome.westell.com
parents: 216
diff changeset
1411 ORDER BY object_type, object_name''' % clauses
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1412 self._execute(statement)
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1413 return self.curs.fetchall()
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1414
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1415 @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
1416 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
1417 make_option('-t', '--timesort', action='store_true', help="Sort by last_ddl_time"),
280
8ea39093ddf2 struggling with catching terminator after /*
catherine@dellzilla
parents: 277
diff changeset
1418 make_option('-r', '--reverse', action='store_true', help="Reverse order while sorting")])
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1419 def do_ls(self, arg, opts):
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1420 '''
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1421 Lists objects as through they were in an {object_type}/{object_name} UNIX
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1422 directory structure. `*` and `%` may be used as wildcards.
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1423 '''
216
c5a49947eedc going to try multiple pull
catherine@Elli.myhome.westell.com
parents: 213
diff changeset
1424 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
1425 FROM %(whose)s_objects %(where)s
227
5cfa3eff8e4b time and reverse sorting added to ls
catherine@dellzilla
parents: 226
diff changeset
1426 ORDER BY %(orderby)s;''' % self._ls_statement(arg, opts)
200
54cd1e802fa0 terminators + suffixes now preserved
catherine@dellzilla
parents: 199
diff changeset
1427 self.do_select(self.parsed(statement, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1428
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1429 @options([make_option('-i', '--ignore-case', dest='ignorecase', action='store_true', help='Case-insensitive search')])
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1430 def do_grep(self, arg, opts):
281
701f0aae837a got maxtselctrows working again
catherine@dellzilla
parents: 280
diff changeset
1431 """grep {target} {table} [{table2,...}] - search for {target} in any of {table}'s fields"""
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1432
195
4a3af9ac215f wow, parsing is broken
catherine@dellzilla
parents: 194
diff changeset
1433 targetnames = arg.split()
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1434 pattern = targetnames.pop(0)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1435 targets = []
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1436 for target in targetnames:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1437 if '*' in target:
310
c897add05eb1 fixed grep bug
catherine@Elli.myhome.westell.com
parents: 309
diff changeset
1438 self._execute("""SELECT owner, object_name FROM all_objects
c897add05eb1 fixed grep bug
catherine@Elli.myhome.westell.com
parents: 309
diff changeset
1439 WHERE object_type IN ('TABLE','VIEW')
c897add05eb1 fixed grep bug
catherine@Elli.myhome.westell.com
parents: 309
diff changeset
1440 AND object_name LIKE '%s'%s""" %
c897add05eb1 fixed grep bug
catherine@Elli.myhome.westell.com
parents: 309
diff changeset
1441 (target.upper().replace('*','%'), arg.parsed.terminator))
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1442 for row in self.curs:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1443 targets.append('%s.%s' % row)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1444 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1445 targets.append(target)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1446 for target in targets:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1447 print target
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1448 target = target.rstrip(';')
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1449 try:
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1450 self._execute('select * from %s where 1=0' % target) # just to fill description
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1451 if opts.ignorecase:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1452 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
1453 else:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1454 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
1455 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
1456 self.do_select(sql)
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1457 except Exception, e:
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1458 print e
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1459 import traceback
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1460 traceback.print_exc(file=sys.stdout)
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1461
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1462 def _execute(self, sql, bindvars={}):
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1463 if self.sql_echo:
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1464 print sql
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1465 self.curs.execute(sql, bindvars)
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1466
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1467 #@options([make_option('-l', '--long', action='store_true',
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1468 # help='Wordy, easy-to-understand form'),])
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1469 def do_refs(self, arg):
286
abb4c6524113 adding ioug paper
catherine@dellzilla
parents: 285
diff changeset
1470 '''Lists referential integrity (foreign key constraints) on an object or referring to it.'''
211
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1471
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1472 if not arg.strip():
catherine@Elli.myhome.westell.com
parents: 210
diff changeset
1473 print 'Usage: refs (table name)'
190
e9d0492d7358 changing refs
catherine@dellzilla
parents: 189
diff changeset
1474 result = []
205
catherine@dellzilla
parents: 204
diff changeset
1475 (type, owner, table_name) = self.resolve(arg.upper())
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1476 sql = """SELECT constraint_name, r_owner, r_constraint_name
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1477 FROM all_constraints
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1478 WHERE constraint_type = 'R'
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1479 AND owner = :owner
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1480 AND table_name = :table_name"""
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1481 self._execute(sql, {"owner": owner, "table_name": table_name})
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1482 for (constraint_name, remote_owner, remote_constraint_name) in self.curs.fetchall():
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1483 result.append('%s on %s.%s:' % (constraint_name, owner, table_name))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1484
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1485 self._execute("SELECT column_name FROM all_cons_columns WHERE owner = :owner AND constraint_name = :constraint_name ORDER BY position",
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1486 {'constraint_name': constraint_name, 'owner': owner})
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1487 result.append(" (%s)" % (",".join(col[0] for col in self.curs.fetchall())))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1488 self._execute("SELECT table_name FROM all_constraints WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name",
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1489 {'remote_owner': remote_owner, 'remote_constraint_name': remote_constraint_name})
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1490 remote_table_name = self.curs.fetchone()[0]
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1491 result.append("must be in %s:" % (remote_table_name))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1492 self._execute("SELECT column_name FROM all_cons_columns WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name ORDER BY position",
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1493 {'remote_constraint_name': remote_constraint_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1494 result.append(' (%s)\n' % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1495 remote_table_name = table_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1496 remote_owner = owner
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1497 self._execute("""SELECT owner, constraint_name, table_name, r_constraint_name
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1498 FROM all_constraints
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1499 WHERE (r_owner, r_constraint_name) IN
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1500 ( SELECT owner, constraint_name
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1501 FROM all_constraints
192
6bb8a112af6b accept special terminators on most anything
catherine@dellzilla
parents: 191
diff changeset
1502 WHERE table_name = :remote_table_name
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1503 AND owner = :remote_owner )""",
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1504 {'remote_table_name': remote_table_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1505 for (owner, constraint_name, table_name, remote_constraint_name) in self.curs.fetchall():
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1506 result.append('%s on %s.%s:' % (constraint_name, owner, table_name))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1507 self._execute("SELECT column_name FROM all_cons_columns WHERE owner = :owner AND constraint_name = :constraint_name ORDER BY position",
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1508 {'constraint_name': constraint_name, 'owner': owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1509 result.append(" (%s)" % (",".join(col[0] for col in self.curs.fetchall())))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1510 self._execute("SELECT table_name FROM all_constraints WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name",
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1511 {'remote_owner': remote_owner, 'remote_constraint_name': remote_constraint_name})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1512 remote_table_name = self.curs.fetchone()[0]
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1513 result.append("must be in %s:" % (remote_table_name))
249
9e3e49c95abf added sql_echo
catherine@Elli.myhome.westell.com
parents: 248
diff changeset
1514 self._execute("SELECT column_name FROM all_cons_columns WHERE owner = :remote_owner AND constraint_name = :remote_constraint_name ORDER BY position",
191
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1515 {'remote_constraint_name': remote_constraint_name, 'remote_owner': remote_owner})
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1516 result.append(' (%s)\n' % (",".join(col[0] for col in self.curs.fetchall())))
eca4361bfdb6 improved refs
catherine@dellzilla
parents: 190
diff changeset
1517 self.stdout.write('\n'.join(result) + "\n")
190
e9d0492d7358 changing refs
catherine@dellzilla
parents: 189
diff changeset
1518
189
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1519 def _test():
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1520 import doctest
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1521 doctest.testmod()
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1522
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1523 if __name__ == "__main__":
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1524 "Silent return implies that all unit tests succeeded. Use -v to see details."
c5398d87498e cat bug
catherine@dellzilla
parents:
diff changeset
1525 _test()
198
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
1526 if __name__ == "__main__":
b2d8bf5f89db merged with changes from work
catherine@Elli.myhome.westell.com
parents: 196
diff changeset
1527 "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
1528 _test()