Skip to content

Commit

Permalink
Merge pull request #43 from kadrlica/1.2.0br2
Browse files Browse the repository at this point in the history
Dereferencing tablenames (1.2.0br2)
  • Loading branch information
mgckind committed Dec 9, 2015
2 parents 601c699 + 7c3474b commit 560c7f1
Showing 1 changed file with 138 additions and 105 deletions.
243 changes: 138 additions & 105 deletions easyaccess.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ def write_to_fits(df, fitsfile, fileindex, mode='w', listN=[], listT=[], fits_ma
return fileindex

else:
raise Exception("Illegal write mode!")
msg = "Illegal write mode!"
raise Exception(msg)


class easy_or(cmd.Cmd, object):
Expand Down Expand Up @@ -1443,7 +1444,10 @@ def do_set_password(self, arg):


def do_refresh_metadata_cache(self, arg):
"""DB:Refreshes meta data cache for auto-completion of table names and column names """
"""
DB:Refreshes meta data cache for auto-completion of table
names and column names .
"""

# Meta data access: With the two linked databases, accessing the
# "truth" via fgetmetadata has become very slow.
Expand Down Expand Up @@ -1491,7 +1495,8 @@ def do_show_db(self, arg):
lines = "user: %s\ndb : %s\nhost: %s\n" % (self.user.upper(), self.dbname.upper(), self.dbhost.upper())
lines = lines + "\nPersonal links:"
query = """
select owner, db_link, username, host, created from all_db_links where OWNER = '%s'
SELECT owner, db_link, username, host, created
FROM all_db_links where OWNER = '%s'
""" % (self.user.upper())
self.query_and_print(query, print_time=False, extra=lines, clear=True)

Expand All @@ -1517,19 +1522,24 @@ def do_myquota(self, arg):
Usage: myquota
"""
sql_getquota = "select TABLESPACE_NAME, \
MBYTES_USED/1024 as GBYTES_USED, MBYTES_LEFT/1024 as GBYTES_LEFT from myquota"
self.query_and_print(sql_getquota, print_time=False, clear=True)
query = """
SELECT tablespace_name, mbytes_used/1024 as GBYTES_USED,
mbytes_left/1024 as GBYTES_LEFT from myquota
"""
self.query_and_print(query, print_time=False, clear=True)

def do_mytables(self, arg):
"""
DB:Lists table you have made in your 'mydb'
DB:Lists tables you have made in your user schema.
Usage: mytables
"""
# query = "SELECT table_name FROM user_tables"
query = "SELECT t.table_name, s.bytes/1024/1024/1024 SIZE_GBYTES \
FROM user_segments s, user_tables t WHERE s.segment_name = t.table_name"
query = """
SELECT t.table_name, s.bytes/1024/1024/1024 SIZE_GBYTES
FROM user_segments s, user_tables t
WHERE s.segment_name = t.table_name
"""

self.query_and_print(query, print_time=False, extra="List of my tables", clear=True)

Expand Down Expand Up @@ -1579,64 +1589,40 @@ def complete_user_tables(self, text, line, start_index, end_index):
else:
return options_users

def do_describe_table(self, arg, clear=True):
def get_tablename_tuple(self, tablename):
"""
DB:This tool is useful in noting the lack of documentation for the
columns. If you don't know the full table name you can use tab
completion on the table name. Tables of usual interest are described
Usage: describe_table <table_name>
Describes the columns in <table-name> as
column_name, oracle_Type, date_length, comments
Optional: describe_table <table_name> with <pattern>
Describes only the columns with certain pattern, example:
describe_table Y1A1_COADD_OBJECTS with MAG%
will describe only columns starting with MAG in that table
Return the tuple (schema,table,link) that can be used to
locate the `real` table requested.
"""
if arg == '':
return self.do_help('describe_table')
arg = arg.replace(';', '')
arg = " ".join(arg.split())
tablename = arg.split()[0]
tablename = tablename.upper()
pattern = None
try:
extra = arg.split()[1]
if extra.upper() == 'WITH':
pattern = arg.split()[2]
except:
pass

table = tablename
schema = self.user.upper() # default --- Mine
link = "" # default no link
if "." in tablename: (schema, tablename) = tablename.split(".")
if "@" in tablename: (tablename, link) = tablename.split("@")
table = tablename

if "." in table: (schema, table) = table.split(".")
if "@" in table: (table, link) = table.split("@")

#
# loop until we find a fundamental definition OR determine there is
# no reachable fundamental definition, floow links and resolving
# Loop until we find a fundamental definition OR determine there is
# no reachable fundamental definition, follow links and resolve
# schema names. Rely on how the DES database is constructed we log
# into our own schema, and rely on synonyms for a "simple" view of
# common schema.
#

while (1):
# check for fundamental definition e.g. schema.table@link
q = """
select count(*) from all_tab_columns%s
where OWNER = '%s' and
TABLE_NAME = '%s'
""" % ("@" + link if link else "", schema, table)
select count(*) from ALL_TAB_COLUMNS%s
where OWNER = '%s'
and TABLE_NAME = '%s'
""" % ("@" + link if link else "", schema, table)
ans = self.query_results(q)
if ans[0][0] > 0:
# found real definition go get meta-data
break
# found real definition return the tuple
return (schema,table,link)

# check if we are indirect by synonym of mine
q = """select TABLE_OWNER, TABLE_NAME, DB_LINK from USER_SYNONYMS%s
where SYNONYM_NAME= '%s'
q = """
select TABLE_OWNER, TABLE_NAME, DB_LINK from USER_SYNONYMS%s
where SYNONYM_NAME = '%s'
""" % ("@" + link if link else "", table)
ans = self.query_results(q)
if len(ans) == 1:
Expand All @@ -1645,49 +1631,94 @@ def do_describe_table(self, arg, clear=True):
continue

# check if we are indirect by a public synonym
q = """select TABLE_OWNER, TABLE_NAME, DB_LINK from ALL_SYNONYMS%s
where SYNONYM_NAME = '%s' AND OWNER = 'PUBLIC'
q = """
select TABLE_OWNER, TABLE_NAME, DB_LINK from ALL_SYNONYMS%s
where SYNONYM_NAME = '%s' AND OWNER = 'PUBLIC'
""" % ("@" + link if link else "", table)
ans = self.query_results(q)
if len(ans) == 1:
# resolved one step closer to fundamental definition
(schema, table, link) = ans[0]
continue

# failed to find the reference count on the query below to give a null result
break # no such table accessible by user
# failed to find the reference to the table
# no such table accessible by user
break

msg = "No table found for: %s"%tablename
raise Exception(msg)

# schema, table and link are now valid.
link = "@" + link if link else ""
qcom = """ select comments from all_tab_comments%s atc where atc.table_name = '%s'""" % (link, table)
comment_table = self.query_results(qcom)
if len(comment_table) == 0:
comment_table = "Table does not exist"
else:
comment_table = comment_table[0][0]

def do_describe_table(self, arg, clear=True):
"""
DB:This tool is useful for noting the lack of documentation
for columns. If you don't know the full table name you can
use tab completion on the table name. Tables of usual interest
are described.
Usage: describe_table <table_name>
Describes the columns in <table-name> as
column_name, oracle_Type, date_length, comments
Optional: describe_table <table_name> with <pattern>
Describes only the columns with certain pattern, example:
describe_table Y1A1_COADD_OBJECTS with MAG%
will describe only columns starting with MAG in that table
"""
if arg == '':
return self.do_help('describe_table')
arg = arg.replace(';', '')
arg = " ".join(arg.split())
tablename = arg.split()[0]
tablename = tablename.upper()
pattern = None
try:
extra = arg.split()[1]
if extra.upper() == 'WITH':
pattern = arg.split()[2].upper()
except:
pass

try:
schema,table,link = self.get_tablename_tuple(tablename)
# schema, table and link are now valid.
link = "@" + link if link else ""
qcom = """
select comments from all_tab_comments%s atc
where atc.table_name = '%s'""" % (link, table)
comment_table = self.query_results(qcom)[0][0]
except:
print(colored("Table not found.", "red"))
return

# String formatting parameters
params = dict(schema=schema, table=table, link=link,
pattern=pattern, comment=comment_table)

if pattern:
comm = """Description of %s with pattern %s commented as: '%s'""" % (table, pattern.upper(), comment_table)
comm = """Description of %(table)s with pattern %(pattern)s commented as: '%(comment)s'""" % params
q = """
select
atc.column_name, atc.data_type,
select atc.column_name, atc.data_type,
atc.data_length || ',' || atc.data_precision || ',' || atc.data_scale DATA_FORMAT, acc.comments
From all_tab_cols%s atc , all_col_comments%s acc
where atc.owner = '%s' and atc.table_name = '%s' and
acc.owner = '%s' and acc.table_name='%s' and acc.column_name = atc.column_name and atc.column_name like '%s'
from all_tab_cols%(link)s atc , all_col_comments%(link)s acc
where atc.owner = '%(schema)s' and atc.table_name = '%(table)s'
and acc.owner = '%(schema)s' and acc.table_name = '%(table)s'
and acc.column_name = atc.column_name
and atc.column_name like '%(pattern)s'
order by atc.column_id
""" % (link, link, schema, table, schema, table, pattern.upper())
""" % params
else:
comm = """Description of %s commented as: '%s'""" % (table, comment_table)
comm = """Description of %(table)s commented as: '%(comment)s'""" % params
q = """
select
atc.column_name, atc.data_type,
select atc.column_name, atc.data_type,
atc.data_length || ',' || atc.data_precision || ',' || atc.data_scale DATA_FORMAT, acc.comments
From all_tab_cols%s atc , all_col_comments%s acc
where atc.owner = '%s' and atc.table_name = '%s' and
acc.owner = '%s' and acc.table_name='%s' and acc.column_name = atc.column_name
from all_tab_cols%(link)s atc , all_col_comments%(link)s acc
where atc.owner = '%(schema)s' and atc.table_name = '%(table)s'
and acc.owner = '%(schema)s' and acc.table_name = '%(table)s'
and acc.column_name = atc.column_name
order by atc.column_id
""" % (link, link, schema, table, schema, table)
""" % params

self.query_and_print(q, print_time=False,
err_arg='Table does not exist or it is not accessible by user or pattern do not match',
Expand Down Expand Up @@ -1722,22 +1753,15 @@ def do_find_tables_with_column(self, arg):
# query = "SELECT TABLE_NAME, COLUMN_NAME FROM fgottenmetadata WHERE COLUMN_NAME LIKE '%%%s%%' " % (arg.upper())
if arg == '': return self.do_help('find_tables_with_column')
query = """
SELECT
table_name, column_name
FROM
fgottenmetadata
WHERE
column_name LIKE '%s'
SELECT table_name, column_name
FROM fgottenmetadata
WHERE column_name LIKE '%s'
UNION
SELECT LOWER(owner) || '.' || table_name, column_name
FROM
all_tab_cols
WHERE
column_name LIKE '%s'
AND
owner NOT LIKE '%%SYS'
AND
owner not in ('XDB','SYSTEM')
FROM all_tab_cols
WHERE column_name LIKE '%s'
AND owner NOT LIKE '%%SYS'
AND owner not in ('XDB','SYSTEM')
""" % (arg.upper(), arg.upper())

self.query_and_print(query)
Expand All @@ -1754,24 +1778,33 @@ def do_show_index(self, arg):
Usage: describe_index <table_name>
"""

if arg == '':
return self.do_help('show_index')
arg = arg.replace(';', '')
arg = " ".join(arg.split())
tablename = arg.split()[0]
tablename = tablename.upper()

try:
schema,table,link = self.get_tablename_tuple(tablename)
link = "@" + link if link else ""
except:
print(colored("Table not found.", "red"))
return

# Parse tablename for simple name or owner.tablename.
# If owner present, then add owner where clause.
arg = arg.upper().strip()
if not arg:
print("table name required")
return
tablename = arg
tablename = tablename.replace(';', '')
query_template = """

params = dict(schema=schema,table=table,link=link)
query = """
SELECT UNIQUE tab.table_name,icol.column_name,
idx.index_type,idx.index_name
FROM dba_tables tab
JOIN dba_indexes idx on idx.table_name = tab.table_name
JOIN dba_ind_columns icol ON idx.index_name = icol.index_name
WHERE tab.table_name='%s'
FROM all_tables%(link)s tab
JOIN all_indexes%(link)s idx on idx.table_name = tab.table_name
JOIN all_ind_columns%(link)s icol on idx.index_name = icol.index_name
WHERE tab.table_name='%(table)s' and tab.owner = '%(schema)s'
ORDER BY icol.column_name,idx.index_name
"""
query = query_template % (tablename)
""" % params
nresults = self.query_and_print(query)
return

Expand Down

0 comments on commit 560c7f1

Please sign in to comment.