# # Simple SQL Console for Hibernate # J R Briggs # import sys import types from org.python.core import PyArray from java.lang.reflect import * from org.hibernate import * from org.hibernate.cfg import * sessionFactory = Configuration().configure().buildSessionFactory() session = sessionFactory.openSession() print 'Ready...' fieldsize = 10 def process_class(cl, meta, obj): ''' find all the get methods in a class (and superclasses) ''' scl = cl.getSuperclass() if scl.getName() != 'java.lang.Object': process_class(scl, meta, obj) for method in cl.getMethods(): methodname = method.getName() if methodname == 'getClass': continue if methodname.startswith('get') and len(method.getParameterTypes()) == 0: name = method.getName()[3:] size = max(len(name)+2, fieldsize) val = get_data(method.invoke(obj, None), size) size = max(size, len(val)) meta.append( (name, method, size ) ) def process_meta(obj): ''' produce metadata (a tuple containing name, method object and column size) for an object ''' meta = [ ] try: process_class(obj.getClass(), meta, obj) except: # if obj is an array, then create default meta if isinstance(obj, PyArray): for x in obj: meta.append(('Unknown', None, fieldsize)) # otherwise we don't know what to do with it # so just create a single tuple else: meta.append(('Unknown', None, fieldsize)) # loop through the tuple and print the names as headings for (name, method, size) in meta: print name.center(size), print '' # print an underline beneath the headings for (name, method, size) in meta: print '=' * size, print '' return meta def print_fields(meta, obj): ''' print fields (actually call the get methods) in an object ''' # if an array, print out the array elements if isinstance(obj, PyArray): for x in obj: print get_data(x, fieldsize), else: # otherwise loop through the meta to invoke each method in turn for idx in xrange(0, len(meta)): (name, method, size) = meta[idx] # if no method, just print the object if not method: print str(obj).ljust(size), else: # invoke the method against the object try: val = method.invoke(obj, None) print get_data(val, size), except: print '[ERR]'.ljust(size), print '' def get_method(cl, name): ''' get a method, return None if an error occurs ''' try: return cl.getMethod(name, None) except: return None def find_id(cl): ''' find a getId method ''' m = get_method(cl, 'getId') if m: return m m = get_method(cl, 'getID') if m: return m if cl.getSuperclass().getName() != 'java.lang.Object': return find_id(cl.getSuperclass()) else: return None def get_data(val, size): ''' print a data value ''' cl = None try: cl = val.getClass() except: pass if cl: idmethod = find_id(cl) if idmethod: val = idmethod.invoke(val, None) elif cl.getName().find('Date') < 0: val = '[Object]' return str(val).ljust(size) try: input = [] # loop, reading input and running queries while 1: input.append(sys.stdin.readline().rstrip()) # read until we hit a ';' if not input[len(input)-1].endswith(';'): continue line = ' '.join(input) line = line[0:len(line)-1].lstrip().rstrip() input = [] if line == 'quit' or line == 'exit': break elif line == '': print '' continue try: print 'Processing query...' rs = session.find(line) count = 0 meta = None for r in rs: count = count+1 if not meta: meta = process_meta(r) print_fields(meta, r) if count == 0: print 'No data' except Exception, e: print e finally: print 'closing session factory' sessionFactory.close()