annotate sqlpython/sqlpyPlus.py @ 326:82937b8dcbfe

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