Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1ZqdUr-0007iR-F4 for pgadmin-hackers@arkaria.postgresql.org; Mon, 26 Oct 2015 08:51:18 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1ZqdUr-00028X-19 for pgadmin-hackers@arkaria.postgresql.org; Mon, 26 Oct 2015 08:51:17 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1ZqdUq-00028M-CC for pgadmin-hackers@postgresql.org; Mon, 26 Oct 2015 08:51:16 +0000 Received: from mail.srv.pl ([2001:1a68:0:c::4a]) by magus.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1ZqdUh-0007KV-7q for pgadmin-hackers@postgresql.org; Mon, 26 Oct 2015 08:51:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=srv.pl; s=dkim; h=Mime-Version:Content-Type:Date:To:From:Subject:Message-ID; bh=EDevkV1fotE5QigQWkfGcF61D5hxmlceY4xxC80R3Ww=; b=bApTydn7DjeUtPlTeJ/2tL0/F2Sx6P3f3zLR2gFhBiiu8pPUgY8CNG7p+YL0IADgEFr5xCKlE1SkLjmtYaRNSY1cBmhcKtyR9jbHdqBeq21lkfhHwfcx60v3vBaAgkEb7OOyMIAGwn8yo9zS0lCfDFUygklrsIje7+H0ElRnXik=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=bodygloveoptrix.pl; s=dkim; h=Mime-Version:Content-Type:Date:To:From:Subject:Message-ID; bh=EDevkV1fotE5QigQWkfGcF61D5hxmlceY4xxC80R3Ww=; b=Ptl2H4loZT//vnLApfmRY6pDjwhklCT0QdEXrQl9aDhXJhT+U1jWaHiQyl4ADcpUsHhKIyLUqD+4J1RczdcKiiuupelfa3hsIutXPQs+kShn2HuwLHUIRzasu4/k4Cz50dj8Mw333YcZULeAEAOEfYF8AE67afwTqjyAC+O1jFE=; Message-ID: <1445849459.17392.68.camel@jlap3.macro.local> Subject: SQL formatting From: jarek To: pgadmin-hackers@postgresql.org Date: Mon, 26 Oct 2015 09:50:59 +0100 Content-Type: multipart/mixed; boundary="=-WkrbRCGOrI/2MbeL/KjY" X-Mailer: Evolution 3.4.4-3 Mime-Version: 1.0 X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgadmin-hackers Precedence: bulk Sender: pgadmin-hackers-owner@postgresql.org --=-WkrbRCGOrI/2MbeL/KjY Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Hello! First of all I'd like to thank all the pgAdmin developers for a great job! As I like to have nice formatted SQL, I've written simple script in python to format SQL procedures. It would be nice, to integrate it with pgAdmin. This script doesn't cover all PostgreSQL structures, but is enough for me. If there will be some interest, I can improve it. I think that it should be enough to add call to this script from SQL query dialog menu. I've no experience with wxWidgets, so it may be better if someone more skilled will integrate it. best regards Jarek Tabor --=-WkrbRCGOrI/2MbeL/KjY Content-Disposition: attachment; filename="sqlf.py" Content-Type: text/x-python; name="sqlf.py"; charset="UTF-8" Content-Transfer-Encoding: 8bit #!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (c) 2014-2015 Jarosław Tabor # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import sys import re indent_keywords = ['BEGIN', 'IF', 'FOR'] unindent_keywords = ['END'] uindent_once_keywords = ['ELSE'] indent_once = ['DECLARE'] indentsize = 4 function_re = re.compile('^CREATE[\ ]*(OR[\ ]*REPLACE[\ ]*)*FUNCTION') function_body_re = re.compile('\$.*\$') function_declare_re = re.compile('DECLARE') function_begin_re = re.compile('BEGIN') function_end_re = re.compile('END;') function_endsc_re = re.compile(';') if_re = re.compile('^IF') endif_re = re.compile('^END IF') else_re = re.compile('^(ELSE|ELSIF)') for_re = re.compile('^(FOR.*LOOP|LOOP)') endfor_re = re.compile('^END[\ ]*LOOP') exception_re = re.compile('^EXCEPTION') query_re = re.compile('^(SELECT|PERFORM|UPDATE|DELETE)') def indent_print( _indent, _line ): out = '' if _line != '': if( _indent > 0 ): for i in range(_indent * indentsize): out = out + ' ' print out + _line else: print def main(_file): indent_level = 0 function_body = 0 query = 0 with open(_file) as f: n = 0 for line in f: n = n + 1 out = '' line=line.strip() if function_re.match( line ): # function start function_body = 1 indent_level = 1 print line continue if function_body_re.match( line ): #function body if function_body==1: function_body = 2 elif function_body==5: function_body = 6 else: sys.stderr.write('Unexpected $$ keyword in %d\n' % n ) print line continue if function_declare_re.match( line ): if function_body == 2: function_body = 3 else: sys.stderr.write('Unexpected DECLARE keyword in %d\n' % n ) print line continue if function_begin_re.match( line ): if function_body == 2 or function_body == 3: function_body = 4 print line else: indent_print(indent_level,line) indent_level = indent_level + 1 continue if function_end_re.match( line ): if function_body == 4: if indent_level > 1: indent_level = indent_level -1 indent_print(indent_level,line) continue else: function_body = 5 else: sys.stderr.write('Unexpected END; keyword in %d\n' % n ) print line continue if function_body == 6 and (';' in line): function_body = 0 indent_print(indent_level,line) indent_level = 0 continue if if_re.match( line ): indent_print(indent_level,line) indent_level = indent_level + 1 continue if else_re.match( line ): indent_print(indent_level-1,line) continue if exception_re.match( line ): indent_print(indent_level-1,line) continue if endif_re.match(line): if indent_level > 0: indent_level = indent_level-1 if for_re.match(line): indent_print(indent_level,line) indent_level = indent_level + 1 continue if endfor_re.match(line): if indent_level > 0: indent_level = indent_level-1 if query_re.match(line): #print '*********query 1' if not ';' in line: query = 1 indent_print(indent_level,line) indent_level = indent_level + 1 continue if (';' in line) and (query>0): #print '*********query 0' if indent_level > 0: query = query -1 indent_print(indent_level,line) indent_level = indent_level-1 continue indent_print(indent_level,line) if __name__ == "__main__": if len(sys.argv) > 1: main(sys.argv[1]) else: sys.stderr.write('No input file provided.\n' ) --=-WkrbRCGOrI/2MbeL/KjY Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers --=-WkrbRCGOrI/2MbeL/KjY--