1212import io
1313import codecs
1414import shlex # Simple lexical analysis
15+ from os .path import expanduser
1516
1617try : # We are Python 3.3+
1718 from tkinter import *
@@ -31,12 +32,13 @@ class App:
3132 """the GUI graphic application"""
3233 def __init__ (self ):
3334 """create a tkk graphic interface with a main window tk_win"""
34- self .__version__ = '0.9.1 '
35- self ._title = "2019-06-16a : 'Support un-named Tabs !'"
35+ self .__version__ = '0.9.2 '
36+ self ._title = "of 2021-04-20a : 'Give PyPy a chance !'"
3637 self .conn = None # Baresql database object
3738 self .database_file = ""
3839 self .tk_win = Tk ()
39- self .tk_win .title ('A graphic SQLite Client in 1 Python file' )
40+ self .tk_win .title ('A graphic SQLite Client in 1 Python file (' +
41+ self .__version__ + ')' )
4042 self .tk_win .option_add ('*tearOff' , FALSE ) # hint of tk documentation
4143 self .tk_win .minsize (600 , 200 ) # minimal size
4244
@@ -74,6 +76,9 @@ def __init__(self):
7476 # Bind keyboard shortcuts
7577 self .tk_win .bind ('<F9>' , self .run_tab )
7678
79+ # define default home directory
80+ self .home = expanduser ("~" )
81+
7782 def create_menu (self ):
7883 """create the menu of the application"""
7984 menubar = Menu (self .tk_win )
@@ -102,8 +107,13 @@ def create_menu(self):
102107 self .menu_help .add_command (label = 'about' ,
103108 command = lambda : messagebox .showinfo (message = """
104109 \n SQLite_bro : a graphic SQLite Client in 1 Python file
105- \n (""" + self .__version__ + ") " + self ._title + """
106- \n (https://github.com/stonebig/sqlite_bro)""" ))
110+ \n Version """ + self .__version__ + " " + self ._title +
111+ "\n (https://github.com/stonebig/sqlite_bro)" +
112+ "\n \n run by: " + sys .executable +
113+ "\n \n home: " + self .home +
114+ "\n \n current directory: " + os .getcwd ()
115+
116+ ))
107117
108118 def create_toolbar (self ):
109119 """create the toolbar of the application"""
@@ -690,6 +700,8 @@ def bip(c):
690700 try :
691701 if shell_list [0 ] == '.import' and len (shell_list ) >= 2 :
692702 csv_file = shell_list [1 ]
703+ if (csv_file + "z" )[0 ] == "~" :
704+ csv_file = os .path .join (self .home , csv_file [1 :])
693705 guess = guess_csv (csv_file )
694706 if len (shell_list ) >= 3 :
695707 guess .table_name = shell_list [2 ]
@@ -722,21 +734,25 @@ def bip(c):
722734 log .write ("Error ! %s : %s" % (msg , instru ))
723735 sql_error = True
724736 break
725- elif instruction != "" :
737+ elif len ( "" . join ( instruction . split ())) > 1 : # PyPy answer 42 to blanks sql
726738 try :
727739 if shell_list [0 ] == '.once' :
728740 shell_list [0 ] = ' '
729741 encode_in = 'utf-8-sig' if os .name == 'nt' else 'utf-8'
730- self .conn .export_writer (instruction , shell_list [1 ],
742+ csv_file = shell_list [1 ]
743+ if (csv_file + "z" )[0 ] == "~" :
744+ csv_file = os .path .join (self .home , csv_file [1 :])
745+ self .conn .export_writer (instruction , csv_file ,
731746 encoding = encode_in )
732747 self .n .add_treeview (tab_tk_id , ('qry' , 'file' ),
733- ((instruction , shell_list [ 1 ] ),),
734- "Info" , ".once %s" % shell_list [ 1 ] )
748+ ((instruction , csv_file ),),
749+ "Info" , ".once %s" % csv_file )
735750 else :
736751 cur = cu .execute (instruction )
737752 rows = cur .fetchall ()
738753 # a query may have no result( like for an "update")
739- if cur .description is not None :
754+ if cur .description is not None and \
755+ len (cur .description )> 0 : #pypy needs the second test
740756 titles = [row_info [0 ] for
741757 row_info in cur .description ]
742758 self .n .add_treeview (
@@ -1526,19 +1542,23 @@ def export_writer(self, sql, csv_file, header=True,
15261542 """export a csv table (action)"""
15271543 cursor = self .conn .cursor ()
15281544 cursor .execute (sql )
1545+ # with PyPy, the "with io.open" for is more than necessary
15291546 if sys .version_info [0 ] != 2 : # python3
1530- fout = io .open (csv_file , 'w' , newline = '' , encoding = encoding )
1531- writer = csv .writer (fout , delimiter = delimiter ,
1547+ with io .open (csv_file , 'w' , newline = '' , encoding = encoding ) as fout :
1548+ writer = csv .writer (fout , delimiter = delimiter ,
15321549 quotechar = '"' , quoting = csv .QUOTE_MINIMAL )
1550+ if header :
1551+ writer .writerow ([i if isinstance (i , str ) else i [0 ]
1552+ for i in cursor .description ]) # PyPy as a strange list of list
1553+ writer .writerows (cursor .fetchall ())
15331554 else : # python2.7 (minimal)
1534- fout = io .open (csv_file , 'wb' )
1535- writer = csv .writer (fout , delimiter = str (delimiter ),
1555+ with io .open (csv_file , 'wb' ) as fout :
1556+ writer = csv .writer (fout , delimiter = str (delimiter ),
15361557 quotechar = str ('"' ), quoting = csv .QUOTE_MINIMAL )
1537- if header :
1538- writer .writerow ([i [0 ] for i in cursor .description ]) # heading row
1539- writer .writerows (cursor .fetchall ())
1540- fout .close
1541-
1558+ if header :
1559+ writer .writerow ([i if isinstance (i , str ) else i [0 ]
1560+ for i in cursor .description ]) # heading row with anti-PyPy bug
1561+ writer .writerows (cursor .fetchall ())
15421562
15431563def _main ():
15441564 app = App ()
@@ -1598,9 +1618,9 @@ def _main():
15981618-- .once FILENAME Output for the next SQL command only to FILENAME
15991619-- .import FILE TABLE Import data from FILE into TABLE
16001620-- (create table only if it doesn't exist, keep existing records)
1601- .once 'this_file_of_result.txt'
1621+ .once '~ this_file_of_result.txt'
16021622select ItemNo, Description from item order by ItemNo desc;
1603- .import 'this_file_of_result.txt' in_this_table
1623+ .import '~ this_file_of_result.txt' in_this_table
16041624
16051625"""
16061626 app .n .new_query_tab ("Welcome" , welcome_text )
0 commit comments