del net-oscar
[learning-git.git] / pgworksheet_yvesf / pgw / Execute.py
blobc1315622e2ebb599bc5c41744899c407a69668e3
1 # -*- coding: latin-1; -*-
3 # PgWorksheet - PostgreSQL Front End
4 # http://pgworksheet.projects.postgresql.org/
6 # Copyright © 2004-2005 Henri Michelon & CML http://www.e-cml.org/
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details (read LICENSE.txt).
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 # $Id: Execute.py,v 1.26 2005/06/10 12:54:30 hmichelon Exp $
24 import os
25 import sys
26 import popen2
27 import string
28 import gtk
30 import pgw
31 import pgw.Lexical
34 class Execute:
35 """SQL query and psql commands handling"""
38 def __init__(self, db):
39 self.db = db
40 self.lexical = pgw.Lexical.Lexical()
43 def execute_one(self, sql):
44 """Execute one query"""
45 if (len(sql) > 0) :
46 # psql commands
47 if (sql[0] == '\\'):
48 sql = string.replace(sql, '\\\\', '\\')
49 if (pgw.mswindows()):
50 cmd = "psql.exe"
51 sql = string.strip(sql)
52 else:
53 cmd = "psql"
54 if (self.db.user is not None):
55 cmd += ' -U "' + self.db.user + '"'
56 if (self.db.host is not None):
57 cmd += ' -h "' + self.db.host + '"'
58 if (self.db.port is not None):
59 cmd += ' -p ' + self.db.port
60 if (self.db.database is not None):
61 cmd += ' -d "' + self.db.database + '"'
62 cmd += ' -c "' + sql + '"'
63 if (self.db.password is not None):
64 os.putenv("PGPASSWORD", self.db.password)
65 #os.putenv("PGCLIENTENCODING", pgw.get_user_encoding())
66 output, input = popen2.popen4(cmd)
67 result = output.read()
68 output.close()
69 input.close()
70 #os.putenv("PGCLIENTENCODING", "")
71 os.putenv("PGPASSWORD", "")
72 return { 'text' : result }
73 else:
74 # SQL query
75 return self.db.query(sql)
78 def execute(self, sql):
79 """Execute SQL queries or psql commands"""
80 if not self.db.is_connected() : return
81 # SQL query
82 sqls = self.split(sql)
83 if (len(sqls) > 1):
84 # multiple queries
85 results = []
86 for sql in sqls:
87 sql = string.strip(sql)
88 if (len(sql) > 0):
89 results.append(self.execute_one(sql))
90 if (len(results) == 1):
91 return results[0]
92 return results
93 else:
94 # unique query
95 return self.execute_one(sqls[0])
98 def split(self, oldsql):
99 """Split multiple queries"""
100 # a new textbuffer, because we don't want to modify the original
101 buffer = gtk.TextBuffer()
102 buffer.set_text(oldsql)
104 # filter comments
105 tokens = self.lexical.analyse(buffer, buffer.get_start_iter(),
106 buffer.get_end_iter())
107 for token in tokens:
108 if (token.token == 'comment'):
109 buffer.delete(token.start_iter, token.end_iter)
111 # restart without the comments
112 buffer.set_text(buffer.get_text(buffer.get_start_iter(),
113 buffer.get_end_iter()))
114 start = buffer.get_start_iter()
115 end = buffer.get_end_iter()
116 tokens = self.lexical.analyse(buffer, start, end)
118 # create a list of queries
119 sql = buffer.get_text(start, end)
120 parts = []
121 stop = start
122 while (len(tokens) > 0):
123 token = tokens.pop(0)
124 if (token.token == 'psql'):
125 i = token.start_iter
126 i.backward_char()
127 parts.append(buffer.get_text(stop, i))
128 parts.append(token.value)
129 stop = token.end_iter
130 elif (token.value == ';'):
131 i = token.start_iter
132 parts.append(buffer.get_text(stop, i))
133 stop = token.end_iter
134 if (stop != end):
135 parts.append(buffer.get_text(stop, end))
136 return parts